Skip to content

Commit ea5d050

Browse files
committed
feat(sponsor): 企業スポンサーコンポーネントを作成
1 parent a90096c commit ea5d050

File tree

4 files changed

+136
-82
lines changed

4 files changed

+136
-82
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
// Company.astro
3+
type Props = {
4+
sponsor: {
5+
rank: "platinum" | "gold" | "silver" | "bronze";
6+
name: string;
7+
url: string;
8+
image: string;
9+
};
10+
};
11+
12+
const props = Astro.props;
13+
const { rank, name, url, image } = props.sponsor;
14+
15+
let imageUrl = "";
16+
try {
17+
const module = await import(`../../assets/sponsors/${image}?url`);
18+
imageUrl = module.default;
19+
} catch (e) {
20+
console.error(`Icon not found: ${image}`);
21+
}
22+
23+
// ランクごとのスタイル設定
24+
const rankStyles = {
25+
platinum: {
26+
container: "mb-4 flex h-28 items-center justify-center md:h-36 lg:h-40",
27+
image: "max-h-full max-w-full object-contain",
28+
},
29+
gold: {
30+
container: "mb-3 flex h-20 items-center justify-center md:h-24 lg:h-28",
31+
image: "max-h-full max-w-full object-contain",
32+
},
33+
silver: {
34+
container: "mb-2 flex h-14 items-center justify-center md:h-16 lg:h-20",
35+
image: "max-h-full max-w-full object-contain",
36+
},
37+
bronze: {
38+
container: "mb-2 flex h-12 items-center justify-center md:h-14 lg:h-16",
39+
image: "max-h-full max-w-full object-contain",
40+
},
41+
};
42+
43+
const currentStyle = rankStyles[rank];
44+
---
45+
46+
<a
47+
href={url}
48+
class="relative block w-full max-w-xs"
49+
target="_blank"
50+
rel="noopener noreferrer"
51+
>
52+
<div class={currentStyle.container}>
53+
<img alt={name} src={imageUrl} class={currentStyle.image} loading="lazy" />
54+
</div>
55+
</a>
Lines changed: 47 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,49 @@
1-
<div class="mb-10">
2-
<h3 class="mb-6 text-center text-xl font-semibold md:text-2xl">
3-
企業スポンサー
4-
</h3>
5-
<div class="space-y-10">
6-
<div class="space-y-6">
7-
<h4 class="text-center text-lg font-medium">プラチナ</h4>
8-
<div class="grid grid-cols-1 justify-items-center gap-8 md:grid-cols-2">
9-
<div class="flex flex-col items-center">
10-
<div class="mb-3 flex h-24 items-center justify-center md:h-32">
11-
<img alt="Acme Inc." class="max-h-full max-w-full object-contain" />
12-
</div>
13-
<h4 class="text-base font-medium text-gray-800 md:text-lg">
14-
Acme Inc.
15-
</h4>
16-
</div>
17-
<div class="flex flex-col items-center">
18-
<div class="mb-3 flex h-24 items-center justify-center md:h-32">
19-
<img alt="TechCorp" class="max-h-full max-w-full object-contain" />
20-
</div>
21-
<h4 class="text-base font-medium text-gray-800 md:text-lg">
22-
TechCorp
23-
</h4>
24-
</div>
25-
</div>
26-
</div>
27-
<div class="space-y-6">
28-
<h4 class="text-center text-lg font-medium">ゴールド</h4>
29-
<div class="grid grid-cols-2 justify-items-center gap-6 md:grid-cols-3">
30-
<div class="flex flex-col items-center">
31-
<div class="mb-2 flex h-20 items-center justify-center md:h-24">
32-
<img
33-
alt="DevSolutions"
34-
class="max-h-full max-w-full object-contain"
35-
/>
36-
</div>
37-
<h4 class="text-sm font-medium text-gray-800 md:text-base">
38-
DevSolutions
39-
</h4>
40-
</div>
41-
<div class="flex flex-col items-center">
42-
<div class="mb-2 flex h-20 items-center justify-center md:h-24">
43-
<img
44-
alt="CodeMasters"
45-
class="max-h-full max-w-full object-contain"
46-
/>
47-
</div>
48-
<h4 class="text-sm font-medium text-gray-800 md:text-base">
49-
CodeMasters
50-
</h4>
51-
</div>
52-
</div>
53-
</div>
54-
<div class="space-y-6">
55-
<h4 class="text-center text-lg font-medium">シルバー</h4>
56-
<div class="grid grid-cols-3 justify-items-center gap-4 md:grid-cols-4">
57-
<div class="flex flex-col items-center">
58-
<div class="mb-2 flex h-12 items-center justify-center md:h-16">
59-
<img alt="ByteWorks" class="max-h-full max-w-full object-contain" />
60-
</div>
61-
<h4 class="text-center text-xs font-medium text-gray-800 md:text-sm">
62-
ByteWorks
1+
---
2+
import { getCollection } from "astro:content";
3+
import Company from "./Company.astro";
4+
import Heading from "../Heading.astro";
5+
6+
const sponsorsData = await getCollection("sponsors");
7+
8+
const sponsors = sponsorsData.map((sponsor) => sponsor.data);
9+
10+
const sponsorsByRank = sponsors.reduce(
11+
(acc, sponsor) => {
12+
if (!acc[sponsor.rank]) {
13+
acc[sponsor.rank] = [];
14+
}
15+
acc[sponsor.rank].push(sponsor);
16+
return acc;
17+
},
18+
{} as Record<string, typeof sponsors>,
19+
);
20+
21+
const rankOrder = ["platinum", "gold", "silver", "bronze"];
22+
---
23+
24+
<Heading>企業スポンサー</Heading>
25+
{
26+
rankOrder.map(
27+
(rank) =>
28+
sponsorsByRank[rank] && (
29+
<>
30+
<h4 class="mb-4 text-center text-lg font-medium capitalize">
31+
{rank}
6332
</h4>
64-
</div>
65-
<div class="flex flex-col items-center">
66-
<div class="mb-2 flex h-12 items-center justify-center md:h-16">
67-
<img alt="EditPro" class="max-h-full max-w-full object-contain" />
33+
<div
34+
class:list={[
35+
"mb-8 grid place-items-center gap-4",
36+
{ "grid-cols-1": rank === "platinum" },
37+
{ "grid-cols-2 md:grid-cols-2": rank === "gold" },
38+
{ "grid-cols-2 md:grid-cols-3": rank === "silver" },
39+
{ "grid-cols-2 md:grid-cols-4": rank === "bronze" },
40+
]}
41+
>
42+
{sponsorsByRank[rank].map((sponsor) => (
43+
<Company {sponsor} />
44+
))}
6845
</div>
69-
<h4 class="text-center text-xs font-medium text-gray-800 md:text-sm">
70-
EditPro
71-
</h4>
72-
</div>
73-
<div class="flex flex-col items-center">
74-
<div class="mb-2 flex h-12 items-center justify-center md:h-16">
75-
<img alt="VimTools" class="max-h-full max-w-full object-contain" />
76-
</div>
77-
<h4 class="text-center text-xs font-medium text-gray-800 md:text-sm">
78-
VimTools
79-
</h4>
80-
</div>
81-
</div>
82-
</div>
83-
</div>
84-
</div>
46+
</>
47+
),
48+
)
49+
}

2025/src/components/Sponsors/index.astro

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
---
2+
import Companies from "./Companies.astro";
23
import Card from "../Card.astro";
34
import Heading from "../Heading.astro";
45
import {
@@ -12,6 +13,10 @@ import {
1213
---
1314

1415
<section id="sponsors" class="bg-emerald-50 py-10 md:py-16">
16+
<Companies />
17+
</section>
18+
19+
<section id="why-sponsors" class="bg-emerald-50 py-10 md:py-16">
1520
<div class="container mx-auto px-4">
1621
<Heading> スポンサー </Heading>
1722
<div class="mx-auto mb-12 max-w-4xl">

2025/src/content/config.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { glob } from "astro/loaders";
2+
// src/content/config.ts
3+
import { defineCollection, z } from "astro:content";
4+
5+
const sponsors = defineCollection({
6+
loader: glob({
7+
pattern: "*.toml",
8+
base: "./src/content/sponsors",
9+
}),
10+
schema: z.object({
11+
rank: z.enum(["platinum", "gold", "silver", "bronze"]),
12+
name: z.string(),
13+
url: z.string().url(),
14+
image: z.string(),
15+
// sponsor: z.array(
16+
// z.object({
17+
// rank: z.enum(['gold', 'silver', 'bronze']),
18+
// name: z.string(),
19+
// url: z.string().url(),
20+
// image: z.string()
21+
// })
22+
// )
23+
}),
24+
});
25+
26+
// コレクションのエクスポート
27+
export const collections = {
28+
sponsors,
29+
};

0 commit comments

Comments
 (0)