Newer
Older
smart-home-server / webclient-vue / src / components / area / AreaAssignSection.vue
<template>
  <div class="devices-panel">
    <div class="block-title">{{ title }}</div>
    <div v-if="area" class="area-assigned">
      <router-link
        :to="{ name: 'area-detail', params: { id: area.id } }"
        class="area-card"
      >
        <div class="area-card-icon text-primary"><i class="ph ph-map-trifold"></i></div>
        <div class="area-card-info">
          <strong>{{ area.display_name }}</strong>
          <small class="text-muted">{{ area.type }} — {{ area.alias }}</small>
        </div>
      </router-link>
    </div>
    <AppEmptyState
      v-else
      title="Not assigned"
      :message="emptyMessage"
    >
      <template #action>
        <slot name="action">
          <GnButton variant="primary" icon="ph-map-pin" @click="emit('assign')"
          >Assign to area</GnButton>
        </slot>
      </template>
    </AppEmptyState>
  </div>
</template>

<script setup>
import { computed } from "vue";
import { useAreasStore } from "../../stores/areas";
import { GnButton } from "gnexus-ui-kit/vue";
import AppEmptyState from "../feedback/AppEmptyState.vue";

const props = defineProps({
  item: { type: Object, default: null },
  areaId: { type: [Number, String], default: null },
  title: { type: String, default: "Area" },
  emptyMessage: {
    type: String,
    default: "This item is not assigned to any area.",
  },
});

const emit = defineEmits(["assign"]);

const areasStore = useAreasStore();

const area = computed(() => {
  const id = props.areaId != null ? props.areaId : props.item?.area_id;
  if (!id) return null;
  return areasStore.areasById[String(id)] || null;
});
</script>

<style scoped>
.devices-panel {
  margin-bottom: 24px;
}

.block-title {
  font-weight: 700;
  text-transform: uppercase;
  margin-bottom: 12px;
  color: var(--color-primary);
}

.area-assigned {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.area-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: var(--color-panel);
  border: 1px solid rgba(192, 202, 245, 0.12);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.15s;
}

.area-card:hover {
  border-color: var(--color-primary);
}

.area-card-icon {
  font-size: 20px;
}

.area-card-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.area-card-info small {
  font-size: 12px;
}

.form-group {
  margin-bottom: 16px;
}
</style>