diff --git a/amplify/auth/PostConfirmation/handler.ts b/amplify/auth/PostConfirmation/handler.ts index 702bd92f..74d48a3a 100644 --- a/amplify/auth/PostConfirmation/handler.ts +++ b/amplify/auth/PostConfirmation/handler.ts @@ -52,6 +52,7 @@ export const handler: PostConfirmationTriggerHandler = async (event) => { const cognitoGroupResponse = await cognitoClient.send(command); const DDBResponse = await dataClient.models.User.create({ + profilePicture: "", firstName: "", lastName: "", role: "Participant", diff --git a/amplify/auth/resource.ts b/amplify/auth/resource.ts index 780710cd..5db975a3 100644 --- a/amplify/auth/resource.ts +++ b/amplify/auth/resource.ts @@ -27,68 +27,7 @@ export const auth = defineAuth({ verificationEmailStyle: "CODE", verificationEmailSubject: "Welcome Hack the Change!", verificationEmailBody: (createCode) => - ` - - - Hack the Change Account Confirmation - - - -
-
-

Hack the Change Account Confirmation

-

Thank you for creating your Hack the Change account. Please use the code below to complete your registration:

-
${createCode()}
-

If you didn't request this code, you can safely ignore this email.

-
- -
- - `, + `

Use this code to confirm your Hack the Change Account: ${createCode()}

`, }, externalProviders: { diff --git a/amplify/backend.ts b/amplify/backend.ts index a1ae0c8a..dc9f55c7 100644 --- a/amplify/backend.ts +++ b/amplify/backend.ts @@ -3,9 +3,12 @@ import { auth } from "@/amplify/auth/resource"; import { data } from "@/amplify/data/resource"; import { defineBackend } from "@aws-amplify/backend"; +import { storage } from "./storage/resource"; + const backend = defineBackend({ auth, data, + storage, }); // Cognito Email Overrides diff --git a/amplify/data/resource.ts b/amplify/data/resource.ts index cc1d81ab..730e764e 100644 --- a/amplify/data/resource.ts +++ b/amplify/data/resource.ts @@ -15,6 +15,7 @@ const schema = a User: a .model({ id: a.id().required(), + profilePicture: a.string(), firstName: a.string(), lastName: a.string(), role: a diff --git a/amplify/storage/resource.ts b/amplify/storage/resource.ts new file mode 100644 index 00000000..72a7ccd5 --- /dev/null +++ b/amplify/storage/resource.ts @@ -0,0 +1,13 @@ +import { defineStorage } from "@aws-amplify/backend"; + +export const storage = defineStorage({ + name: "profileImageStorage", + access: (allow) => ({ + "public/*": [ + allow.authenticated.to(["read", "write", "delete"]), + allow.groups(["Participant"]).to(["read", "write"]), + allow.groups(["Judge"]).to(["read", "write", "delete"]), + allow.groups(["Admin"]).to(["read", "write", "delete"]), + ], + }), +}); diff --git a/next.config.js b/next.config.js index e85fc5d2..0f33f843 100644 --- a/next.config.js +++ b/next.config.js @@ -1,6 +1,7 @@ /** @type {import('next').NextConfig} */ const nextConfig = { images: { + domains: ["images.ctfassets.net", "s3.ca-central-1.amazonaws.com"], remotePatterns: [ { protocol: "https", diff --git a/package.json b/package.json index 5ceba816..9ecec91a 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@aldabil/react-scheduler": "^2.9.5", "@aws-amplify/adapter-nextjs": "^1.0.18", "@aws-amplify/ui-react": "^6.1.5", + "@aws-amplify/ui-react-storage": "^3.9.1", "@emotion/react": "11.13.3", "@emotion/styled": "11.13.0", "@mui/icons-material": "^5.15.10", @@ -36,9 +37,9 @@ "date-fns": "^4.1.0", "js-sha3": "^0.9.3", "luxon": "^3.4.4", - "next": "^14.2.12", - "react": "^18", - "react-dom": "^18", + "next": "^15.3.5", + "react": "^19.1.0", + "react-dom": "^19.1.0", "react-hook-form": "^7.51.5", "react-icons": "^5.0.1", "react-loading-skeleton": "^3.4.0", diff --git a/public/images/landingpage/HackathonFinished/hackathon_finished_background.png b/public/images/landingpage/HackathonFinished/hackathon_finished_background.png deleted file mode 100644 index 20f2f45a..00000000 Binary files a/public/images/landingpage/HackathonFinished/hackathon_finished_background.png and /dev/null differ diff --git a/public/svgs/judgingRubric/rubric_left.svg b/public/svgs/judgingRubric/rubric_left.svg deleted file mode 100644 index 3bda143d..00000000 --- a/public/svgs/judgingRubric/rubric_left.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/public/svgs/judgingRubric/rubric_right.svg b/public/svgs/judgingRubric/rubric_right.svg deleted file mode 100644 index 6955076e..00000000 --- a/public/svgs/judgingRubric/rubric_right.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/_middleware.ts b/src/_middleware.ts new file mode 100644 index 00000000..9a5ea594 --- /dev/null +++ b/src/_middleware.ts @@ -0,0 +1,43 @@ +// // middleware.ts +// import { fetchAuthSession } from "aws-amplify/auth/server"; +// import { NextResponse } from "next/server"; +// import type { NextRequest } from "next/server"; + +// import { runWithAmplifyServerContext } from "@/utils/amplify-utils"; + +// export async function middleware(request: NextRequest) { +// const response = NextResponse.next(); + +// const authenticated = await runWithAmplifyServerContext({ +// nextServerContext: { request, response }, +// operation: async (contextSpec) => { +// try { +// const session = await fetchAuthSession(contextSpec, {}); +// return session.tokens !== undefined; +// } catch (error) { +// console.log(error); +// return false; +// } +// }, +// }); + +// if (authenticated) { +// return response; +// } + +// return NextResponse.redirect(new URL("/login", request.url)); +// } + +// export const config = { +// matcher: [ +// /* +// * Match all request paths except for the ones starting with: +// * - api (API routes) +// * - _next/static (static files) +// * - _next/image (image optimization files) +// * - favicon.ico (favicon file) +// * - login +// */ +// "/((?!api|_next/static|_next/image|favicon.ico|static|login|$).*)", +// ], +// }; diff --git a/src/app/admin/components/UsersTable.tsx b/src/app/admin/components/UsersTable.tsx index 2f9f3f42..4765f846 100644 --- a/src/app/admin/components/UsersTable.tsx +++ b/src/app/admin/components/UsersTable.tsx @@ -36,33 +36,31 @@ export default function UsersTable({ users }: { users: User[] }) { typeName: "User", }); return ( -
-
-
- setGlobalFilter(value), - [], - )} +
+
+ setGlobalFilter(value), + [], + )} + /> + + table.getHeaderGroups(), [table])} /> -
- table.getHeaderGroups(), [table])} - /> - - - - - -
-
-
- + + + + + + +
+
); } diff --git a/src/app/admin/teams/components/TanstackTableFooter.tsx b/src/app/admin/teams/components/TanstackTableFooter.tsx index 331d4be0..7bdd1455 100644 --- a/src/app/admin/teams/components/TanstackTableFooter.tsx +++ b/src/app/admin/teams/components/TanstackTableFooter.tsx @@ -2,7 +2,7 @@ import type { Table } from "@tanstack/react-table"; export default function TanstackTableFooter({ table }: { table: Table }) { return ( -
+
Showing {table.getRowModel().rows.length.toLocaleString()} of{" "} {table.getRowCount().toLocaleString()} Rows diff --git a/src/app/admin/teams/components/TeamsTable.tsx b/src/app/admin/teams/components/TeamsTable.tsx index d8613066..789be7c3 100644 --- a/src/app/admin/teams/components/TeamsTable.tsx +++ b/src/app/admin/teams/components/TeamsTable.tsx @@ -29,33 +29,31 @@ export default function TeamsTable({ teams }: { teams: Team[] }) { typeName: "Team", }); return ( -
-
-
- setGlobalFilter(value), - [], - )} +
+
+ setGlobalFilter(value), + [], + )} + /> + + table.getHeaderGroups(), [table])} /> -
- table.getHeaderGroups(), [table])} - /> - - - - - -
-
-
- + + + + + + +
+
); } diff --git a/src/app/hackathon-end/page.tsx b/src/app/hackathon-end/page.tsx deleted file mode 100644 index 1acc18fb..00000000 --- a/src/app/hackathon-end/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import HackathonFinished from "@/components/HackathonFinished"; - -export default function HackathonEndPage() { - return ; -} diff --git a/src/app/judging/RubricTable.tsx b/src/app/judging/RubricTable.tsx deleted file mode 100644 index ec5f57d1..00000000 --- a/src/app/judging/RubricTable.tsx +++ /dev/null @@ -1,443 +0,0 @@ -interface RubricTableProps { - tableBackgroundColor: string; - dividerColor: string; - headerTextColor: string; - headerBackgroundColor: string; - textColor: string; - oddRowColor: string; - evenRowColor: string; -} - -export default function RubricTable(props: RubricTableProps) { - return ( -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Category - - Minimal (1-2) - - Developing (3-4) - - Satisfactory (5-6) - - Effective (7-8) - - Excellent (9-10) -
- Idea - -
    -
  • The product is unrelated to the prompt.
  • -
  • - Idea is very similar or identical to a well-known solution. -
  • -
-
-
    -
  • - Product takes wide liberty with the prompt and is loosely - related. -
  • -
  • - Innovative aspects of the idea are not explained or - showcased. -
  • -
-
-
    -
  • - Product loosely addresses the prompt, and would not have a - large impact -
  • -
  • - Innovative aspects of the idea are explained vaguely or not - showcased. -
  • -
-
-
    -
  • Product innovatively addresses the prompt.
  • -
  • - Innovative aspects of the idea are explained and showcased. -
  • -
-
-
    -
  • - Product directly addresses the prompt and explains its - solution to the prompt in detail.  -
  • -
  • - Innovative and goes beyond the original scope of the project -
  • -
  • - Innovative aspects of the idea are explained and clearly - showcased. -
  • -
-
- Effectiveness - -
    -
  • The product is not functional and is unpresentable
  • -
-
-
    -
  • - Some features are completely broken or requires multiple - attempts to work. -
  • -
  • - Most of the product’s functionality does not relate to the - original idea of the product. -
  • -
-
-
    -
  • The core features of the product are functional. 
  • -
  • - Noticeable bugs in some features, but these bugs do not - break the overall function of the product. -
  • -
  • - Some of the product’s functionality does not relate to its - original idea. -
  • -
-
-
    -
  • The core features of the product are functional. 
  • -
  • - There are minor noticeable bugs in some features, but these - bugs do not detract from the effectiveness of the product. -
  • -
  • - Most of the product’s functionality relates to its original - idea. -
  • -
-
-
    -
  • - All features of the product are functional and working - correctly. -
  • -
  • - No visible bugs throughout the entirety of the product. -
  • -
  • - All of the product’s functionality strengthens and relates - to its original idea. -
  • -
-
- Technical Challenge - -
    -
  • - Product is straightforward and requires little to no - technical effort -
  • -
-
-
    -
  • - Product implements some level of coding and requires a small - amount of technical effort -
  • -
-
-

The product does at least ONE of the following:

-
    -
  • - Uses 1-2 different technologies/services together, including - databases, servers, datasets, and external APIs. -
  • -
  • - Implements a simple computer science concept or technique of - medium effort to enhance its functionality in an effective - way. -
  • -
  • Includes more than one functionality.
  • -
-
-

The product does at least ONE of the following:

-
    -
  • - Uses 3-4 different technologies/services together, including - databases, servers, datasets, and external APIs. -
  • -
  • - Implements a computer science concept or technique of medium - complexity to enhance its core functionality in an effective - way. -
  • -
  • Includes a wide range of cohesive functionalities.
  • -
-
-

The product does at least ONE of the following:

-
    -
  • - Uses 5+ different technologies/services together, including - databases, servers, datasets, and external APIs.  -
  • -
  • - Implements a difficult and complex computer science concept - or technique to enhance its functionality. -
  • -
  • Introduces a new solution that breaks ground.
  • -
-
- Presentation/ Marketability - -
    -
  • - The team appears to have not prepared for the presentation - at all -
  • -
  • Knowledge on the topic is not apparent
  • -
  • Questions asked by judges cannot be answered
  • -
-
-
    -
  • - The team appears to have practiced for the presentation, but - the delivery is not smooth. -
  • -
  • Limited knowledge of the topic
  • -
  • - Questions asked by the judges can be partially answered with - uncertainty -
  • -
-
-
    -
  • The team is coordinated in their presentation.
  • -
  • - Presentation includes information regarding motivation, - marketability, and real-world applications of their product. -
  • -
  • Solid knowledge of the topic
  • -
  • - Questions asked by judges can be answered with simple - phrases -
  • -
-
-
    -
  • - The presentation is engaging and team members appear - coordinated in the delivery. -
  • -
  • - Presentation provides unique perspectives on the motivation, - marketability, and real-world applications of their product. -
  • -
  • Good knowledge on the topic
  • -
  • - Questions asked by judges can be answered eloquently with - some code references -
  • -
-
-
    -
  • - Presenters are enthusiastic and the presentation clearly - captivates the audience. -
  • -
  • - Presentation is visually appealing and provides unique - perspectives on the motivation, marketability, and - real-world applications of their product. -
  • -
  • Refined knowledge on the topic
  • -
  • - Questions asked by judges can be answered eloquently with - code references -
  • -
-
- Design - -
    -
  • The design of the product makes it unusable
  • -
-
-
    -
  • - The design of the project overall detracts from its - functionality -
  • -
  • Product usage is not intuitive or difficult to follow
  • -
  • The product message and intention are unclear
  • -
-
-
    -
  • - The product’s design neither detracts nor enhances its - functionality. -
  • -
  • - Presentation includes information regarding motivation, - marketability, and real-world applications of their product. -
  • -
  • - The product’s message is mostly clear but loosely relates to - its original idea. -
  • -
-
-
    -
  • The product’s design is clean and uncluttered.
  • -
  • - The product is easy to use but may require some additional - instruction. -
  • -
  • - The product’s message is clear and the product’s design - relates to its original idea. -
  • -
-
-
    -
  • - The product’s design is clean, visually appealing and - eye-catching. -
  • -
  • - The product is organized and can be used without any - additional instruction. -
  • -
  • - The product’s design enhances and aligns strongly with its - original idea. -
  • -
-
-
-
- ); -} diff --git a/src/app/judging/layout.tsx b/src/app/judging/layout.tsx index 1d8d137c..0573ec5d 100644 --- a/src/app/judging/layout.tsx +++ b/src/app/judging/layout.tsx @@ -1,3 +1,5 @@ +import NavBar from "@/components/judging/Navbar"; + export default function JudgingLayout({ children, }: { @@ -5,6 +7,7 @@ export default function JudgingLayout({ }) { return (
+
{children}
); diff --git a/src/app/judging/rubric/page.tsx b/src/app/judging/rubric/page.tsx index d4533a5e..ebe3c47e 100644 --- a/src/app/judging/rubric/page.tsx +++ b/src/app/judging/rubric/page.tsx @@ -1,21 +1,8 @@ -import JudgingRubric from "../../judging/RubricTable"; - const RubricPage = () => { return ( -
-

- Judging Rubric -

- - +
+

Judging Rubric here

+
    ); }; diff --git a/src/app/page.tsx b/src/app/page.tsx index 4aa3e5f4..df6a3066 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -9,7 +9,7 @@ import PagePlaceholder from "@/components/PagePlaceholder"; import { enableLandingPage } from "@/featureFlags"; export const revalidate = 600; -const Home = async () => { +const Home = () => { return (
    {enableLandingPage ? ( diff --git a/src/app/participant/layout.tsx b/src/app/participant/layout.tsx deleted file mode 100644 index 04c80f49..00000000 --- a/src/app/participant/layout.tsx +++ /dev/null @@ -1,18 +0,0 @@ -"use client"; - -export default function RoleBasedLayout({ - children, -}: { - children: React.ReactNode; -}) { - // For Admin layouts we might want to show a SideNavBar/TopNavBar - // You can use the same hook or control it separately if needed. - // Here we assume non-admin users only need the nav rendered by UserBasedNav. - - // This example uses the UserBasedNav component in the layout: - return ( -
    -
    {children}
    -
    - ); -} diff --git a/src/app/participant/team-selection/CreateTeamPage.tsx b/src/app/participant/team-selection/CreateTeamPage.tsx index 74d36b2d..33908232 100644 --- a/src/app/participant/team-selection/CreateTeamPage.tsx +++ b/src/app/participant/team-selection/CreateTeamPage.tsx @@ -36,7 +36,7 @@ const CreateTeamPage = () => { />

    Register for Hack the Change{" "} - 2025 + 2024

    - + Go To My

    Food Ticket

    - + diff --git a/src/components/Dashboard/JudgingInfo.tsx b/src/components/Dashboard/JudgingInfo.tsx index 85348258..f0a0b68b 100644 --- a/src/components/Dashboard/JudgingInfo.tsx +++ b/src/components/Dashboard/JudgingInfo.tsx @@ -107,7 +107,7 @@ export default function JudgingInfo() {
    View Judging Rubric diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 03087192..9e06c1e5 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -9,7 +9,7 @@ const Footer = () => { >

    Keep Up With Us!

    -

    +

    Copyright @ Code the Change YYC

    diff --git a/src/components/HackathonFinished.tsx b/src/components/HackathonFinished.tsx index d846a871..ef375111 100644 --- a/src/components/HackathonFinished.tsx +++ b/src/components/HackathonFinished.tsx @@ -25,7 +25,7 @@ const HackathonFinished = () => {

    Hack the Change

    -

    +

    2025

    @@ -35,7 +35,7 @@ const HackathonFinished = () => {

    -

    +

    Thank-you to all participants, judges and sponsors!

    diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 5c709c01..5df1b320 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -10,9 +10,38 @@ import { useUserDetails } from "@/components/contexts/UserDetailsContext"; import UserBasedNav from "./Dashboard/UserBasedNav"; export default function Header() { - const { userDetails } = useUserDetails(); + const user = useUser().currentUser; - const userId = userDetails?.id || ""; + const userId = useUser().currentUser.username as string; + + const { data } = useQuery({ + initialData: {} as Schema["Team"]["type"], + initialDataUpdatedAt: 0, + queryKey: ["Team", userId], + queryFn: async () => { + const userResponse = await client.models.User.get({ + id: userId, + }); + + if (userResponse.errors) throw new Error(userResponse.errors[0].message); + + const userTeamId = userResponse.data?.teamId as string; + + if (userTeamId) { + const teamResponse = await client.models.Team.get({ + id: userTeamId, + }); + + if (teamResponse.errors) + throw new Error(teamResponse.errors[0].message); + + return teamResponse.data; + } else { + return {} as Schema["Team"]["type"]; + } + }, + enabled: !!userId, + }); const router = useRouter(); const handleLogout = () => { signOut(); @@ -43,12 +72,12 @@ export default function Header() {
    - {userDetails?.completedRegistration && ( + {user.completedRegistration && ( )} - {userDetails.role && userDetails?.role !== UserType.Guest && ( + {user.username && ( diff --git a/src/components/KevinLoadingRing.tsx b/src/components/KevinLoadingRing.tsx index 69e43d94..7871a578 100644 --- a/src/components/KevinLoadingRing.tsx +++ b/src/components/KevinLoadingRing.tsx @@ -6,7 +6,7 @@ export default function KevinLoadingRing() {
    Kevin Icon
    {sortedSponsors.map((sponsor, index) => ( -
    -
    -
    +
    +
    +
    -
    +
    {
    Register for Hack the Change - 2025 + 2024
    ); diff --git a/src/components/LoginForm/PersonalFormFields.tsx b/src/components/LoginForm/PersonalFormFields.tsx index fe8e462a..b9b99511 100644 --- a/src/components/LoginForm/PersonalFormFields.tsx +++ b/src/components/LoginForm/PersonalFormFields.tsx @@ -1,4 +1,5 @@ import type { AuthUser } from "aws-amplify/auth"; +import { fetchAuthSession } from "aws-amplify/auth"; import { useRouter } from "next/navigation"; import { useState } from "react"; import { toast } from "react-toastify"; @@ -7,11 +8,15 @@ import { client } from "@/app/QueryProvider"; import FormFieldButtons from "@/components/LoginForm/FormFieldButtons"; import FormFieldsHeader from "@/components/LoginForm/FormFieldsHeader"; import { Flex, Input, Label, SelectField } from "@aws-amplify/ui-react"; -import { useMutation, useQuery } from "@tanstack/react-query"; +import { FileUploader } from "@aws-amplify/ui-react-storage"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; + +import KevinLoadingRing from "../KevinLoadingRing"; import { UserType, useUser } from "../contexts/UserContext"; import KevinLoadingRing from "../KevinLoadingRing"; export default function PersonalFormFields({ user }: { user: AuthUser }) { + const queryClient = useQueryClient(); const router = useRouter(); const { isPending, isError, data } = useQuery({ queryKey: ["User", user?.userId], @@ -38,6 +43,7 @@ export default function PersonalFormFields({ user }: { user: AuthUser }) { willEatMeals: input.willEatMeals, allergies: input.allergies, completedRegistration: true, + profilePicture: input.profilePicture, }); toast.dismiss(toastObj); if (response.errors) { @@ -70,6 +76,7 @@ export default function PersonalFormFields({ user }: { user: AuthUser }) { } const [formState, setFormState] = useState({ id: user?.userId, + profilePicture: "", } as Schema["User"]["type"]); const submitForm = (e: React.FormEvent) => { e.preventDefault(); @@ -90,7 +97,6 @@ export default function PersonalFormFields({ user }: { user: AuthUser }) { } }; - console.log(isPending); if (isPending) { return (
    @@ -129,6 +135,7 @@ export default function PersonalFormFields({ user }: { user: AuthUser }) { return null; } } + return (
    +
    + + { + if (file.type !== "image/png") { + throw new Error("Only PNG files are allowed."); + } + const session = await fetchAuthSession(); + const identityId = session.identityId; + const extension = file.type.split("/")[1] || "png"; + const newKey = `${identityId}.${extension}`; + const renamedFile = new File( + [file], + `${identityId}.${extension}`, + { + type: file.type, + }, + ); + return { + key: newKey, + file: renamedFile, + }; + }} + onUploadSuccess={() => { + queryClient.invalidateQueries({ queryKey: ["profile-image"] }); + }} + /> +
    => { + const session = await fetchAuthSession(); + const identityId = session.identityId; + try { + const { url } = await getUrl({ + path: `public/${identityId}.png`, + }); + return url.href; + } catch (err) { + console.error(`Failed to fetch image:`, err); + } -const RIGHT_SQUIGGLE_STYLES = - "absolute right-0 ml-1 mt-2 md:right-0 md:h-56 md:w-60 lg:right-20 lg:block lg:size-1/3"; + return null; // No image found + }; -export default function ProfileHeader() { - const user = useUser().currentUser; + const { data: profileImageUrl, isLoading } = useQuery({ + queryKey: ["profile-image"], + queryFn: fetchProfileImage, + }); - // console.log(user); + if (isLoading) { + return ( +
    +

    Loading...

    +
    + ); + } return ( -
    -
    +
    +
    Profile Image
    @@ -37,7 +60,9 @@ export default function ProfileHeader() { alt="Left Squiggly SVG" width={105} height={60} - className={LEFT_SQUIGGLE_STYLES} + className={ + "absolute left-0 mr-1 mt-2 md:h-56 md:w-52 lg:mb-8 lg:block lg:h-1/3 lg:w-2/5" + } />

    {user.username ? ( @@ -56,7 +81,9 @@ export default function ProfileHeader() { alt="Right Squiggly SVG" width={105} height={60} - className={RIGHT_SQUIGGLE_STYLES} + className={ + "absolute right-0 ml-1 mt-2 md:right-0 md:h-56 md:w-60 lg:right-20 lg:block lg:size-1/3" + } />

    diff --git a/src/components/UserProfile/ProfileLinks.tsx b/src/components/UserProfile/ProfileLinks.tsx index 7ded5307..1c936edc 100644 --- a/src/components/UserProfile/ProfileLinks.tsx +++ b/src/components/UserProfile/ProfileLinks.tsx @@ -26,7 +26,7 @@ export default function ProfileLinks() { }, []); return ( -
    +
    {currentUser.id && links.map((link, index) => ( { teamId, checkedIn, profileOwner, - email, - role, ...extractedFields } = input; // TODO this can be cleaned if we use React Hook Form to handle form state better diff --git a/src/components/atoms/SocialMediaIcons.tsx b/src/components/atoms/SocialMediaIcons.tsx index 899cbf1a..0054f024 100644 --- a/src/components/atoms/SocialMediaIcons.tsx +++ b/src/components/atoms/SocialMediaIcons.tsx @@ -45,13 +45,10 @@ const SocialMediaIcons = () => { ]; return ( -
    +
    {links.map(({ link, icon: Icon }) => ( - + ))}
    diff --git a/src/components/hoc/withAuthGuard.tsx b/src/components/hoc/withAuthGuard.tsx index 420cc330..a4ae919a 100644 --- a/src/components/hoc/withAuthGuard.tsx +++ b/src/components/hoc/withAuthGuard.tsx @@ -1,7 +1,7 @@ import { redirect } from "next/navigation"; import type React from "react"; import { UserType } from "@/components/contexts/UserContext"; -import { AuthGetAuthSession } from "@/utils/amplify-utils"; +import { AuthGetCurrentUserServer } from "@/utils/amplify-utils"; const withAuthGuard = ( WrappedComponent: React.ComponentType, @@ -17,7 +17,7 @@ const withAuthGuard = ( } }; - return AuthGetAuthSession() + return AuthGetCurrentUserServer() .then((user) => { if (user?.tokens) { return userTypeHasPagePermission( diff --git a/src/components/layouts/MainLayout.tsx b/src/components/layouts/MainLayout.tsx index 1a459182..a533fd8f 100644 --- a/src/components/layouts/MainLayout.tsx +++ b/src/components/layouts/MainLayout.tsx @@ -4,34 +4,23 @@ import Footer from "@/components/Footer"; import Header from "@/components/Header"; import PagePlaceholder from "@/components/PagePlaceholder"; import { enableLandingPage } from "@/featureFlags"; -import { - AuthGetCurrentUserDetails, - type UserDetailsNoFunctions, -} from "@/utils/amplify-utils"; interface Props { children: ReactNode | ReactNode[]; } -export default async function MainLayout({ children }: Props) { - const userDetails = await AuthGetCurrentUserDetails(); - - // have to return a placeholder for this in the case that the user is a guest user +export default function MainLayout({ children }: Props) { return ( <> {enableLandingPage ? ( ) : ( <> - -
    -
    - {children} -
    -