Skip to content

Commit 93ca89a

Browse files
Merge pull request #87 from abakus-ntnu/fix/spotlight-refresh
fix: make spotlight and group cards update on each page load
2 parents 875dd5d + 2dca2b6 commit 93ca89a

File tree

5 files changed

+175
-100
lines changed

5 files changed

+175
-100
lines changed

src/components/Card/LinkCard.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ interface Props {
1010
const { href, target = "_self", class: className, ...rest } = Astro.props;
1111
---
1212

13-
<a href={href} target={target}>
13+
<a href={href} target={target} data-spotlight="href">
1414
<Card
1515
class:list={[
1616
"group/linkcard transition-all hover:bg-gray-100 hover:shadow-md hover:dark:bg-gray-800",

src/components/Card/MultiImageCard.astro

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const { images } = Astro.props;
1818
{
1919
images
2020
.slice(0, 3)
21-
.map(({ src, alt }) => (
21+
.map(({ src, alt }, i) => (
2222
<div
2323
class:list={[
2424
"absolute left-0 top-0 aspect-square w-full overflow-hidden rounded-lg transition-transform",
@@ -34,9 +34,16 @@ const { images } = Astro.props;
3434
height={500}
3535
class="w-full"
3636
loading="eager"
37+
data-card-image={i}
3738
/>
3839
) : (
39-
<Image src={src} alt={alt} class="w-full" loading="eager" />
40+
<Image
41+
src={src}
42+
alt={alt}
43+
class="w-full"
44+
loading="eager"
45+
data-card-image={i}
46+
/>
4047
)}
4148
</div>
4249
))

src/components/Images/ProfilePicture.astro

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ interface Props {
1111
alt: string;
1212
}
1313
14-
const { class: className, src, alt } = Astro.props;
14+
const { class: className, src, alt, ...rest } = Astro.props;
1515
---
1616

1717
<Image
1818
class:list={["aspect-square w-auto rounded-full", className]}
1919
src={src}
2020
alt={alt}
21+
{...rest}
2122
/>

src/layouts/Home/HomePageLayout.astro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const lastWellFormedShow = PREVIOUS_REVUES.toReversed().find(
3838
<slot name="contact">
3939
<h2 class="text-center text-xl font-medium">Kontakt oss</h2>
4040
<div
41-
class="mx-auto grid max-w-screen-md grid-cols-1 gap-6 px-6 md:grid-cols-3"
41+
class="mx-auto grid max-w-screen-md grid-cols-1 gap-6 px-6 sm:grid-cols-3"
4242
>
4343
{
4444
SOCIALS.map(({ name, href, external, Icon }) => (

src/pages/om_oss/index.astro

Lines changed: 162 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import ProfilePicture from "@/components/Images/ProfilePicture.astro";
1414
import { Image } from "astro:assets";
1515
1616
import { SHOWS } from "@/lib/shows";
17-
import { getEntry } from "astro:content";
1817
import { getCollection } from "astro:content";
1918
2019
import { Calendar, Pencil } from "lucide-astro";
@@ -23,31 +22,27 @@ const om_oss = await getCollection("om_oss");
2322
const groups = await getCollection("grupper");
2423
const leaders = await getCollection("ledere");
2524
26-
const spotlightGroupIdx = Math.floor(Math.random() * groups.length);
27-
const spotlight = groups[spotlightGroupIdx];
28-
const spotlightLeader =
29-
spotlight.data.leaders && spotlight.data.leaders.length >= 1
30-
? await getEntry(spotlight.data.leaders[0])
31-
: await getEntry("ledere", "hamre");
25+
const spotlight = groups[0];
26+
const spotlightLeader = leaders[0];
3227
---
3328

3429
<PageLayout title="Om oss">
35-
<div class="container mx-auto space-y-6 px-3">
36-
<Title
37-
>Om <span class="text-primary" id="about-branding">Abakusrevyen</span
38-
></Title
39-
>
30+
<div
31+
id="root"
32+
data-groups={JSON.stringify(groups)}
33+
data-leaders={JSON.stringify(leaders)}
34+
class="container mx-auto space-y-6 px-3"
35+
>
36+
<Title>
37+
Om <span class="text-primary" id="about-branding">Abakusrevyen</span>
38+
</Title>
4039

4140
<div
4241
class="mx-auto grid max-w-screen-sm grid-cols-2 gap-10 py-6 md:gap-16 md:px-6 lg:gap-24"
4342
>
44-
<a href="/grupper" class="group">
43+
<a href="/grupper" class="group" id="groups-card" data-role="groups-card">
4544
<MultiImageCard
46-
images={[
47-
groups[(spotlightGroupIdx + 1) % groups.length],
48-
spotlight,
49-
groups[(spotlightGroupIdx + 2) % groups.length],
50-
].map((group) => ({
45+
images={[groups[0], groups[1], groups[2]].map((group) => ({
5146
src: group.data.logo,
5247
alt: `${group.data.name} logo`,
5348
}))}
@@ -56,7 +51,12 @@ const spotlightLeader =
5651
</MultiImageCard>
5752
</a>
5853

59-
<a href="/ledere" class="group">
54+
<a
55+
href="/ledere"
56+
class="group"
57+
id="leaders-card"
58+
data-role="leaders-card"
59+
>
6060
<MultiImageCard
6161
images={[leaders[0], spotlightLeader, leaders[1]].map((leader) => ({
6262
src: leader!.data.image,
@@ -106,85 +106,152 @@ const spotlightLeader =
106106
<div class="order-2 flex flex-col gap-3">
107107
<h2 class="text-lg font-bold">Spotlight</h2>
108108

109-
<LinkCard href={`/grupper/${spotlight.slug}`} class="flex">
110-
<div class="relative max-w-fit">
111-
<Image
112-
src={spotlight.data.logo}
113-
alt="Spotlight group logo"
114-
loading="eager"
115-
class="h-full w-36 min-w-36 rounded-l-lg"
116-
/>
117-
{
118-
spotlightLeader ? (
119-
<ProfilePicture
120-
src={spotlightLeader.data.image}
121-
alt="Spotlight leader"
122-
class="absolute bottom-1.5 right-1.5 h-1/3 object-cover opacity-60 transition-opacity hover:opacity-100"
123-
/>
124-
) : undefined
125-
}
126-
</div>
127-
<CardContent class="py-3 pl-3 pr-1.5">
128-
<h3 class="font-medium">{spotlight.data.name}</h3>
129-
<p class="text-sm sm:text-base md:text-sm lg:text-base">
130-
{spotlight.data.spotlight ?? spotlight.data.brief}
131-
</p>
132-
</CardContent>
133-
</LinkCard>
109+
<div data-role="spotlight">
110+
<LinkCard href={`/grupper/${spotlight.slug}`} class="flex">
111+
<div class="relative max-w-fit">
112+
<Image
113+
src={spotlight.data.logo}
114+
alt="Spotlight group logo"
115+
loading="eager"
116+
class="h-full w-36 min-w-36 rounded-l-lg"
117+
data-spotlight="logo"
118+
/>
119+
<ProfilePicture
120+
src={spotlightLeader.data.image}
121+
alt="Spotlight leader"
122+
class="absolute bottom-1.5 right-1.5 h-1/3 object-cover opacity-60 transition-opacity hover:opacity-100"
123+
data-spotlight="leader"
124+
/>
125+
<CardContent class="py-3 pl-3 pr-1.5">
126+
<h3 class="font-medium" data-spotlight="name">
127+
{spotlight.data.name}
128+
</h3>
129+
<p
130+
class="text-sm sm:text-base md:text-sm lg:text-base"
131+
data-spotlight="desc"
132+
>
133+
{spotlight.data.spotlight ?? spotlight.data.brief}
134+
</p>
135+
</CardContent>
136+
</div>
137+
</LinkCard>
138+
</div>
139+
</div>
140+
141+
<div class="space-y-6">
142+
<h2 class="text-lg font-bold">Innlegg</h2>
143+
<ul class="space-y-3">
144+
{
145+
om_oss
146+
.sort((a, b) => (b.data.pubDate < a.data.pubDate ? 1 : -1))
147+
.map(
148+
({
149+
slug,
150+
data: { title, pubDate, updateDate, description, image },
151+
}) => (
152+
<li>
153+
<LinkCard href={`/om_oss/${slug}`}>
154+
<div class="flex flex-col gap-3 rounded-lg border-[1px] border-gray-200 sm:flex-row dark:border-gray-500">
155+
<CardImage
156+
src={image}
157+
alt={`${title} post`}
158+
class="h-40 w-full overflow-hidden !rounded-t-md sm:h-48 sm:max-w-[25%] sm:!rounded-tr-none"
159+
/>
160+
161+
<CardContent class="flex flex-col justify-between px-1.5 py-3">
162+
<h2 class="font-medium">{title}</h2>
163+
<p>{description}</p>
164+
165+
<div class="flex flex-col gap-3 text-sm sm:flex-row sm:items-center">
166+
<CardDetail>
167+
<Calendar />
168+
{pubDate.toLocaleString("NO-nb", {
169+
day: "numeric",
170+
month: "numeric",
171+
year: "numeric",
172+
})}
173+
</CardDetail>
174+
<CardDetail>
175+
<Pencil />
176+
{(updateDate ?? pubDate).toLocaleString("NO-nb", {
177+
day: "numeric",
178+
month: "numeric",
179+
year: "numeric",
180+
})}
181+
</CardDetail>
182+
</div>
183+
</CardContent>
184+
</div>
185+
</LinkCard>
186+
</li>
187+
),
188+
)
189+
}
190+
</ul>
134191
</div>
135192
</div>
136193

137-
<div class="space-y-6">
138-
<h2 class="text-lg font-bold">Innlegg</h2>
139-
140-
<ul class="space-y-3">
141-
{
142-
om_oss
143-
.sort((a, b) => (b.data.pubDate < a.data.pubDate ? 1 : -1))
144-
.map(
145-
({
146-
slug,
147-
data: { title, pubDate, updateDate, description, image },
148-
}) => (
149-
<li>
150-
<LinkCard href={`/om_oss/${slug}`}>
151-
<div class="flex flex-col gap-3 rounded-lg border-[1px] border-gray-200 sm:flex-row dark:border-gray-500">
152-
<CardImage
153-
src={image}
154-
alt={`${title} post`}
155-
class="h-40 w-full overflow-hidden !rounded-t-md sm:h-48 sm:max-w-[25%] sm:!rounded-tr-none"
156-
/>
157-
158-
<CardContent class="flex flex-col justify-between px-1.5 py-3">
159-
<h2 class="font-medium">{title}</h2>
160-
<p>{description}</p>
161-
162-
<div class="flex flex-col gap-3 text-sm sm:flex-row sm:items-center">
163-
<CardDetail>
164-
<Calendar />
165-
{pubDate.toLocaleString("NO-nb", {
166-
day: "numeric",
167-
month: "numeric",
168-
year: "numeric",
169-
})}
170-
</CardDetail>
171-
<CardDetail>
172-
<Pencil />
173-
{(updateDate ?? pubDate).toLocaleString("NO-nb", {
174-
day: "numeric",
175-
month: "numeric",
176-
year: "numeric",
177-
})}
178-
</CardDetail>
179-
</div>
180-
</CardContent>
181-
</div>
182-
</LinkCard>
183-
</li>
184-
),
185-
)
194+
<script is:inline>
195+
document.addEventListener("DOMContentLoaded", () => {
196+
const root = document.getElementById("root");
197+
if (!root) return;
198+
199+
const groups = JSON.parse(root.dataset.groups);
200+
const leaders = JSON.parse(root.dataset.leaders);
201+
202+
const spotlightGroupIdx = Math.floor(Math.random() * groups.length);
203+
const spotlight = groups[spotlightGroupIdx];
204+
const spotlightLeader =
205+
leaders.find((l) => l.slug === spotlight.data.leaders?.[0].slug) ??
206+
leaders[0];
207+
208+
const selectedGroups = [
209+
groups[(spotlightGroupIdx + 1) % groups.length],
210+
groups[spotlightGroupIdx],
211+
groups[(spotlightGroupIdx + 2) % groups.length],
212+
];
213+
214+
const groupCard = document.querySelector("[data-role='groups-card']");
215+
if (groupCard) {
216+
selectedGroups.forEach((g, i) => {
217+
const img = groupCard.querySelector(`[data-card-image='${i}']`);
218+
if (img) {
219+
img.src = g.data.logo.src;
220+
img.alt = `${g.data.name} logo`;
221+
}
222+
});
186223
}
187-
</ul>
188-
</div>
224+
225+
const leaderCard = document.querySelector("[data-role='leaders-card']");
226+
if (leaderCard) {
227+
selectedGroups.forEach((g, i) => {
228+
const leader = leaders.find(
229+
(l) => l.slug === g.data.leaders?.[0].slug,
230+
);
231+
const img = leaderCard.querySelector(`[data-card-image='${i}']`);
232+
if (img && leader) {
233+
img.src = leader.data.image.src;
234+
img.alt = leader.data.name;
235+
}
236+
});
237+
}
238+
239+
const spotlightCard = document.querySelector("[data-role='spotlight']");
240+
if (spotlightCard) {
241+
spotlightCard.querySelector("[data-spotlight='logo']").src =
242+
spotlight.data.logo.src;
243+
spotlightCard.querySelector("[data-spotlight='logo']").alt =
244+
`${spotlight.data.name} logo`;
245+
spotlightCard.querySelector("[data-spotlight='leader']").src =
246+
spotlightLeader.data.image.src;
247+
spotlightCard.querySelector("[data-spotlight='name']").textContent =
248+
spotlight.data.name;
249+
spotlightCard.querySelector("[data-spotlight='desc']").textContent =
250+
spotlight.data.spotlight ?? spotlight.data.brief;
251+
spotlightCard.querySelector("[data-spotlight='href']").href =
252+
`/grupper/${spotlight.slug}`;
253+
}
254+
});
255+
</script>
189256
</div>
190257
</PageLayout>

0 commit comments

Comments
 (0)