format
This commit is contained in:
@@ -5,12 +5,17 @@
|
||||
<div class="p-6 border-b border-gray-200">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-xl font-semibold text-gray-900">Room Management</h2>
|
||||
<button
|
||||
<button
|
||||
@click="$emit('close')"
|
||||
class="text-gray-400 hover:text-gray-600 transition-colors"
|
||||
>
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M6 18L18 6M6 6l12 12"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -53,49 +58,54 @@
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-3">
|
||||
<div
|
||||
v-for="room in roomsWithStats"
|
||||
:key="room.name"
|
||||
class="bg-gray-50 rounded-lg p-4"
|
||||
>
|
||||
<div v-for="room in roomsWithStats" :key="room.name" class="bg-gray-50 rounded-lg p-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex-1">
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<h4 class="font-medium text-gray-900">{{ room.name }}</h4>
|
||||
<span class="text-xs px-2 py-1 bg-blue-100 text-blue-700 rounded-full font-medium">
|
||||
<span
|
||||
class="text-xs px-2 py-1 bg-blue-100 text-blue-700 rounded-full font-medium"
|
||||
>
|
||||
{{ room.sensorCount }} sensors
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid grid-cols-2 lg:grid-cols-4 gap-4 text-sm">
|
||||
<div>
|
||||
<span class="text-gray-600">Types:</span>
|
||||
<div class="flex flex-wrap gap-1 mt-1">
|
||||
<span
|
||||
v-for="type in room.sensorTypes"
|
||||
<span
|
||||
v-for="type in room.sensorTypes"
|
||||
:key="type"
|
||||
class="text-xs px-2 py-0.5 bg-gray-200 text-gray-700 rounded"
|
||||
>
|
||||
{{ type }}
|
||||
</span>
|
||||
<span v-if="room.sensorTypes.length === 0" class="text-xs text-gray-500">None</span>
|
||||
<span v-if="room.sensorTypes.length === 0" class="text-xs text-gray-500"
|
||||
>None</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<span class="text-gray-600">Energy:</span>
|
||||
<div class="font-medium" :class="room.hasMetrics ? 'text-gray-900' : 'text-gray-400'">
|
||||
{{ room.hasMetrics ? room.energyConsumption.toFixed(2) + ' kWh' : 'No data' }}
|
||||
<div
|
||||
class="font-medium"
|
||||
:class="room.hasMetrics ? 'text-gray-900' : 'text-gray-400'"
|
||||
>
|
||||
{{
|
||||
room.hasMetrics ? room.energyConsumption.toFixed(2) + ' kWh' : 'No data'
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<span class="text-gray-600">CO2:</span>
|
||||
<div class="font-medium" :class="getCO2Color(room.co2Level)">
|
||||
{{ room.hasMetrics ? Math.round(room.co2Level) + ' ppm' : 'No data' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<span class="text-gray-600">Last Update:</span>
|
||||
<div class="text-xs text-gray-500">
|
||||
@@ -104,7 +114,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="ml-4">
|
||||
<button
|
||||
@click="confirmDeleteRoom(room.name)"
|
||||
@@ -118,7 +128,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Empty state -->
|
||||
<div v-if="roomsWithStats.length === 0" class="text-center py-8">
|
||||
<div class="text-gray-400 text-4xl mb-2">🏢</div>
|
||||
@@ -132,7 +142,7 @@
|
||||
<!-- Footer -->
|
||||
<div class="p-6 border-t border-gray-200 bg-gray-50">
|
||||
<div class="flex justify-end gap-3">
|
||||
<button
|
||||
<button
|
||||
@click="$emit('close')"
|
||||
class="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg text-sm font-medium hover:bg-gray-50 transition-colors"
|
||||
>
|
||||
@@ -143,23 +153,28 @@
|
||||
</div>
|
||||
|
||||
<!-- Delete Confirmation Modal -->
|
||||
<div v-if="roomToDelete" class="fixed inset-0 bg-black/50 flex items-center justify-center p-4 z-60">
|
||||
<div
|
||||
v-if="roomToDelete"
|
||||
class="fixed inset-0 bg-black/50 flex items-center justify-center p-4 z-60"
|
||||
>
|
||||
<div class="bg-white rounded-xl max-w-md w-full p-6">
|
||||
<h3 class="text-lg font-semibold text-gray-900 mb-2">Delete Room</h3>
|
||||
<p class="text-gray-600 mb-4">
|
||||
Are you sure you want to delete <strong>"{{ roomToDelete }}"</strong>?
|
||||
{{ getRoomStats(roomToDelete).sensorCount > 0
|
||||
? `This will unassign ${getRoomStats(roomToDelete).sensorCount} sensor(s).`
|
||||
: 'This action cannot be undone.' }}
|
||||
Are you sure you want to delete <strong>"{{ roomToDelete }}"</strong>?
|
||||
{{
|
||||
getRoomStats(roomToDelete).sensorCount > 0
|
||||
? `This will unassign ${getRoomStats(roomToDelete).sensorCount} sensor(s).`
|
||||
: 'This action cannot be undone.'
|
||||
}}
|
||||
</p>
|
||||
<div class="flex gap-3">
|
||||
<button
|
||||
<button
|
||||
@click="roomToDelete = null"
|
||||
class="flex-1 px-4 py-2 border border-gray-300 text-gray-700 rounded-lg text-sm font-medium hover:bg-gray-50 transition-colors"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
<button
|
||||
@click="deleteRoom"
|
||||
class="flex-1 px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-lg text-sm font-medium transition-colors"
|
||||
>
|
||||
@@ -274,7 +289,7 @@ const formatTime = (timestamp: number) => {
|
||||
const now = new Date()
|
||||
const diffMs = now.getTime() - date.getTime()
|
||||
const diffSecs = Math.floor(diffMs / 1000)
|
||||
|
||||
|
||||
if (diffSecs < 60) {
|
||||
return `${diffSecs}s ago`
|
||||
} else if (diffSecs < 3600) {
|
||||
@@ -296,4 +311,4 @@ const clearError = () => {
|
||||
// Watch for changes in newRoomName to clear errors
|
||||
import { watch } from 'vue'
|
||||
watch(newRoomName, clearError)
|
||||
</script>
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user