table
Projects table with team avatars and status
Projects table with team avatars and status
Загрузка превью…
src/table/c-table-8.vue
<!--
Расхождение с апстримом: `IconPlaceholder` заменена инлайновым `<svg>`
(lucide-react v0.545.0 "folder") и unsplash-аватары заменены локальным
1x1 data-URI (`PIXEL`) — см. docs/PORTING.md §5.
-->
<script setup lang="ts">
import { Badge } from "@/components/reui/badge"
import { Avatar, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage } from "@/components/ui/avatar"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
const PIXEL = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAUwAOw=="
const projects = [
{
name: "Website Redesign",
description: "Landing page and marketing site",
status: "In Progress",
statusVariant: "info-light" as const,
team: [
{ src: PIXEL, fallback: "SC" },
{ src: PIXEL, fallback: "MJ" },
{ src: PIXEL, fallback: "EP" },
],
extra: 2,
dueDate: "Mar 15",
},
{
name: "Mobile App v2",
description: "iOS and Android release",
status: "Review",
statusVariant: "warning-light" as const,
team: [
{ src: PIXEL, fallback: "DK" },
{ src: PIXEL, fallback: "SD" },
],
extra: 0,
dueDate: "Apr 1",
},
{
name: "API Integration",
description: "Third-party payment gateway",
status: "Completed",
statusVariant: "success-light" as const,
team: [{ src: PIXEL, fallback: "MJ" }],
extra: 0,
dueDate: "Feb 28",
},
{
name: "Analytics Dashboard",
description: "Real-time metrics and reporting",
status: "Planning",
statusVariant: "outline" as const,
team: [
{ src: PIXEL, fallback: "SC" },
{ src: PIXEL, fallback: "DK" },
{ src: PIXEL, fallback: "EP" },
],
extra: 4,
dueDate: "May 10",
},
]
</script>
<template>
<div class="mx-auto flex w-full max-w-2xl flex-col">
<Table>
<TableHeader>
<TableRow>
<TableHead>Project</TableHead>
<TableHead>Status</TableHead>
<TableHead>Team</TableHead>
<TableHead class="text-right">Due</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow v-for="project in projects" :key="project.name">
<TableCell>
<div class="flex items-center gap-3">
<div class="bg-muted rounded-sm flex size-8 shrink-0 items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-folder text-muted-foreground size-4">
<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" />
</svg>
</div>
<div class="flex flex-col">
<span class="text-sm font-medium">{{ project.name }}</span>
<span class="text-muted-foreground text-xs">{{ project.description }}</span>
</div>
</div>
</TableCell>
<TableCell>
<Badge :variant="project.statusVariant" size="sm">{{ project.status }}</Badge>
</TableCell>
<TableCell>
<AvatarGroup>
<Avatar v-for="member in project.team" :key="member.fallback" size="sm">
<AvatarImage :src="member.src" :alt="member.fallback" />
<AvatarFallback>{{ member.fallback }}</AvatarFallback>
</Avatar>
<AvatarGroupCount v-if="project.extra > 0">
<span class="text-muted-foreground text-[0.625rem]">+{{ project.extra }}</span>
</AvatarGroupCount>
</AvatarGroup>
</TableCell>
<TableCell class="text-muted-foreground text-right text-sm">{{ project.dueDate }}</TableCell>
</TableRow>
</TableBody>
</Table>
</div>
</template>