an app to share curated trails
sidetrail.app
1import Link from "next/link";
2import type { User } from "../data/queries";
3import { loadTrailActiveWalkers } from "../data/queries";
4import { FloatingAvatar } from "./FloatingAvatar";
5import "./TrailCard.css";
6
7type Props = {
8 uri: string;
9 rkey: string;
10 creatorHandle: string;
11 title: string;
12 description: string;
13 accentColor: string;
14 backgroundColor: string;
15 creator: User;
16 stopsCount: number;
17};
18
19async function ActiveWalkers({ trailUri }: { trailUri: string }) {
20 const walkers = await loadTrailActiveWalkers(trailUri);
21 const displayWalkers = walkers.filter((w) => w.avatar).slice(0, 3);
22
23 if (displayWalkers.length === 0) return null;
24
25 return (
26 <div className="TrailCard-walkers">
27 {displayWalkers.map((walker, i) => {
28 return (
29 <FloatingAvatar
30 key={i}
31 src={walker.avatar}
32 title={walker.handle}
33 contained={true}
34 opaque={true}
35 handle={walker.handle}
36 />
37 );
38 })}
39 </div>
40 );
41}
42
43export async function TrailCard({
44 uri,
45 rkey,
46 creatorHandle,
47 title,
48 description,
49 accentColor,
50 backgroundColor,
51 creator,
52 stopsCount,
53}: Props) {
54 return (
55 <div className="TrailCard">
56 <Link href={`/@${creatorHandle}/trail/${rkey}`} className="TrailCard-underlay" />
57 <div
58 className="TrailCard-bg"
59 style={
60 {
61 "--accent-color": accentColor,
62 "--accent-color-transparent": `${accentColor}15`,
63 "--bg-color": backgroundColor,
64 } as React.CSSProperties
65 }
66 >
67 <h3 className="TrailCard-title">
68 <span>{title}</span>
69 </h3>
70 <p className="TrailCard-description">{description}</p>
71 <div className="TrailCard-meta">
72 <span className="TrailCard-creator">@{creator.handle}</span>
73 <div className="TrailCard-activity">
74 <ActiveWalkers trailUri={uri} />
75 <span className="TrailCard-steps">{stopsCount} stops</span>
76 </div>
77 </div>
78 </div>
79 </div>
80 );
81}