From 99dfc4ec00444e4881cdea0a4561a5adaf7b63a7 Mon Sep 17 00:00:00 2001 From: Erik Sevelin <91209290+SortHvit@users.noreply.github.com> Date: Mon, 9 Sep 2024 18:18:09 +0200 Subject: [PATCH] add margin to member graphic. add informing text --- .../_components/OrganisationMemberInfo.tsx | 14 + .../OrganisationMembersGraphic.tsx | 454 +++++++++--------- src/app/about/page.tsx | 35 ++ 3 files changed, 276 insertions(+), 227 deletions(-) create mode 100644 src/app/_components/OrganisationMemberInfo.tsx diff --git a/src/app/_components/OrganisationMemberInfo.tsx b/src/app/_components/OrganisationMemberInfo.tsx new file mode 100644 index 0000000..6f1812d --- /dev/null +++ b/src/app/_components/OrganisationMemberInfo.tsx @@ -0,0 +1,14 @@ +export function OrganisationMembersInfo({ + children, + title +}: { + children?: React.ReactNode + title: string +}) { + return ( +
+

{title}

+

{children}

+
+ ) +} diff --git a/src/app/_components/OrganisationMembersGraphic.tsx b/src/app/_components/OrganisationMembersGraphic.tsx index 08fd812..e35313f 100644 --- a/src/app/_components/OrganisationMembersGraphic.tsx +++ b/src/app/_components/OrganisationMembersGraphic.tsx @@ -8,231 +8,231 @@ amount of layers change dynamically */ export function OrganisationMembersGraphic() { - const memberRadius = 4 - const layerRadius = 10 - const updateSpeed = 50 //animation speed in milliseconds - const PgCircleList = (people: number) => { - const [theta, setTheta] = useState(0) - - let pi_division = 0 - let pi_division2 = 0 - let pg_circles = [] - let pg_layer1 = Math.floor(Math.PI / Math.asin(memberRadius / layerRadius)) //amount of circles of radius [memberRadius] that can fit on the circle making up a layer - - //divide pi by people, if divided num too small -> add second layer - if (people > pg_layer1) { - pi_division = (2 * Math.PI) / pg_layer1 - pi_division2 = (2 * Math.PI) / (people - pg_layer1) - } else { - pi_division = (2 * Math.PI) / people - } - //setting up layers - for (let i = 0; i < Math.min(people, pg_layer1); i++) { - pg_circles.push({ - name: i, - cx: 85 + layerRadius * Math.sin(i * pi_division + theta), - cy: 85 + layerRadius * Math.cos(i * pi_division + theta), - r: memberRadius - }) - } - for (let i = pg_layer1; i < people; i++) { - pg_circles.push({ - name: i, - cx: 85 + 2 * layerRadius * Math.sin(i * pi_division2 - theta), - cy: 85 + 2 * layerRadius * Math.cos(i * pi_division2 - theta), - r: memberRadius - }) - } - //animating the circles - useEffect(() => { - const updateTheta = () => { - setTheta(prevTheta => (prevTheta + 0.002) % (2 * Math.PI)) - } - - const interval = setInterval(updateTheta, updateSpeed) - - return () => clearInterval(interval) - }, []) - - return pg_circles - } - - const OtCircleList = (people: number) => { - const [theta, setTheta] = useState(0) - - let pi_division = 0 - let pi_division2 = 0 - let pi_division3 = 0 - let ot_circles = [] - //amount of circles of radius [memberRadius] that can fit on the circle making up a layer - let ot_layer1 = Math.floor( - Math.PI / Math.asin(memberRadius / (3 * layerRadius)) - ) - let ot_layer2 = Math.floor( - Math.PI / Math.asin(memberRadius / (4 * layerRadius)) - ) - - //divide pi by people, if divided num too small -> add layers - if (people > ot_layer1 + ot_layer2) { - pi_division = (2 * Math.PI) / ot_layer1 - pi_division2 = (2 * Math.PI) / ot_layer2 - pi_division3 = (2 * Math.PI) / (people - ot_layer1 - ot_layer2) - } else if (people > ot_layer1) { - pi_division = (2 * Math.PI) / ot_layer1 - pi_division2 = (2 * Math.PI) / (people - ot_layer1) - } else { - pi_division = (2 * Math.PI) / people - } - - //setting up layers - for (let i = 0; i < Math.min(people, ot_layer1); i++) { - ot_circles.push({ - name: i, - cx: 85 + 3 * layerRadius * Math.sin(i * pi_division + theta), - cy: 85 + 3 * layerRadius * Math.cos(i * pi_division + theta), - r: memberRadius - }) - } - for (let i = ot_layer1; i < ot_layer1 + ot_layer2; i++) { - ot_circles.push({ - name: i, - cx: 85 + 4 * layerRadius * Math.sin(i * pi_division2 - theta), - cy: 85 + 4 * layerRadius * Math.cos(i * pi_division2 - theta), - r: memberRadius - }) - } - for (let i = ot_layer1 + ot_layer2; i < people; i++) { - ot_circles.push({ - name: i, - cx: 85 + 5 * layerRadius * Math.sin(i * pi_division3 + theta), - cy: 85 + 5 * layerRadius * Math.cos(i * pi_division3 + theta), - r: memberRadius - }) - } - //animating the circles - useEffect(() => { - const updateTheta = () => { - setTheta(prevTheta => (prevTheta + 0.0015) % (2 * Math.PI)) - } - - const interval = setInterval(updateTheta, updateSpeed) - - return () => clearInterval(interval) - }, []) - - return ot_circles - } - - const HostCircleList = (people: number) => { - const [theta, setTheta] = useState(0) - - let pi_division = 0 - let pi_division2 = 0 - let pi_division3 = 0 - let host_circles = [] - //amount of circles of radius [memberRadius] that can fit on the circle making up a layer - let host_layer1 = Math.floor( - Math.PI / Math.asin(memberRadius / (6 * layerRadius)) - ) - let host_layer2 = Math.floor( - Math.PI / Math.asin(memberRadius / (7 * layerRadius)) - ) - - //divide pi by people, if divided num too small -> add layers - if (people > host_layer1 + host_layer2) { - pi_division = (2 * Math.PI) / host_layer1 - pi_division2 = (2 * Math.PI) / host_layer2 - pi_division3 = (2 * Math.PI) / (people - host_layer1 - host_layer2) - } else if (people > host_layer1) { - pi_division = (2 * Math.PI) / host_layer1 - pi_division2 = (2 * Math.PI) / (people - host_layer1) - } else { - pi_division = (2 * Math.PI) / people - } - - //setting up layers - for (let i = 0; i < Math.min(people, host_layer1); i++) { - host_circles.push({ - name: i, - cx: 85 + 6 * layerRadius * Math.sin(i * pi_division - theta), - cy: 85 + 6 * layerRadius * Math.cos(i * pi_division - theta), - r: memberRadius - }) - } - for (let i = host_layer1; i < host_layer1 + host_layer2; i++) { - host_circles.push({ - name: i, - cx: 85 + 7 * layerRadius * Math.sin(i * pi_division2 + theta), - cy: 85 + 7 * layerRadius * Math.cos(i * pi_division2 + theta), - r: memberRadius - }) - } - for (let i = host_layer1 + host_layer2; i < people; i++) { - host_circles.push({ - name: i, - cx: 85 + 8 * layerRadius * Math.sin(i * pi_division3 - theta), - cy: 85 + 8 * layerRadius * Math.cos(i * pi_division3 - theta), - r: memberRadius - }) - } - //animating the circles - useEffect(() => { - const updateTheta = () => { - setTheta(prevTheta => (prevTheta + 0.001) % (2 * Math.PI)) - } - - const interval = setInterval(updateTheta, updateSpeed) - - return () => clearInterval(interval) - }, []) - - return host_circles - } - - const pgCircles = PgCircleList(20).map(circle => { - return ( - - ) - }) - - const otCircles = OtCircleList(80).map(circle => { - return ( - - ) - }) - - const hostCircles = HostCircleList(120).map(circle => { - return ( - - ) - }) - - return ( - <> - - - {pgCircles} - {otCircles} - {hostCircles} - - - ) + const memberRadius = 4 + const layerRadius = 10 + const updateSpeed = 50 //animation speed in milliseconds + const PgCircleList = (people: number) => { + const [theta, setTheta] = useState(0) + + let pi_division = 0 + let pi_division2 = 0 + let pg_circles = [] + let pg_layer1 = Math.floor(Math.PI / Math.asin(memberRadius / layerRadius)) //amount of circles of radius [memberRadius] that can fit on the circle making up a layer + + //divide pi by people, if divided num too small -> add second layer + if (people > pg_layer1) { + pi_division = (2 * Math.PI) / pg_layer1 + pi_division2 = (2 * Math.PI) / (people - pg_layer1) + } else { + pi_division = (2 * Math.PI) / people + } + //setting up layers + for (let i = 0; i < Math.min(people, pg_layer1); i++) { + pg_circles.push({ + name: i, + cx: 85 + layerRadius * Math.sin(i * pi_division + theta), + cy: 85 + layerRadius * Math.cos(i * pi_division + theta), + r: memberRadius + }) + } + for (let i = pg_layer1; i < people; i++) { + pg_circles.push({ + name: i, + cx: 85 + 2 * layerRadius * Math.sin(i * pi_division2 - theta), + cy: 85 + 2 * layerRadius * Math.cos(i * pi_division2 - theta), + r: memberRadius + }) + } + //animating the circles + useEffect(() => { + const updateTheta = () => { + setTheta(prevTheta => (prevTheta + 0.002) % (2 * Math.PI)) + } + + const interval = setInterval(updateTheta, updateSpeed) + + return () => clearInterval(interval) + }, []) + + return pg_circles + } + + const OtCircleList = (people: number) => { + const [theta, setTheta] = useState(0) + + let pi_division = 0 + let pi_division2 = 0 + let pi_division3 = 0 + let ot_circles = [] + //amount of circles of radius [memberRadius] that can fit on the circle making up a layer + let ot_layer1 = Math.floor( + Math.PI / Math.asin(memberRadius / (3 * layerRadius)) + ) + let ot_layer2 = Math.floor( + Math.PI / Math.asin(memberRadius / (4 * layerRadius)) + ) + + //divide pi by people, if divided num too small -> add layers + if (people > ot_layer1 + ot_layer2) { + pi_division = (2 * Math.PI) / ot_layer1 + pi_division2 = (2 * Math.PI) / ot_layer2 + pi_division3 = (2 * Math.PI) / (people - ot_layer1 - ot_layer2) + } else if (people > ot_layer1) { + pi_division = (2 * Math.PI) / ot_layer1 + pi_division2 = (2 * Math.PI) / (people - ot_layer1) + } else { + pi_division = (2 * Math.PI) / people + } + + //setting up layers + for (let i = 0; i < Math.min(people, ot_layer1); i++) { + ot_circles.push({ + name: i, + cx: 85 + 3 * layerRadius * Math.sin(i * pi_division + theta), + cy: 85 + 3 * layerRadius * Math.cos(i * pi_division + theta), + r: memberRadius + }) + } + for (let i = ot_layer1; i < ot_layer1 + ot_layer2; i++) { + ot_circles.push({ + name: i, + cx: 85 + 4 * layerRadius * Math.sin(i * pi_division2 - theta), + cy: 85 + 4 * layerRadius * Math.cos(i * pi_division2 - theta), + r: memberRadius + }) + } + for (let i = ot_layer1 + ot_layer2; i < people; i++) { + ot_circles.push({ + name: i, + cx: 85 + 5 * layerRadius * Math.sin(i * pi_division3 + theta), + cy: 85 + 5 * layerRadius * Math.cos(i * pi_division3 + theta), + r: memberRadius + }) + } + //animating the circles + useEffect(() => { + const updateTheta = () => { + setTheta(prevTheta => (prevTheta + 0.0015) % (2 * Math.PI)) + } + + const interval = setInterval(updateTheta, updateSpeed) + + return () => clearInterval(interval) + }, []) + + return ot_circles + } + + const HostCircleList = (people: number) => { + const [theta, setTheta] = useState(0) + + let pi_division = 0 + let pi_division2 = 0 + let pi_division3 = 0 + let host_circles = [] + //amount of circles of radius [memberRadius] that can fit on the circle making up a layer + let host_layer1 = Math.floor( + Math.PI / Math.asin(memberRadius / (6 * layerRadius)) + ) + let host_layer2 = Math.floor( + Math.PI / Math.asin(memberRadius / (7 * layerRadius)) + ) + + //divide pi by people, if divided num too small -> add layers + if (people > host_layer1 + host_layer2) { + pi_division = (2 * Math.PI) / host_layer1 + pi_division2 = (2 * Math.PI) / host_layer2 + pi_division3 = (2 * Math.PI) / (people - host_layer1 - host_layer2) + } else if (people > host_layer1) { + pi_division = (2 * Math.PI) / host_layer1 + pi_division2 = (2 * Math.PI) / (people - host_layer1) + } else { + pi_division = (2 * Math.PI) / people + } + + //setting up layers + for (let i = 0; i < Math.min(people, host_layer1); i++) { + host_circles.push({ + name: i, + cx: 85 + 6 * layerRadius * Math.sin(i * pi_division - theta), + cy: 85 + 6 * layerRadius * Math.cos(i * pi_division - theta), + r: memberRadius + }) + } + for (let i = host_layer1; i < host_layer1 + host_layer2; i++) { + host_circles.push({ + name: i, + cx: 85 + 7 * layerRadius * Math.sin(i * pi_division2 + theta), + cy: 85 + 7 * layerRadius * Math.cos(i * pi_division2 + theta), + r: memberRadius + }) + } + for (let i = host_layer1 + host_layer2; i < people; i++) { + host_circles.push({ + name: i, + cx: 85 + 8 * layerRadius * Math.sin(i * pi_division3 - theta), + cy: 85 + 8 * layerRadius * Math.cos(i * pi_division3 - theta), + r: memberRadius + }) + } + //animating the circles + useEffect(() => { + const updateTheta = () => { + setTheta(prevTheta => (prevTheta + 0.001) % (2 * Math.PI)) + } + + const interval = setInterval(updateTheta, updateSpeed) + + return () => clearInterval(interval) + }, []) + + return host_circles + } + + const pgCircles = PgCircleList(20).map(circle => { + return ( + + ) + }) + + const otCircles = OtCircleList(80).map(circle => { + return ( + + ) + }) + + const hostCircles = HostCircleList(120).map(circle => { + return ( + + ) + }) + + return ( +
+ + + {pgCircles} + {otCircles} + {hostCircles} + +
+ ) } diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx index a3692af..efc448e 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -1,7 +1,9 @@ +import { OrganisationMembersInfo } from "@/app/_components/OrganisationMemberInfo" import { OrganisationMembersGraphic } from "@/app/_components/OrganisationMembersGraphic" import { P } from "@/app/_components/Paragraph" import { PhotoSlideCarousel } from "@/app/_components/PhotoSlideCarousel" import { Page } from "@/components/shared/Page" +import { CircleDashed } from "lucide-react" import { Metadata } from "next" import Link from "next/link" @@ -54,6 +56,39 @@ export default async function RecruitmentPage() { , the student union at KTH, any profit Armada makes goes back to the students, funding THS initiatives for a better student life.

+ + The graphics below contain our current organisation structure. +
    +
  • + + Hosts +
  • +
  • + + Operation team +
  • +
  • + + Project group +
  • +
  • + + Project manager +
  • +
+