Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/api/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { type To, href } from "react-router";

interface Metric {
number: number;
title: string;
description: string;
link: {
path: To;
text: string;
};
}

export function getMetrics(): Array<Metric> {
return [
{
number: 2218,
title: "Assistenter",
description:
"Over 2218 studenter har hatt et verv som vektorassistent i Vektorprogrammet",
link: {
path: href("/assistenter"),
text: "Les mer om assistenter",
},
},
{
number: 608,
title: "I team",
description:
"Over 608 studenter har hatt et verv i et av Vektorprogrammets mange team",
link: {
path: href("/team"),
text: "Les mer om verv i team",
},
},
];
}
55 changes: 48 additions & 7 deletions src/api/sponsor.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,70 @@
import Abelprisen from "/images/mainPage/sponsor/Abelprisen.png";
import ksBergen from "/images/mainPage/sponsor/KSBergen.png";
import Matematikksenteret from "/images/mainPage/sponsor/Matematikksenteret.png";
import NTNUIE from "/images/mainPage/sponsor/NTNUIE.png";
import NTNUIV from "/images/mainPage/sponsor/NTNUIV.png";
import Samarbeidsforum from "/images/mainPage/sponsor/SamarbeidsForum.png";
import sparebankstiftelsenDnb from "/images/mainPage/sponsor/SparebankstiftelsenDNB.png";
import Tekna from "/images/mainPage/sponsor/Tekna.png";
import UiB from "/images/mainPage/sponsor/UIB.png";
import VisionTech from "/images/mainPage/sponsor/VisionTech.png";

export interface Sponsor {
name: string;
url: URL;
image?: string;
}

export function getMainSponsors(): Array<Sponsor> {
return [
{
name: "Abelprisen",
url: new URL("https://www.abelprisen.no/"),
image: Abelprisen,
},
{
name: "Sparebankstiftelsen DNB",
url: new URL("https://www.sparebankstiftelsendnb.no/"),
image: sparebankstiftelsenDnb,
},
];
}

// TODO: This data should be fetched from backend later
export function getSponsors(): Array<Sponsor> {
return [
{ name: "Tekna", url: new URL("https://www.tekna.no/") },
{ name: "Tekna", url: new URL("https://www.tekna.no/"), image: Tekna },
{
name: "Nasjonalt senter for realfagsrekruttering",
url: new URL("https://www.realfagsrekruttering.no/"),
image: Matematikksenteret,
},
{ name: "NTNU IV", url: new URL("https://www.ntnu.no/iv") },
{ name: "NTNU IE", url: new URL("https://www.ntnu.no/ie") },
{ name: "NTNU IV", url: new URL("https://www.ntnu.no/iv"), image: NTNUIV },
{ name: "NTNU IE", url: new URL("https://www.ntnu.no/ie"), image: NTNUIE },
{ name: "NTNU IMF", url: new URL("https://www.ntnu.no/imf") },
{ name: "Samarbeidsforum", url: new URL("https://www.ntnu.no/nv/sf") },
{ name: "Abelprisen", url: new URL("https://www.abelprisen.no/") },
{ name: "VisionTech", url: new URL("https://www.visiontech.no/") },
{
name: "Samarbeidsforum",
url: new URL("https://www.ntnu.no/nv/sf"),
image: Samarbeidsforum,
},
{
name: "VisionTech",
url: new URL("https://www.visiontech.no/"),
image: VisionTech,
},
{
name: "Kulturstyret i Bergen",
url: new URL("https://www.vtvest.no/kulturstyret/"),
image: ksBergen,
},
{
name: "MN-faktultetet ved UiB",
url: new URL("https://www.uib.no/matnat"),
image: UiB,
},
];
}

// TODO: This data should be fetched from backend later
export function getAllSponsors(): Array<Sponsor> {
return [...getMainSponsors(), ...getSponsors()];
}
19 changes: 19 additions & 0 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";

/**
* Merge and deduplicate Tailwind classes without style conflicts
*
* @param inputs - Class names to merge
* @returns A string of class names, merged and deduplicated
*/
export function cn(...inputs: Array<ClassValue>) {
return twMerge(clsx(inputs));
}

/**
* Size breakpoints in pixels based on Tailwind CSS defaults.
*
* https://tailwindcss.com/docs/responsive-design
*/
export const breakpointPixels = {
sm: 640,
md: 768,
lg: 1024,
xl: 1280,
"2xl": 1536,
} as const;
198 changes: 59 additions & 139 deletions src/routes/_home._index.tsx
Original file line number Diff line number Diff line change
@@ -1,134 +1,56 @@
import { buttonVariants } from "@/components/ui/button";
import { useInView, useMotionValue, useSpring } from "motion/react";
import { useEffect, useRef } from "react";
import { Link, type To, href } from "react-router";
import { Fragment, useEffect, useRef } from "react";
import { Link } from "react-router";
import { getMetrics } from "~/api/main";
import { getMainSponsors, getSponsors } from "~/api/sponsor";
import { Button } from "~/components/ui/button";
import Abelprisen from "/images/mainPage/sponsor/Abelprisen.png";
import ksBergen from "/images/mainPage/sponsor/KSBergen.png";
import Matematikksenteret from "/images/mainPage/sponsor/Matematikksenteret.png";
import NTNUIE from "/images/mainPage/sponsor/NTNUIE.png";
import NTNUIV from "/images/mainPage/sponsor/NTNUIV.png";
import Samarbeidsforum from "/images/mainPage/sponsor/SamarbeidsForum.png";
import sparebankstiftelsenDnb from "/images/mainPage/sponsor/SparebankstiftelsenDNB.png";
import Tekna from "/images/mainPage/sponsor/Tekna.png";
import UiB from "/images/mainPage/sponsor/UIB.png";
import VisionTech from "/images/mainPage/sponsor/VisionTech.png";
import { cn } from "~/lib/utils";
import vektorForsidebilde from "/images/mainPage/vektor-forsidebilde.png";
import vektorLogo from "/images/vektor-logo.svg";

const hovedsponsor = [
{
name: "Abelprisen",
image: Abelprisen,
},
{
name: "Sparebankstiftelsen DNB",
image: sparebankstiftelsenDnb,
},
];

const sponsorer = [
{
name: "Tekna",
image: Tekna,
},
{
name: "NTNU - Fakultet for ingeniørvitenskap",
image: NTNUIV,
},
{
name: "NTNU - Fakultet for informasjonsteknologi og elektronikk",
image: NTNUIE,
},
{
name: "Samarbeidsforum",
image: Samarbeidsforum,
},
{
name: "Universitetet i Bergen - Det matematisk-naturvitenskapelige fakultet",
image: UiB,
},
{
name: "Matematikksenteret",
image: Matematikksenteret,
},
{
name: "VisionTech",
image: VisionTech,
},
{
name: "Kulturstyret Bergen",
image: ksBergen,
},
];
interface MainPageProps {
number: number;
title: string;
text: string;
route: {
path: To;
text: string;
};
}

const cards: Array<MainPageProps> = [
{
number: 2218,
title: "Assistenter",
text: "Over 2218 studenter har hatt et verv som vektorassistent i Vektorprogrammet",
route: {
path: href("/assistenter"),
text: "Les mer om assistenter",
},
},
{
number: 608,
title: "I team",
text: "Over 608 studenter har hatt et verv i et av Vektorprogrammets mange team",
route: {
path: href("/team"),
text: "Les mer om verv i team",
},
},
];

// biome-ignore lint/style/noDefaultExport: Route Modules require default export https://reactrouter.com/start/framework/route-module
export default function mainPage() {
export default function MainPage() {
const mainSponsors = getMainSponsors();
const sponsors = getSponsors();
const metrics = getMetrics();

return (
<main className="flex-grow">
{/* Use component when the rendered component needs no props */}
{/* Getting the routes from the defined route file in pages */}
<div className="bg-vektor-index-blue md:flex md:h-[80vh] md:pt-14">
{/*Upper start*/}
<div className="flex w-full flex-col items-center text-center md:h-[26rem] md:w-1/2 md:p-8 lg:h-[31rem] xl:h-[35rem]">
<img
className="w-2/4 pt-12 pb-14 md:hidden"
src={vektorLogo}
alt="Vektorprogrammet"
/>
<img
className="mx-auto my-auto h-full w-full p-5 pt-14 md:mr-0 md:ml-auto md:w-auto md:pt-0"
src={vektorForsidebilde}
alt="Vektorprogrammet bildet"
/>
</div>
<div className="w-full p-6 text-center md:mt-24 md:mr-auto md:w-1/2 md:p-10 md:text-left">
<h1 className="mb-4 hidden font-bold text-4xl md:block dark:text-text-dark">
{"Vektorprogrammet"}
</h1>
<div className="mt-6 mb-4 flex justify-center md:block">
<p className="text-left text-md md:w-4/5 md:text-xl dark:text-text-dark">
{`- sender studenter til ungdomsskoler for å hjelpe til som lærerens
<main
className={cn(
// Depends on parent layout
"col-span-full",
)}
>
<header className="grid grid-cols-1 place-items-center gap-14 bg-vektor-index-blue pt-14 md:grid-cols-2 md:flex-row">
<img
className="w-2/4 max-w-prose md:hidden"
src={vektorLogo}
alt={"Logo til Vektorprogrammet"}
/>
<img
className="size-full max-w-prose object-contain"
src={vektorForsidebilde}
width={801}
height={765}
alt="Illustrasjon av assistenter fra Vektorprogrammet foran en tavle med matteformler"
/>
<div className="flex flex-col items-center gap-4 text-center md:items-start md:text-left">
<h1 className="text-wrap font-bold text-4xl">{"Vektorprogrammet"}</h1>
<p className="text-balance text-md">
{`- sender studenter til ungdomsskoler for å hjelpe til som lærerens
assistent i matematikkundervisningen`}
</p>
</div>
<Button variant="green">{"Les mer og bli assistent"}</Button>
</p>
<Button variant="green" className="max-w-fit">
{"Les mer og bli assistent"}
</Button>
</div>
</div>
</header>

{/*Upper end*/}
<div className="info-background mb-0 flex max-w-full flex-row flex-wrap items-center justify-center gap-24 pt-72 pb-72 text-center md:mt-20 md:gap-40">
{/*Middle start*/}
{cards.map(({ number, title, text, route }) => (
{metrics.map(({ number, title, description, link }) => (
<div
key={title}
className="flex max-w-96 flex-col gap-5 text-vektor-bg"
Expand All @@ -139,14 +61,16 @@ export default function mainPage() {
</div>
<p className="text-xl md:text-2xl">{title}</p>
</div>
<p className="max-w-80 text-sm md:max-w-96 md:text-xl">{text}</p>
<p className="max-w-80 text-sm md:max-w-96 md:text-xl">
{description}
</p>
<div>
<Link
to={route.path}
to={link.path}
className={buttonVariants({ variant: "green" })}
prefetch="intent"
>
{route.text}
{link.text}
</Link>
</div>
</div>
Expand All @@ -156,31 +80,27 @@ export default function mainPage() {
<div className="flex justify-center">
<div className="flex max-w-4xl flex-col md:gap-32">
<div className="flex flex-row flex-wrap justify-around md:justify-between">
{hovedsponsor.map((sponsor) => (
{mainSponsors.map(({ name, image }) => (
<div
className="flex h-72 w-72 items-center md:h-96 md:w-96"
key={sponsor.name}
key={name}
>
<img
className="h-auto w-auto"
src={sponsor.image}
alt={sponsor.name}
/>
<img className="h-auto w-auto" src={image} alt={name} />
</div>
))}
</div>
<div className="flex flex-row flex-wrap justify-around md:justify-between">
{sponsorer.map((sponsor) => (
<div
className="flex h-36 w-36 items-center md:h-64 md:w-64"
key={sponsor.name}
>
<img
className="h-auto w-auto"
src={sponsor.image}
alt={sponsor.name}
/>
</div>
{sponsors.map(({ name, image }) => (
<Fragment key={name}>
{image && (
<div
className="flex h-36 w-36 items-center md:h-64 md:w-64"
key={name}
>
<img className="h-auto w-auto" src={image} alt={name} />
</div>
)}
</Fragment>
))}
</div>
</div>
Expand Down
Loading