diff --git a/apps/rpc/src/modules/event/event-repository.ts b/apps/rpc/src/modules/event/event-repository.ts index 1edf671213..770250aa5e 100644 --- a/apps/rpc/src/modules/event/event-repository.ts +++ b/apps/rpc/src/modules/event/event-repository.ts @@ -55,6 +55,7 @@ export interface EventRepository { deleteEventHostingGroups(handle: DBHandle, eventId: EventId, hostingGroupIds: Set): Promise deleteEventCompanies(handle: DBHandle, eventId: EventId, companyIds: Set): Promise updateEventAttendance(handle: DBHandle, eventId: EventId, attendanceId: AttendanceId): Promise + count(handle: DBHandle): Promise } export function getEventRepository(): EventRepository { @@ -292,5 +293,8 @@ export function getEventRepository(): EventRepository { invariant(event !== null, "Event should exist within same transaction after updating attendance") return event }, + async count(handle) { + return await handle.event.count() + }, } } diff --git a/apps/rpc/src/modules/event/event-router.ts b/apps/rpc/src/modules/event/event-router.ts index 803c1856f9..8067638c7a 100644 --- a/apps/rpc/src/modules/event/event-router.ts +++ b/apps/rpc/src/modules/event/event-router.ts @@ -114,4 +114,9 @@ export const eventRouter = t.router({ return ctx.eventService.updateEventAttendance(handle, input.eventId, attendance.id) }) }), + count: procedure.query(async ({ ctx }) => { + return ctx.executeTransaction(async (handle) => { + return await ctx.eventService.count(handle) + }) + }), }) diff --git a/apps/rpc/src/modules/event/event-service.ts b/apps/rpc/src/modules/event/event-service.ts index 671deb1451..b0c74a3bb1 100644 --- a/apps/rpc/src/modules/event/event-service.ts +++ b/apps/rpc/src/modules/event/event-service.ts @@ -37,6 +37,7 @@ export interface EventService { */ getEventById(handle: DBHandle, eventId: EventId): Promise getByAttendance(handle: DBHandle, attendanceId: AttendanceId): Promise + count(handle: DBHandle): Promise } export function getEventService(eventRepository: EventRepository): EventService { @@ -91,5 +92,8 @@ export function getEventService(eventRepository: EventRepository): EventService const event = await this.getEventById(handle, eventId) return await eventRepository.updateEventAttendance(handle, event.id, attendanceId) }, + async count(handle) { + return await eventRepository.count(handle) + }, } } diff --git a/apps/web/public/Hovedbygget-01.jpg b/apps/web/public/Hovedbygget-01.jpg new file mode 100644 index 0000000000..29c1ca40e9 Binary files /dev/null and b/apps/web/public/Hovedbygget-01.jpg differ diff --git a/apps/web/public/OnlineStruktur.png b/apps/web/public/OnlineStruktur.png new file mode 100644 index 0000000000..450ece8aed Binary files /dev/null and b/apps/web/public/OnlineStruktur.png differ diff --git a/apps/web/src/app/om-linjeforeningen/components/OurGoals.tsx b/apps/web/src/app/om-linjeforeningen/components/OurGoals.tsx new file mode 100644 index 0000000000..33edf18d70 --- /dev/null +++ b/apps/web/src/app/om-linjeforeningen/components/OurGoals.tsx @@ -0,0 +1,18 @@ +import { Divider, ImageCard, Text, Title } from "@dotkomonline/ui" + +export const OurGoalsCard = () => { + return ( + +
+ + Vårt Mål + + + + Online skal arbeide for å skape sterkere bånd mellom medlemmer på ulike årstrinn og være kontaktledd mellom + medlemmene og eksterne aktører. + +
+
+ ) +} diff --git a/apps/web/src/app/om-linjeforeningen/components/Statistics.tsx b/apps/web/src/app/om-linjeforeningen/components/Statistics.tsx new file mode 100644 index 0000000000..cf3ef9243e --- /dev/null +++ b/apps/web/src/app/om-linjeforeningen/components/Statistics.tsx @@ -0,0 +1,38 @@ +import { Text } from "@dotkomonline/ui" + +export const Statistics = async () => { + const memberCount = roundToLowestN(600, 50) // This could be fetched from the server, but stays relatively constant + const hobbyGroups = roundToLowestN(30, 5) // This could also be fetched from the server, but does not change as often + const eventCount = roundToLowestN(2500, 50) // Fetching the event count from the server + + const StatisticsNumber = ({ number, title }: { number: number; title: string }) => { + return ( +
+ {number}+ + {title} +
+ ) + } + return ( + <> + + Linjeforeningen startet som en liten gruppe studenter høsten 1985, og har siden den gang vokst til å bli en av + NTNU's større linjeforeninger innen teknologi, med over {memberCount} medlemmer. Foreningen drives av et stort + antall frivillige som legger ned betydelig innsats for å skape et variert og engasjerende tilbud for medlemmene. + Gjennom årene har Online arrangert mer enn {eventCount} aktiviteter inkludert faglige kurs, + bedriftspresentasjoner og sosiale sammenkomster, som til sammen bidrar til å styrke både det faglige og det + sosiale fellesskapet. Denne kombinasjonen av profesjonelle arrangementer og sosiale møteplasser har gjort Online + til en sentral arena for kompetanseutvikling, nettverksbygging og trivsel blant medlemmene. + +
+ + + +
+ + ) +} + +const roundToLowestN = (num: number, n: number) => { + return Math.floor(num / n) * n +} diff --git a/apps/web/src/app/om-linjeforeningen/components/Structure.tsx b/apps/web/src/app/om-linjeforeningen/components/Structure.tsx new file mode 100644 index 0000000000..133a9047d9 --- /dev/null +++ b/apps/web/src/app/om-linjeforeningen/components/Structure.tsx @@ -0,0 +1,43 @@ +import { Text, Title } from "@dotkomonline/ui" +import Image from "next/image" +import Link from "next/link" + +export const Structure = () => { + return ( +
+ + Struktur + +
+ + Generalforsamlingen utgjør den øverste besluttende myndighet i Online, og kan sammenlignes med et + stortingsvalg for en ny regjering. Mellom generalforsamlingene ivaretas den daglige driften av linjeforeningen + av hovedstyret og komiteene. Disse komiteene har spesifikke ansvarsområder, som spenner fra sosiale + arrangementer til faglige kurs. Dette gir medlemmene muligheten til å engasjere seg i sine interessefelt, + samtidig som det sikrer at foreningen kan tilby et variert spekter av aktiviteter og tjenester. + + + Online har også tilknytning til flere andre grupper og organisasjoner som bidrar til å styrke miljøet rundt + linjeforeningen. Disse samarbeidene kan være både sosiale og organisatoriske, og gir medlemmene flere + muligheter for nettverksbygging, kompetanseutvikling og deltakelse i ulike arrangementer. + + + Ønsker du å vite mer om hvordan Online er organisert og hvilke grupper vi samarbeider med, kan du lese mer på{" "} + + Online Wiki + + + <> + Online Organizational Structure map + Online Organisasjonskart + +
+
+ ) +} diff --git a/apps/web/src/app/om-linjeforeningen/components/WhoAreWeCard.tsx b/apps/web/src/app/om-linjeforeningen/components/WhoAreWeCard.tsx new file mode 100644 index 0000000000..9c7c1cbe97 --- /dev/null +++ b/apps/web/src/app/om-linjeforeningen/components/WhoAreWeCard.tsx @@ -0,0 +1,18 @@ +import { Divider, ImageCard, Text, Title } from "@dotkomonline/ui" + +export const WhoAreWeCard = () => { + return ( + +
+ + Hvem er vi? + + + + Online er linjeforeningen for informatikkstudenter ved NTNU i Trondheim. Linjeforeningens oppgave er å + forbedre studiemiljøet ved å fremme sosialt samvær, faglig kompetanse og kontakt med næringslivet. + +
+
+ ) +} diff --git a/apps/web/src/app/om-linjeforeningen/page.tsx b/apps/web/src/app/om-linjeforeningen/page.tsx index 70e8a0bae1..074068d8f2 100644 --- a/apps/web/src/app/om-linjeforeningen/page.tsx +++ b/apps/web/src/app/om-linjeforeningen/page.tsx @@ -1,127 +1,15 @@ -import { OnlineIcon } from "@/components/atoms/OnlineIcon" -import { server } from "@/utils/trpc/server" -import type { Group } from "@dotkomonline/types" -import { Text, Title } from "@dotkomonline/ui" -import Image from "next/image" -import Link from "next/link" -import type { FC } from "react" +import { OurGoalsCard } from "./components/OurGoals" +import { Statistics } from "./components/Statistics" +import { Structure } from "./components/Structure" +import { WhoAreWeCard } from "./components/WhoAreWeCard" export default async function AboutOnlinePage() { - const nodeCommittees = await server.group.allByType.query("NODE_COMMITTEE") - const committees = await server.group.allByType.query("COMMITTEE") - return ( -
-
- - Bli kjent med{" "} - <span className="relative inline-block"> - Online linjeforening - <span className="absolute left-0 -bottom-6 h-4 w-full bg-blue-600 dark:bg-blue-700 rounded-2xl" /> - </span> - - - Nysjerrig på hva de ulike delene av Online egentlig er? -
- Har du noen gang lurt på hvordan alt henger sammen? -
- Her får du et innblikk til linjeforeningens struktur - komiteer, grupper og hovedstyret! -
-
-
- - Generalforsamlingen - - -
-
- Genfors banner -
-
- - - Generalforsamlingen - {" "} - er den høyeste besluttende myndighet i Online. - - - Det betyr at den største beslutningsevnen ligger i hendene på alle våre kjære Onlinere. - -
-
-
-
- - Komiteer - - - Foreningen har et bredt spekter av komiteer som tar for seg alt fra det sosiale til det faglige. Her er en - oversikt over noen av komiteene som bidrar til å skape et levende studentmiljø for informatikkstudentene: - - -
-
- - Nodekomiteer - - - Nodekomiteer er underkomiteer til kjernekomiteene i Online, eller direkte underlagt Hovedstyret. - - -
+
+ + + +
) } - -type GroupListProps = { - groups: Group[] -} - -const GroupList: FC = ({ groups }: GroupListProps) => { - return ( -
    - {groups.map( - (group) => - group.imageUrl && ( - - ) - )} -
- ) -} - -type CardProps = { - imageUrl: string | null - title: string - description: string -} - -const Card: FC = ({ imageUrl, title, description }: CardProps) => { - return ( -
  • -
    - {imageUrl ? ( - {title} - ) : ( - - )} -
    -
    - {title} - {description} -
    -
  • - ) -} diff --git a/packages/ui/src/atoms/Divider/Divider.tsx b/packages/ui/src/atoms/Divider/Divider.tsx new file mode 100644 index 0000000000..2caa241e38 --- /dev/null +++ b/packages/ui/src/atoms/Divider/Divider.tsx @@ -0,0 +1,21 @@ +import type React from "react" +import { forwardRef } from "react" +import { cn } from "../../utils" + +interface DividerProps extends React.HTMLAttributes { + vertical?: boolean +} + +export const Divider = forwardRef(({ vertical, ...props }, ref) => { + return ( +
    + ) +}) diff --git a/packages/ui/src/atoms/ImageCard/ImageCard.tsx b/packages/ui/src/atoms/ImageCard/ImageCard.tsx new file mode 100644 index 0000000000..0f90ac4459 --- /dev/null +++ b/packages/ui/src/atoms/ImageCard/ImageCard.tsx @@ -0,0 +1,45 @@ +import { forwardRef } from "react" +import { cn } from "../../utils" + +interface ImageCardProps extends React.HTMLAttributes { + imagePosition: "left" | "right" | "top" + image: string + alt: string + children?: React.ReactNode +} +export const ImageCard = forwardRef( + ({ image, imagePosition, alt, children, ...props }, ref) => { + return ( +
    + {alt} +
    {children}
    + {imagePosition === "right" && ( + {alt} + )} +
    + ) + } +) diff --git a/packages/ui/src/atoms/Typography/Title.tsx b/packages/ui/src/atoms/Typography/Title.tsx index d2016ad62a..c52f5f3ceb 100644 --- a/packages/ui/src/atoms/Typography/Title.tsx +++ b/packages/ui/src/atoms/Typography/Title.tsx @@ -30,6 +30,8 @@ const title = cva("text-inherit font-title font-bold", { md: "text-xl font-semibold", lg: "text-2xl font-semibold", xl: "text-3xl", + xxl: "text-4xl", + xxxl: "text-5xl", }, }, defaultVariants: { diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 986ba48abb..7c1d4b5bde 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -1,35 +1,36 @@ +export * from "./atoms/Avatar/Avatar" export * from "./atoms/Badge/Badge" export * from "./atoms/Button/Button" export * from "./atoms/Checkbox/Checkbox" -export * from "./atoms/Textarea/Textarea" -export * from "./atoms/Toggle/Toggle" -export * from "./atoms/Input/TextInput" -export * from "./atoms/Label/Label" -export * from "./atoms/Icon/Icon" -export * from "./atoms/Avatar/Avatar" export * from "./atoms/Circle/Circle" -export * from "./atoms/Typography/Title" -export * from "./atoms/Typography/Text" -export * from "./atoms/Select/Select" -export * from "./atoms/Tooltip/Tooltip" export * from "./atoms/Collapsible/Collapsible" +export * from "./atoms/Divider/Divider" +export * from "./atoms/Icon/Icon" +export * from "./atoms/ImageCard/ImageCard" +export * from "./atoms/Input/TextInput" +export * from "./atoms/Label/Label" export * from "./atoms/Popover/Popover" export * from "./atoms/RadioGroup/RadioGroup" -export * from "./atoms/Video/Video" +export * from "./atoms/Select/Select" +export * from "./atoms/Textarea/Textarea" export * from "./atoms/Tilt/Tilt" +export * from "./atoms/Toggle/Toggle" +export * from "./atoms/Tooltip/Tooltip" +export * from "./atoms/Typography/Text" +export * from "./atoms/Typography/Title" +export * from "./atoms/Video/Video" export * from "./molecules/Accordion/Accordion" export * from "./molecules/Alert/Alert" export * from "./molecules/Alert/AlertIcon" -export * from "./molecules/HoverCard/HoverCard" -export * from "./molecules/Tabs/Tabs" -export * from "./molecules/Table/Table" -export * from "./molecules/DropdownMenu/DropdownMenu" -export * from "./molecules/Accordion/Accordion" -export * from "./molecules/Dialog/Dialog" export * from "./molecules/Card/Card" +export * from "./molecules/Dialog/Dialog" +export * from "./molecules/DropdownMenu/DropdownMenu" +export * from "./molecules/HoverCard/HoverCard" +export * from "./molecules/Progress/RadialProgress" export * from "./molecules/ReadMore/ReadMore" export * from "./molecules/RichText/RichText" -export * from "./molecules/Progress/RadialProgress" +export * from "./molecules/Table/Table" +export * from "./molecules/Tabs/Tabs" export * from "./utils"