diff --git a/apps/web/app/_components/footer.tsx b/apps/web/app/_components/footer.tsx
index 8909b2c8..7ccbf09c 100644
--- a/apps/web/app/_components/footer.tsx
+++ b/apps/web/app/_components/footer.tsx
@@ -3,36 +3,29 @@
import GlassCard from "@/components/glassCard"
import IconCircle from "@/components/iconCircle"
import { siteConfig } from "@/config/site"
+import { SponsorList, SponsorTiers } from "@/config/sponsors"
import Link from "next/link"
-interface Sponsor {
- name: string
- image_path: string
-}
-
function Sponsor() {
- const SPONSOR_LIST: Sponsor[] = [
- /* TBA */
- ]
- if (SPONSOR_LIST.length < 1) return <>>
+ if (SponsorList.length < 1) return <>>
return (
สนับสนุนโดย
- {SPONSOR_LIST.map((s) => (
+ {SponsorList.map((s) => (
-
+
))}
- เราขอขอบคุณ {SPONSOR_LIST.map((s) => s.name).join(", ")}
+ เราขอขอบคุณ {SponsorList.map((s) => s.name).join(", ")}
diff --git a/apps/web/app/_components/sponsors/index.tsx b/apps/web/app/_components/sponsors/index.tsx
new file mode 100644
index 00000000..7130d3d7
--- /dev/null
+++ b/apps/web/app/_components/sponsors/index.tsx
@@ -0,0 +1,26 @@
+import { Heading } from "@/components/heading"
+import { SponsorList, SponsorTiers } from "@/config/sponsors"
+
+import SponsorSubgrid from "./subgrid"
+
+export default function Sponsors() {
+ return (
+
+
+
+

+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/web/app/_components/sponsors/logo-renderer.tsx b/apps/web/app/_components/sponsors/logo-renderer.tsx
new file mode 100644
index 00000000..7e4403e2
--- /dev/null
+++ b/apps/web/app/_components/sponsors/logo-renderer.tsx
@@ -0,0 +1,31 @@
+import GlassCard from "@/components/glassCard"
+import { Sponsor } from "@/config/sponsors"
+import { SponsorTiers } from "@/config/sponsors"
+
+interface SponsorLogoRendererProps {
+ data: Sponsor
+}
+
+const SponsorLogoRenderer = ({ data: s }: SponsorLogoRendererProps) => {
+ let h = 60
+
+ if (s.tier === SponsorTiers.diamond) {
+ h = 160
+ } else if (s.tier === SponsorTiers.platinum) {
+ h = 100
+ }
+
+ return (
+
+ {/* eslint-disable-next-line @next/next/no-img-element */}
+

+
+ )
+}
+
+export default SponsorLogoRenderer
diff --git a/apps/web/app/_components/sponsors/subgrid.tsx b/apps/web/app/_components/sponsors/subgrid.tsx
new file mode 100644
index 00000000..321e4150
--- /dev/null
+++ b/apps/web/app/_components/sponsors/subgrid.tsx
@@ -0,0 +1,35 @@
+import { Sponsor } from "@/config/sponsors"
+import { SponsorTiers } from "@/config/sponsors"
+
+import SponsorLogoRenderer from "./logo-renderer"
+
+interface SponsorSubgridProps {
+ data: Sponsor[]
+ tier: SponsorTiers
+}
+
+function getTierName(t: SponsorTiers): string {
+ return t === SponsorTiers.diamond ? "Diamond" : t === SponsorTiers.platinum ? "Platinum" : "Gold"
+}
+
+export default function SponsorSubgrid({ data, tier }: SponsorSubgridProps) {
+ const amt = data.filter((sp) => sp.tier === tier).length
+ const gridClass = amt === 1 ? "md:grid-cols-1" : amt === 2 ? "md:grid-cols-2" : "md:grid-cols-3"
+
+ if (amt === 0) return <>>
+
+ return (
+
+
+ {getTierName(tier)} Sponsor{amt > 1 ? "s" : ""}
+
+
+ {data
+ .filter((sp) => sp.tier === tier)
+ .map((sp) => (
+
+ ))}
+
+
+ )
+}
diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx
index 642d38cc..399344df 100644
--- a/apps/web/app/page.tsx
+++ b/apps/web/app/page.tsx
@@ -8,6 +8,7 @@ import Footer from "@/app/_components/footer"
import LandingSection from "@/app/_components/landing"
import { Navbar } from "@/app/_components/navbar"
import QualificationSector from "@/app/_components/qualification"
+import Sponsors from "@/app/_components/sponsors"
import Scope from "@/app/_components/scope"
import Story from "@/app/_components/story"
import Head from "next/head"
@@ -118,6 +119,9 @@ export default function Page() {
+
+
+
diff --git a/apps/web/config/sponsors.ts b/apps/web/config/sponsors.ts
new file mode 100644
index 00000000..cba00295
--- /dev/null
+++ b/apps/web/config/sponsors.ts
@@ -0,0 +1,21 @@
+export enum SponsorTiers {
+ "diamond" = 3,
+ "platinum" = 2,
+ "gold" = 1,
+}
+
+export interface Sponsor {
+ name: string
+ tier: SponsorTiers
+ image_path: string
+ link?: string
+}
+
+export const SponsorList: Sponsor[] = [
+ {
+ name: "IRE Learning",
+ tier: SponsorTiers.gold,
+ image_path: "/static/sponsors/ire-white.webp",
+ link: "https://www.facebook.com/iretutor/",
+ },
+]
diff --git a/apps/web/public/static/logo/kmutt65-cpe-white-160px.webp b/apps/web/public/static/logo/kmutt65-cpe-white-160px.webp
new file mode 100644
index 00000000..bbf8ef00
Binary files /dev/null and b/apps/web/public/static/logo/kmutt65-cpe-white-160px.webp differ
diff --git a/apps/web/public/static/sponsors/ire-white.webp b/apps/web/public/static/sponsors/ire-white.webp
new file mode 100644
index 00000000..2e6f78cb
Binary files /dev/null and b/apps/web/public/static/sponsors/ire-white.webp differ
diff --git a/apps/web/public/static/sponsors/ire.webp b/apps/web/public/static/sponsors/ire.webp
new file mode 100644
index 00000000..93f1bdf8
Binary files /dev/null and b/apps/web/public/static/sponsors/ire.webp differ
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 460b6b50..748ee977 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -13,6 +13,7 @@
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-select": "^2.2.6",
+ "@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
diff --git a/packages/ui/src/components/separator.tsx b/packages/ui/src/components/separator.tsx
new file mode 100644
index 00000000..a6485017
--- /dev/null
+++ b/packages/ui/src/components/separator.tsx
@@ -0,0 +1,27 @@
+"use client"
+
+import * as SeparatorPrimitive from "@radix-ui/react-separator"
+import { cn } from "@workspace/ui/lib/utils"
+import * as React from "react"
+
+function Separator({
+ className,
+ orientation = "horizontal",
+ decorative = true,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export { Separator }
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 40f82bf9..a17d943f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -483,6 +483,9 @@ importers:
'@radix-ui/react-select':
specifier: ^2.2.6
version: 2.2.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ '@radix-ui/react-separator':
+ specifier: ^1.1.7
+ version: 1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
'@radix-ui/react-slot':
specifier: ^1.2.3
version: 1.2.3(@types/react@19.1.10)(react@19.1.1)
@@ -8352,6 +8355,15 @@ snapshots:
'@types/react': 19.1.10
'@types/react-dom': 19.1.7(@types/react@19.1.10)
+ '@radix-ui/react-separator@1.1.7(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ react: 19.1.1
+ react-dom: 19.1.1(react@19.1.1)
+ optionalDependencies:
+ '@types/react': 19.1.10
+ '@types/react-dom': 19.1.7(@types/react@19.1.10)
+
'@radix-ui/react-slider@1.3.6(@types/react-dom@19.1.7(@types/react@19.1.10))(@types/react@19.1.10)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
dependencies:
'@radix-ui/number': 1.1.1