forked from
slices.network/slices
Highly ambitious ATProtocol AppView service and sdks
1import { Link } from "react-router-dom";
2import { getRkey } from "../utils.ts";
3import { Sparkline } from "./Sparkline.tsx";
4
5type SliceNode = {
6 uri: string;
7 name: string;
8 domain: string;
9 createdAt: string;
10 actorHandle?: string | null;
11 networkSlicesActorProfile?: {
12 avatar?: {
13 url: string;
14 } | null;
15 } | null;
16 appBskyActorProfile?: {
17 avatar?: {
18 url: string;
19 } | null;
20 } | null;
21 sparklines?: any;
22};
23
24interface SliceListProps {
25 slices: SliceNode[];
26 showSparklines?: boolean;
27}
28
29export function SliceList({ slices, showSparklines = false }: SliceListProps) {
30 return (
31 <div className="border-y border-zinc-800 divide-y divide-zinc-800">
32 {slices.map((slice) => {
33 const sliceRkey = getRkey(slice.uri);
34 const profileLink = slice.actorHandle
35 ? `/profile/${slice.actorHandle}/slice/${sliceRkey}`
36 : "#";
37
38 const avatar =
39 slice.networkSlicesActorProfile?.avatar ||
40 slice.appBskyActorProfile?.avatar;
41
42 return (
43 <Link
44 key={slice.uri}
45 to={profileLink}
46 className="block py-4 overflow-hidden hover:bg-zinc-900/30 transition-colors relative"
47 >
48 {/* Sparkline overlay in background */}
49 {showSparklines && slice.sparklines && (
50 <div className="absolute inset-0 opacity-10 pointer-events-none flex items-end">
51 <Sparkline
52 sparklines={slice.sparklines}
53 width={800}
54 height={100}
55 className="w-full"
56 />
57 </div>
58 )}
59
60 {/* Card content */}
61 <div className="relative z-10 px-4">
62 <div className="flex items-start gap-3">
63 {avatar && (
64 <img
65 src={avatar.url}
66 alt={slice.name}
67 className="w-8 h-8 rounded-full"
68 />
69 )}
70 <div className="flex-1">
71 <div className="flex items-start justify-between">
72 <div>
73 <h2 className="text-sm font-medium text-zinc-300 mb-1">
74 {slice.name}
75 </h2>
76 <p className="text-xs text-zinc-500">{slice.domain}</p>
77 </div>
78 {slice.actorHandle && (
79 <span className="text-xs text-zinc-600">
80 @{slice.actorHandle}
81 </span>
82 )}
83 </div>
84 <div className="flex items-center justify-between mt-3">
85 <p className="text-xs text-zinc-700">
86 {new Date(slice.createdAt).toLocaleDateString()}
87 </p>
88 </div>
89 </div>
90 </div>
91 </div>
92 </Link>
93 );
94 })}
95 </div>
96 );
97}