Skip to content

Commit e857f5e

Browse files
committed
Improve UI
1 parent df39f5f commit e857f5e

File tree

4 files changed

+70
-44
lines changed

4 files changed

+70
-44
lines changed

src/app/conf/2025/components/speaker-card.tsx

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,6 @@ export interface SpeakerCardProps extends React.HTMLAttributes<HTMLDivElement> {
1717
year: string
1818
}
1919

20-
function Stripes({ mask }: { mask?: string }) {
21-
return (
22-
<div
23-
role="presentation"
24-
className="pointer-events-none absolute inset-0 inset-y-[-20px]"
25-
style={{
26-
maskImage: mask,
27-
WebkitMaskImage: mask,
28-
}}
29-
>
30-
<StripesDecoration oddClassName="absolute inset-0 bg-gradient-to-b from-sec-dark to-sec-light" />
31-
</div>
32-
)
33-
}
3420

3521
export function SpeakerCard({
3622
tags = [],
@@ -42,7 +28,7 @@ export function SpeakerCard({
4228
return (
4329
<article
4430
className={clsx(
45-
"relative flex flex-col overflow-hidden border border-neu-300",
31+
"relative flex flex-col overflow-hidden border border-neu-300 [container-type:inline-size]",
4632
className,
4733
)}
4834
{...props}
@@ -127,3 +113,19 @@ function SpeakerLinks({
127113
</div>
128114
)
129115
}
116+
117+
118+
function Stripes({ mask }: { mask?: string }) {
119+
return (
120+
<div
121+
role="presentation"
122+
className="pointer-events-none absolute inset-0 inset-y-[-20px]"
123+
style={{
124+
maskImage: mask,
125+
WebkitMaskImage: mask,
126+
}}
127+
>
128+
<StripesDecoration oddClassName="absolute inset-0 bg-gradient-to-b from-sec-dark to-sec-light" />
129+
</div>
130+
)
131+
}

src/app/conf/2025/schedule/[id]/page.tsx

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,6 @@ import { CalendarIcon } from "../../pixelarticons/calendar-icon"
1818
import { SpeakerCard } from "../../components/speaker-card"
1919
import { Anchor } from "@/app/conf/_design-system/anchor"
2020

21-
function getEventTitle(event: ScheduleSession, speakers: string[]): string {
22-
let { name } = event
23-
24-
if (!speakers) {
25-
return name
26-
}
27-
28-
speakers?.forEach(speaker => {
29-
const speakerInTitle = name.indexOf(`- ${speaker.replace("ı", "i")}`)
30-
if (speakerInTitle > -1) {
31-
name = name.slice(0, speakerInTitle)
32-
}
33-
})
34-
35-
return name
36-
}
37-
3821
type SessionProps = { params: { id: string } }
3922

4023
export function generateMetadata({ params }: SessionProps): Metadata {

src/app/conf/2025/schedule/_components/schedule-session-card.tsx

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
import { getEventTitle } from "@/app/conf/2023/utils"
1+
import React from "react"
2+
23
import { SchedSpeaker } from "@/app/conf/2023/types"
4+
import { Anchor } from "@/app/conf/_design-system/anchor"
5+
import { Tag } from "@/app/conf/_design-system/tag"
36

47
import { PinIcon } from "../../pixelarticons/pin-icon"
5-
import { Tag } from "@/app/conf/_design-system/tag"
68

79
import { type ScheduleSession } from "./session-list"
10+
import { getEventTitle } from "../../utils"
811

9-
function isString(x: any) {
12+
function isString(x: unknown): x is string {
1013
return Object.prototype.toString.call(x) === "[object String]"
1114
}
1215

@@ -26,14 +29,16 @@ export function ScheduleSessionCard({
2629
: session.event_type
2730

2831
const speakers = session.speakers
29-
const formattedSpeakers = isString(speakers || [])
30-
? (speakers as string)?.split(",")
31-
: (speakers as SchedSpeaker[])?.map(e => e.name)
32+
? isString(session.speakers)
33+
? (session.speakers as string)
34+
.split(",")
35+
.map(name => ({ name, username: "" }))
36+
: (session.speakers as SchedSpeaker[])
37+
: []
3238

3339
const eventTitle = getEventTitle(
34-
// @ts-expect-error fixme
3540
session,
36-
formattedSpeakers,
41+
speakers.map(s => s.name),
3742
)
3843

3944
const eventColor = eventsColors[session.event_type]
@@ -50,6 +55,7 @@ export function ScheduleSessionCard({
5055
href={`/conf/${year}/schedule/${session.id}?name=${session.name}`}
5156
className="group relative size-full bg-neu-0 p-4 font-normal no-underline ring-neu-400 hover:bg-neu-0/90 hover:ring-1 focus-visible:z-[1] dark:ring-neu-100 dark:hover:bg-neu-0/80 max-lg:mt-px"
5257
>
58+
{/* todo: fix link nesting */}
5359
<span className="flex h-full flex-col justify-start">
5460
{eventColor && (
5561
<Tag className="mb-3" color={eventColor}>
@@ -61,12 +67,25 @@ export function ScheduleSessionCard({
6167
<span className="typography-body-md">{eventTitle}</span>
6268
<span className="flex flex-col">
6369
{(speakers?.length || 0) > 0 && (
64-
<span className="typography-body-sm">
65-
{/* todo: link to speakers (anchor background on z-index above the main link layer) */}
66-
{formattedSpeakers.join(", ")}
70+
<span className="typography-body-sm z-[2]">
71+
{speakers.map((s, i) => (
72+
<React.Fragment key={s.username || s.name}>
73+
{s.username ? (
74+
<Anchor
75+
href={`/conf/${year}/speakers/${s.username}`}
76+
className="decoration-neu-500 hover:underline dark:decoration-neu-100"
77+
>
78+
{s.name}
79+
</Anchor>
80+
) : (
81+
s.name
82+
)}
83+
{i !== speakers.length - 1 && <span>, </span>}
84+
</React.Fragment>
85+
))}
6786
</span>
6887
)}
69-
<span className="mt-2 flex items-center gap-0.5 typography-body-xs">
88+
<span className="typography-body-xs mt-2 flex items-center gap-0.5">
7089
<PinIcon className="size-4 text-pri-base" />
7190
{session.venue}
7291
</span>

src/app/conf/2025/utils.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { ScheduleSession } from "../2023/types"
2+
13
export const eventsColors: Record<string, string> = {
24
Breaks: "#7DAA5E",
35
"Keynote Sessions": "#7e66cc",
@@ -17,3 +19,23 @@ export const eventsColors: Record<string, string> = {
1719
"GraphQL Spec": "#6B73CC",
1820
Scaling: "#8D8D8D",
1921
}
22+
23+
export function getEventTitle(
24+
event: Pick<ScheduleSession, "name">,
25+
speakers: string[],
26+
): string {
27+
let { name } = event
28+
29+
if (!speakers) {
30+
return name
31+
}
32+
33+
speakers?.forEach(speaker => {
34+
const speakerInTitle = name.indexOf(`- ${speaker.replace("ı", "i")}`)
35+
if (speakerInTitle > -1) {
36+
name = name.slice(0, speakerInTitle)
37+
}
38+
})
39+
40+
return name
41+
}

0 commit comments

Comments
 (0)