diff --git a/apps/keystone/admin/pages/incentives-dashboard.tsx b/apps/keystone/admin/pages/incentives-dashboard.tsx index cf17118..256d915 100644 --- a/apps/keystone/admin/pages/incentives-dashboard.tsx +++ b/apps/keystone/admin/pages/incentives-dashboard.tsx @@ -1,7 +1,14 @@ import { Heading } from "@keystone-ui/core"; import { useEffect, useState } from "react"; import { Link } from "@keystone-6/core/admin-ui/router"; -import { useMutation, useQuery, gql, MutationTuple, OperationVariables } from "@keystone-6/core/admin-ui/apollo"; +import { + useMutation, + useQuery, + gql, + MutationTuple, + OperationVariables, + useLazyQuery, +} from "@keystone-6/core/admin-ui/apollo"; import { Button } from "@keystone-ui/button"; import { Select, FieldContainer, FieldLabel } from "@keystone-ui/fields"; import { @@ -96,10 +103,7 @@ interface QUERY_INCENTIVES_RESULTS { const MUTATION_UPDATE_INCENTIVE = gql` mutation ($incentive: ID, $active: Boolean, $data: JSON) { - updateIncentive( - where: { id: $incentive } - data: { data: $data, active: $active } - ) { + updateIncentive(where: { id: $incentive }, data: { data: $data, active: $active }) { id title } @@ -121,11 +125,8 @@ const incentiveTypes = [ function renderIncentive( // @ts-ignore incentive: QUERY_INCENTIVES_RESULTS["event"]["donationIncentives"][0], - updateIncentiveMutation: MutationTuple< - MUTATION_UPDATE_INCENTIVE_RESULTS, - OperationVariables - >[0], - refetchData: () => void + updateIncentiveMutation: MutationTuple[0], + refetchData: () => void, ) { switch (incentive?.type) { case "war": @@ -154,39 +155,70 @@ function renderIncentive( } } +type SelectOption = { + label: string; + value: string; +} | null; + export default function RunsManager() { - const [selectedEvent, setSelectedEvent] = useState({ - label: "ASM2023", - value: "ASM2023", - }); + const [selectedEvent, setSelectedEvent] = useState(getEventInURLQuery()); const [selectedIncentiveIndex, setSelectedIncentiveIndex] = useState(0); const { addToast } = useToasts(); const eventsList = useQuery(QUERY_EVENTS); - const eventData = useQuery(QUERY_INCENTIVES, { - variables: { event: selectedEvent.value }, - }); + const [refetchEventData, { data: eventData }] = useLazyQuery(QUERY_INCENTIVES); const [updateIncentiveMutation, updateIncentiveMutationData] = - useMutation( - MUTATION_UPDATE_INCENTIVE, - ); + useMutation(MUTATION_UPDATE_INCENTIVE); const eventsOptions = eventsList.data?.events.map((event) => ({ value: event.shortname, label: event.shortname, })); - const sortedIncentives = - eventData.data?.event?.donationIncentives.map((a) => ({ ...a })) ?? []; + const sortedIncentives = eventData?.event?.donationIncentives.map((a) => ({ ...a })) ?? []; sortedIncentives.sort( - (a, b) => - new Date(a.run?.scheduledTime ?? 0).getTime() - - new Date(b.run?.scheduledTime ?? 0).getTime(), + (a, b) => new Date(a.run?.scheduledTime ?? 0).getTime() - new Date(b.run?.scheduledTime ?? 0).getTime(), ); const incentiveData = sortedIncentives[selectedIncentiveIndex]; + function handleEventSelection(option: { label: string; value: string } | null) { + const urlParams = new URLSearchParams(window.location.search); + + if (option) { + urlParams.set("event", option.value); + } else { + urlParams.delete("event"); + } + + if (urlParams.size > 0) { + const newUrl = `${window.location.pathname}?${urlParams.toString()}`; + window.history.pushState({ path: newUrl }, "", newUrl); + } else { + window.history.pushState({}, "", window.location.pathname); + } + + setSelectedEvent(option); + } + + function getEventInURLQuery(): SelectOption { + const eventName = new URLSearchParams(window.location.search).get("event"); + + if (!eventName) { + return null; + } + + return { + label: eventName, + value: eventName, + }; + } + + useEffect(() => { + if (selectedEvent?.value) refetchEventData({ variables: { event: selectedEvent.value } }); + }, [selectedEvent]); + // Update Incentive Feedback useEffect(() => { // console.log(updateRunMutationData); @@ -221,30 +253,18 @@ export default function RunsManager() {
Event - handleEventSelection(e)} value={selectedEvent} options={eventsOptions} /> - } - aria-controls="panel1a-content" - id="panel1a-header"> + } aria-controls="panel1a-content" id="panel1a-header"> Add incentive - + - {eventData?.data?.event && ( + {eventData?.event && ( <>
- {incentive.type === "goal" ? ( - - ) : ( - - )} + {incentive.type === "goal" ? : } @@ -309,14 +321,11 @@ export default function RunsManager() {

Game {incentiveData?.run.game}
- Type{" "} - - {incentiveData?.type} - + Type {incentiveData?.type}
Notes {incentiveData?.notes}

- {renderIncentive(incentiveData, updateIncentiveMutation, eventData.refetch)} + {renderIncentive(incentiveData, updateIncentiveMutation, refetchEventData)}
diff --git a/apps/nextjs/components/EventLive/EventLive.module.scss b/apps/nextjs/components/EventLive/EventLive.module.scss index 2c8e419..1baa666 100644 --- a/apps/nextjs/components/EventLive/EventLive.module.scss +++ b/apps/nextjs/components/EventLive/EventLive.module.scss @@ -4,10 +4,11 @@ .eventLive { color: $light-text; - background: $tgx-main; - background-image: url("../../styles/img/events/asgx24/asgx24-hero.png"); - // background-size: cover; + background: $dh-main; + background-image: url("../../styles/img/events/asdh24/DreamHack24Background.png"); + background-size: 100% auto; background-position-x: center; + background-repeat: no-repeat; padding: 2rem; @include breakpoint($sm-zero-only) { @@ -164,12 +165,12 @@ .twitchVideo, .twitchChat { - border: 8px solid $tgx-yellow; + border: 2px solid $dh-red; box-sizing: border-box; } .twitchChat { - border-color: $tgx-red; + border-color: $dh-red; } .twitchVideo { @@ -230,8 +231,8 @@ display: flex; flex-direction: column; justify-content: space-around; - background-color: $tgx-main; - border: 2px solid $tgx-blue; + background-color: $dh-main; + border: 2px solid $dh-red; font-size: 1.2rem; width: fit-content; word-break: break-all; @@ -287,8 +288,8 @@ flex-direction: column; height: 100%; justify-content: space-around; - background-color: $tgx-main; - border: 2px solid $tgx-green; + background-color: $dh-main; + border: 2px solid $dh-red; // width: 50%; @include breakpoint($sm-zero-only) { @@ -310,7 +311,7 @@ margin-top: 10px; width: 80%; height: 10px; - background: $tgx-rainbow-rotated; + background: $dh-orange-to-red; } } diff --git a/apps/nextjs/components/EventLive/EventLive.tsx b/apps/nextjs/components/EventLive/EventLive.tsx index 266e251..9f2f921 100644 --- a/apps/nextjs/components/EventLive/EventLive.tsx +++ b/apps/nextjs/components/EventLive/EventLive.tsx @@ -7,7 +7,7 @@ import { format } from "date-fns"; import TwitchChatEmbed from "../TwitchChatEmbed/TwitchChatEmbed"; import TwitchVideoEmbed from "../TwitchVideoEmbed/TwitchVideoEmbed"; -import EventLogo from "../../styles/img/ASGX2023 Logo.png"; +import EventLogo from "../../styles/img/events/asdh24/DreamHack24Logo.png"; import { useState } from "react"; import { Incentive } from "../Incentives/Incentive"; import Button from "../Button/Button"; @@ -114,6 +114,11 @@ export const EventLive: React.FC = (props: EventProps) => { let currentRunIndex = nextRunIndex - 1; + const numberOfRunners = eventQuery.data?.event.runs?.[currentRunIndex]?.runners.length ?? 1; + const runnersString = + eventQuery.data?.event.runs?.[currentRunIndex]?.runners.map((runner) => runner.username).join(", ") ?? + "Loading"; + return (
@@ -131,7 +136,7 @@ export const EventLive: React.FC = (props: EventProps) => {
-

March 23 – 24 | Melbourne

+

April 26 – 28 | Melbourne

@@ -161,12 +166,12 @@ export const EventLive: React.FC = (props: EventProps) => {

{eventQuery.data?.event.runs?.[currentRunIndex]?.category ?? "Loading"}

-

{currentRunIndex == 0 ? "First Runners" : "Runners"}

-

- {eventQuery.data?.event.runs?.[currentRunIndex]?.runners - .map((runner) => runner.username) - .join(", ") ?? "Loading"} -

+

+ {currentRunIndex == 0 + ? `First Runner${numberOfRunners == 1 ? "" : "s"}` + : `Runner${numberOfRunners == 1 ? "" : "s"}`} +

+

{runnersString}

@@ -188,8 +193,12 @@ export const EventLive: React.FC = (props: EventProps) => {

Upcoming Run

- {eventQuery.data?.event.runs?.[nextRunIndex]?.game ?? "Loading"} - {eventQuery.data?.event.runs?.[nextRunIndex]?.category ?? "Loading"} + + {eventQuery.data?.event.runs?.[nextRunIndex]?.game ?? "Loading"} + + + {eventQuery.data?.event.runs?.[nextRunIndex]?.category ?? "Loading"} + Time {eventQuery.data?.event.runs?.[nextRunIndex]?.scheduledTime diff --git a/apps/nextjs/components/Navbar/Navbar.module.scss b/apps/nextjs/components/Navbar/Navbar.module.scss index c97ca05..b43b369 100644 --- a/apps/nextjs/components/Navbar/Navbar.module.scss +++ b/apps/nextjs/components/Navbar/Navbar.module.scss @@ -96,6 +96,12 @@ font-size: 1rem; } + @include breakpoint($sm-zero-only) { + ul { + align-items: flex-end; + } + } + .icon { color: $light-text; } @@ -110,7 +116,7 @@ .join { color: $light-text; - white-space: nowrap; + white-space: nowrap; a { font-weight: 500; diff --git a/apps/nextjs/components/Navbar/Navbar.tsx b/apps/nextjs/components/Navbar/Navbar.tsx index 009d1b8..84f9e78 100644 --- a/apps/nextjs/components/Navbar/Navbar.tsx +++ b/apps/nextjs/components/Navbar/Navbar.tsx @@ -17,7 +17,7 @@ type NavbarProps = { published: boolean; scheduleReleased: boolean; }[]; - live?: boolean; + live?: string; }; // Define general type for useWindowSize hook, which includes width and height @@ -26,7 +26,7 @@ interface Size { height: number | undefined; } -const Navbar = ({ events = [], live = false }: NavbarProps) => { +const Navbar = ({ events = [], live }: NavbarProps) => { const auth = useAuth(); const [isOpen, setIsOpen] = useState(false); const mobileWidth = useMediaQuery("(max-width: 992px)"); @@ -82,14 +82,22 @@ const Navbar = ({ events = [], live = false }: NavbarProps) => { <>
  • Incentives
  • -
  • +
  • +
  • )} diff --git a/apps/nextjs/next.config.js b/apps/nextjs/next.config.js index 0dab38d..1e4742c 100644 --- a/apps/nextjs/next.config.js +++ b/apps/nextjs/next.config.js @@ -88,7 +88,7 @@ const nextConfig = { }, { source: "/donate", - destination: "https://donate.tiltify.com/@ausspeedruns/asgx2024 ", + destination: "https://donate.tiltify.com/c20c9685-cd1b-4d5f-8595-74378cb06859/details", permanent: false, }, ]; diff --git a/apps/nextjs/pages/ASDH2024/incentives.tsx b/apps/nextjs/pages/ASDH2024/incentives.tsx new file mode 100644 index 0000000..79db344 --- /dev/null +++ b/apps/nextjs/pages/ASDH2024/incentives.tsx @@ -0,0 +1,137 @@ +import Head from "next/head"; +import { gql, useQuery } from "urql"; +import styles from "../../styles/Event.incentives.module.scss"; + +import DiscordEmbed from "../../components/DiscordEmbed"; +import { Goal } from "../../components/Incentives/IncentiveGoal"; +import { War } from "../../components/Incentives/IncentiveWar"; +import Button from 'apps/nextjs/components/Button/Button'; +import { faChevronRight } from '@fortawesome/free-solid-svg-icons'; + +const EVENT = "ASDH2024"; + +const INCENTIVES_QUERY = gql` + query { + event(where: { shortname: "${EVENT}" }) { + donationIncentives { + id + title + notes + type + run { + id + game + category + scheduledTime + } + data + active + } + } + } +`; + +type QUERY_INCENTIVES_RESULTS = { + event: { + donationIncentives: { + id: string; + title: string; + notes: string; + type: string; + run: { + id: string; + game: string; + category: string; + scheduledTime: string; + }; + data: string; + active: string; + }[]; + }; +}; + +const Incentives = () => { + const [incentivesQuery] = useQuery({ + query: INCENTIVES_QUERY, + }); + + const sortedIncentives = incentivesQuery.data?.event.donationIncentives.map((a) => ({ ...a })) ?? []; + sortedIncentives.sort( + (a, b) => new Date(a.run?.scheduledTime ?? 0).getTime() - new Date(b.run?.scheduledTime ?? 0).getTime(), + ); + + let incentiveElements = { + active: [] as JSX.Element[], + inactive: [] as JSX.Element[], + }; + + sortedIncentives.forEach((incentive) => { + if (incentive.active) { + incentiveElements.active.push(getIncentiveElement(incentive)); + } else { + incentiveElements.inactive.push(getIncentiveElement(incentive)); + } + }); + + return ( +
    + + {`${EVENT} Donation Incentives - AusSpeedruns`} + + +
    +

    Donation Incentives

    +
    + In your donation message, mention the challenge and how + much you want to put in for it! +
    +
    +
    + {incentiveElements.active.length > 0 && ( + <> +

    Closing Soon!

    +
    +
    {incentiveElements.active[0]}
    +

    All Incentives

    +
    + {incentiveElements.active} + + )} + + {incentiveElements.inactive.length > 0 && ( + <> +

    Closed Incentives

    +
    + {/* All closed incentives */} + {incentiveElements.inactive} + + )} +
    +
    + ); +}; + +function getIncentiveElement(incentive: any): JSX.Element { + const runMetadata = { + title: incentive.title, + run: incentive.run, + active: incentive.active, + notes: incentive.notes, + }; + switch (incentive.type) { + case "goal": + return <>
    ; + case "war": + return <>
    ; + default: + return <>; + } +} + +export default Incentives; diff --git a/apps/nextjs/pages/ASDH2024/prizes.tsx b/apps/nextjs/pages/ASDH2024/prizes.tsx new file mode 100644 index 0000000..3b32203 --- /dev/null +++ b/apps/nextjs/pages/ASDH2024/prizes.tsx @@ -0,0 +1,60 @@ +import Head from "next/head"; +import styles from "../../styles/Event.incentives.module.scss"; + +import DiscordEmbed from "../../components/DiscordEmbed"; +import Button from "apps/nextjs/components/Button/Button"; +import { faChevronRight } from "@fortawesome/free-solid-svg-icons"; + +const Incentives = () => { + return ( +
    + + ASDH2024 Prizes - AusSpeedruns + + +
    +

    Prizes

    +
    +
    +

    + Prizes are Australia Only +
    + + Prizes Terms and Conditions + +

    +
    + + + + + + + +
    +
    +
    + ); +}; + +interface PrizeProps { + name: string; + requirement: string; +} + +const Prize = (props: PrizeProps) => { + return ( +
    +

    {props.name}

    +

    {props.requirement}

    +
    + ); +}; + +export default Incentives; diff --git a/apps/nextjs/pages/_app.tsx b/apps/nextjs/pages/_app.tsx index 93738c1..16a3d12 100644 --- a/apps/nextjs/pages/_app.tsx +++ b/apps/nextjs/pages/_app.tsx @@ -31,7 +31,7 @@ function AusSpeedrunsWebsite({ Component, pageProps }: AppProps) { return ( - +
    @@ -120,14 +114,14 @@ export default function Home() { actionText="Dreamhack Schedule" />
    */} - {/* */} + {/* */} - + /> */} { - return ( -
    - - ASGX2024 Prizes - AusSpeedruns - - -
    -

    Prizes

    -

    -

    -
    - ); -}; - -export default PoliciesPage; diff --git a/apps/nextjs/styles/Event.incentives.module.scss b/apps/nextjs/styles/Event.incentives.module.scss index facce10..38626e7 100644 --- a/apps/nextjs/styles/Event.incentives.module.scss +++ b/apps/nextjs/styles/Event.incentives.module.scss @@ -3,10 +3,11 @@ @import './responsive.scss'; .app { - background: $asm23-main; - background-image: url("./img/events/asgx24/asgx24-hero.png"); - // background-size: contain; + background: $dh-main; + background-image: url("./img/events/asdh24/DreamHack24Background.png"); + background-size: 100% auto; background-position-x: center; + background-repeat: no-repeat; } .content { @@ -48,7 +49,7 @@ .soon { border: 4px solid #fff; color: $light-text; - background-color: $tgx-main; + background-color: $dh-main; margin: 1rem 0 3rem; padding: 2rem; @@ -59,7 +60,7 @@ .goal { .progress { .bar { - border: 2px solid $pax23-main; + border: 2px solid $dh-main; } } } @@ -80,7 +81,7 @@ } .divider { - background: $tgx-rainbow-rotated; + background: $dh-orange-to-red; height: 5px; width: 100%; margin: 1rem 0; @@ -219,3 +220,36 @@ } } } + +.prizeToC { + padding: 2rem; + font-size: 1.1rem; + text-align: center; + + a { + color: white; + } +} + +.prizes { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 48px; + + .prize { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + + background: $dh-orange-to-red; + color: white; + padding: 32px; + border-radius: 32px; + + p { + margin: 0; + } + } +} + diff --git a/apps/nextjs/styles/colors.scss b/apps/nextjs/styles/colors.scss index 96ef681..ca1e83a 100644 --- a/apps/nextjs/styles/colors.scss +++ b/apps/nextjs/styles/colors.scss @@ -49,3 +49,12 @@ $pax23-blue: #007eb7; $pax23-purple: #904b97; $pax23-rainbow-bar: linear-gradient(90deg, $pax23-red 0%, $pax23-red 25%, $pax23-yellow 25%, $pax23-yellow 50%, $pax23-blue 50%, $pax23-blue 75%, $pax23-purple 75%, $pax23-purple 100%); +$dh-main: #000000; +$dh-light-orange: #ff7e00; +$dh-orange: #FF4B0A; +$dh-yellow: #FFEB00; +$dh-red: #FF0046; + +$dh-orange-to-orange: linear-gradient(90deg, $dh-light-orange, $dh-orange); +$dh-yellow-to-orange: linear-gradient(90deg, $dh-yellow, $dh-light-orange); +$dh-orange-to-red: linear-gradient(90deg, $dh-orange, $dh-red); diff --git a/apps/nextjs/styles/img/events/asdh24/DreamHack24Background.png b/apps/nextjs/styles/img/events/asdh24/DreamHack24Background.png new file mode 100644 index 0000000..71a83f2 Binary files /dev/null and b/apps/nextjs/styles/img/events/asdh24/DreamHack24Background.png differ diff --git a/apps/nextjs/styles/img/events/asdh24/DreamHack24Logo.png b/apps/nextjs/styles/img/events/asdh24/DreamHack24Logo.png index 743875a..61dd95d 100644 Binary files a/apps/nextjs/styles/img/events/asdh24/DreamHack24Logo.png and b/apps/nextjs/styles/img/events/asdh24/DreamHack24Logo.png differ