Skip to content

Commit

Permalink
device management panel (read only)
Browse files Browse the repository at this point in the history
  • Loading branch information
KishinZW committed May 22, 2024
1 parent a027d26 commit a8fd4d1
Show file tree
Hide file tree
Showing 11 changed files with 283 additions and 0 deletions.
16 changes: 16 additions & 0 deletions components/ui/table/Table.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<div class="relative w-full overflow-auto">
<table :class="cn('w-full caption-bottom text-sm', props.class)">
<slot />
</table>
</div>
</template>
14 changes: 14 additions & 0 deletions components/ui/table/TableBody.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<tbody :class="cn('[&_tr:last-child]:border-0', props.class)">
<slot />
</tbody>
</template>
14 changes: 14 additions & 0 deletions components/ui/table/TableCaption.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<caption :class="cn('mt-4 text-sm text-muted-foreground', props.class)">
<slot />
</caption>
</template>
21 changes: 21 additions & 0 deletions components/ui/table/TableCell.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<td
:class="
cn(
'p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-0.5',
props.class,
)
"
>
<slot />
</td>
</template>
37 changes: 37 additions & 0 deletions components/ui/table/TableEmpty.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script setup lang="ts">
import { type HTMLAttributes, computed } from 'vue'
import TableRow from './TableRow.vue'
import TableCell from './TableCell.vue'
import { cn } from '@/lib/utils'
const props = withDefaults(defineProps<{
class?: HTMLAttributes['class']
colspan?: number
}>(), {
colspan: 1,
})
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props
return delegated
})
</script>

<template>
<TableRow>
<TableCell
:class="
cn(
'p-4 whitespace-nowrap align-middle text-sm text-foreground',
props.class,
)
"
v-bind="delegatedProps"
>
<div class="flex items-center justify-center py-10">
<slot />
</div>
</TableCell>
</TableRow>
</template>
14 changes: 14 additions & 0 deletions components/ui/table/TableFooter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<tfoot :class="cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', props.class)">
<slot />
</tfoot>
</template>
14 changes: 14 additions & 0 deletions components/ui/table/TableHead.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<th :class="cn('h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-0.5', props.class)">
<slot />
</th>
</template>
14 changes: 14 additions & 0 deletions components/ui/table/TableHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<thead :class="cn('[&_tr]:border-b', props.class)">
<slot />
</thead>
</template>
14 changes: 14 additions & 0 deletions components/ui/table/TableRow.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<tr :class="cn('border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted', props.class)">
<slot />
</tr>
</template>
8 changes: 8 additions & 0 deletions components/ui/table/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export { default as Table } from './Table.vue'
export { default as TableBody } from './TableBody.vue'
export { default as TableCell } from './TableCell.vue'
export { default as TableHead } from './TableHead.vue'
export { default as TableHeader } from './TableHeader.vue'
export { default as TableRow } from './TableRow.vue'
export { default as TableCaption } from './TableCaption.vue'
export { default as TableEmpty } from './TableEmpty.vue'
117 changes: 117 additions & 0 deletions pages/device.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<template>
<div class="grid gap-4 md:grid-cols-2 md:gap-8 lg:grid-cols-4">
<Card>
<CardHeader class="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle class="text-sm font-medium">
Total Revenue
</CardTitle>
<DollarSign class="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div class="text-2xl font-bold">
$45,231.89
</div>
<p class="text-xs text-muted-foreground">
+20.1% from last month
</p>
</CardContent>
</Card>
<Card>
<CardHeader class="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle class="text-sm font-medium">
Subscriptions
</CardTitle>
<Users class="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div class="text-2xl font-bold">
+2350
</div>
<p class="text-xs text-muted-foreground">
+180.1% from last month
</p>
</CardContent>
</Card>
<Card>
<CardHeader class="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle class="text-sm font-medium">
Sales
</CardTitle>
<CreditCard class="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div class="text-2xl font-bold">
+12,234
</div>
<p class="text-xs text-muted-foreground">
+19% from last month
</p>
</CardContent>
</Card>
<Card>
<CardHeader class="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle class="text-sm font-medium">
Active Now
</CardTitle>
<Activity class="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div class="text-2xl font-bold">
+573
</div>
<p class="text-xs text-muted-foreground">
+201 since last hour
</p>
</CardContent>
</Card>
</div>
<div class="grid gap-4 md:gap-8 lg:grid-cols-2 xl:grid-cols-3">
<Card class="xl:col-span-2">
<CardHeader class="flex flex-row items-center">
<div class="grid gap-2">
<CardTitle>所有设备</CardTitle>
</div>
</CardHeader>
<CardContent>
<Table>
<TableHeader>
<TableRow>
<TableHead class="w-[100px]">
设备id
</TableHead>
<TableHead>设备名称</TableHead>
<TableHead>创建时间</TableHead>
<TableHead class="text-right">
节目id
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow v-for="device in list" :key="device.id">
<TableCell class="font-medium">
{{ device.id }}
</TableCell>
<TableCell>{{ device.location }}</TableCell>
<TableCell>{{ device.createdAt.toLocaleDateString() }}</TableCell>
<TableCell class="text-right">
{{ device.programId }}
</TableCell>
</TableRow>
</TableBody>
</Table>
</CardContent>
</Card>
</div>
</template>

<script setup lang="ts">
import { Activity, ArrowUpRight, CreditCard, DollarSign, Users } from 'lucide-vue-next';
const { $api } = useNuxtApp();
const { data: list, suspense } = useQuery({
queryKey: ['device.list'],
queryFn: () => $api.device.list.query(),
});
await suspense();
</script>

0 comments on commit a8fd4d1

Please sign in to comment.