Skip to content

Commit

Permalink
feat(📬): add invitation view (#94)
Browse files Browse the repository at this point in the history
Co-authored-by: Anton Lilleby <[email protected]>
  • Loading branch information
an2n and Anton Lilleby authored Jul 30, 2024
1 parent 7970e85 commit 9c78e5a
Show file tree
Hide file tree
Showing 11 changed files with 336 additions and 20 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ Design drodling finner man her: [Nettside design](https://www.figma.com/design/Z

## Komme i gang

For å kjøre koden loaklt:
For å kjøre koden lokalt:

1. Be om environment variabler for lokal testing i kanalen [#tmp_arrangementsoversikt]().
Du må selv opprette en `.env.local` fil i /studio og /app.
Du må selv opprette en `.env.local` fil i både /studio og /app.

Hvis du trenger tilgang til Sanity Studio, eventuelt Google Console, Vercel og Supabase, må dette også spesifikt forespørres.

Expand Down
2 changes: 1 addition & 1 deletion app/src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<link rel="icon" href="%sveltekit.assets%/favicon.ico" />
<link rel="stylesheet" href="%sveltekit.assets%/global.css" />
<meta name="viewport" content="width=device-width" />
<meta name="description" content="Arrangementer | Capra Liflig Fryde">
<meta name="description" content="Arrangementer | Capra Liflig Fryde" />

%sveltekit.head%
</head>
Expand Down
4 changes: 2 additions & 2 deletions app/src/components/external/UnregistrationFormExternal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
<input type="text" name="subject" id="subject" class="hidden" />

<div
class="mb-8 flex flex-col items-start justify-center rounded-lg border p-4 sm:p-8 dark:border-gray-700 dark:bg-gray-800"
class="mb-8 flex flex-col items-start justify-center rounded-lg border p-4 dark:border-gray-700 dark:bg-gray-800 sm:p-8"
>
<div class="flex flex-col items-center gap-5">
<div class="items-start-4 flex flex-col">
<h4
class="text-2xl font-bold leading-none tracking-tight text-gray-900 sm:text-2xl dark:text-white"
class="text-2xl font-bold leading-none tracking-tight text-gray-900 dark:text-white sm:text-2xl"
>
<h2 class="pb-4 text-base font-bold sm:text-xl">Ønsker du å melde deg av?</h2>
</h4>
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/shared/EventSummary.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
<div class="group relative w-full sm:h-60 sm:w-[60%]">
<div
aria-hidden="true"
class="ease-in-ou absolute left-0 top-0 h-full w-full rounded-xl duration-1000 group-hover:translate-x-2 group-hover:translate-y-2"
class="absolute left-0 top-0 h-full w-full rounded-xl duration-1000 group-hover:translate-x-2 group-hover:translate-y-2"
style="background: {event.image.palette.darkMuted.background}"
></div>

Expand Down
20 changes: 10 additions & 10 deletions app/src/components/shared/Footer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,31 @@
<div class="pt-6 text-base sm:p-0 sm:text-lg">Sertifiseringer</div>
<div class="flex gap-2">
<img
class="block h-16 dark:hidden sm:h-20"
class="block h-16 sm:h-20 dark:hidden"
alt="Miljøfyrtårn-sertifisering"
src={miljofyrtarnDark}
/>
<img
class="hidden h-16 dark:block sm:h-20"
class="hidden h-16 sm:h-20 dark:block"
alt="Miljøfyrtårn-sertifisering"
src={miljofyrtarnLight}
/>
<img class="block h-16 dark:hidden sm:h-20" alt="DNV-sertifisering" src={dnvDark} />
<img class="hidden h-16 dark:block sm:h-20" alt="DNV-sertifisering" src={dnvLight} />
<img class="block h-16 sm:h-20 dark:hidden" alt="DNV-sertifisering" src={dnvDark} />
<img class="hidden h-16 sm:h-20 dark:block" alt="DNV-sertifisering" src={dnvLight} />
</div>
</div>
<div class="flex gap-11">
<a href="https://www.capraconsulting.no/">
<img class="block h-20 dark:hidden sm:h-28" alt="Capra-logo" src={capraLogoBlack} />
<img class="hidden h-20 dark:block sm:h-28" alt="Capra-logo" src={capraLogoWhite} />
<img class="block h-20 sm:h-28 dark:hidden" alt="Capra-logo" src={capraLogoBlack} />
<img class="hidden h-20 sm:h-28 dark:block" alt="Capra-logo" src={capraLogoWhite} />
</a>
<a href="https://www.liflig.no/">
<img class="block h-20 dark:hidden sm:h-28" alt="Liflig-logo" src={lifligLogoBlack} />
<img class="hidden h-20 dark:block sm:h-28" alt="Liflig-logo" src={lifligLogoWhite} />
<img class="block h-20 sm:h-28 dark:hidden" alt="Liflig-logo" src={lifligLogoBlack} />
<img class="hidden h-20 sm:h-28 dark:block" alt="Liflig-logo" src={lifligLogoWhite} />
</a>
<a href="https://www.fryde.no/">
<img class="block h-20 dark:hidden sm:h-28" alt="Fryde-logo" src={frydeLogoBlack} />
<img class="hidden h-20 dark:block sm:h-28" alt="Fryde-logo" src={frydeLogoWhite} />
<img class="block h-20 sm:h-28 dark:hidden" alt="Fryde-logo" src={frydeLogoBlack} />
<img class="hidden h-20 sm:h-28 dark:block" alt="Fryde-logo" src={frydeLogoWhite} />
</a>
</div>
<div>
Expand Down
26 changes: 26 additions & 0 deletions app/src/models/database.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,32 @@ export type Database = {
},
];
};
event_invitation: {
Row: {
email: string;
event_id: number;
full_name: string | null;
};
Insert: {
email: string;
event_id: number;
full_name?: string | null;
};
Update: {
email?: string;
event_id?: number;
full_name?: string | null;
};
Relationships: [
{
foreignKeyName: "event_invitation_event_id_fkey";
columns: ["event_id"];
isOneToOne: false;
referencedRelation: "event";
referencedColumns: ["event_id"];
},
];
};
event_participant: {
Row: {
attending: boolean;
Expand Down
4 changes: 2 additions & 2 deletions studio/components/event/EventFoodPreference.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from "react";
import { useQuery } from "@tanstack/react-query";
import { Card, Flex, Grid, Heading, Spinner, Stack, Text } from "@sanity/ui";
import { getEventFoodPreferences } from "../../supabase/queries";
import { getEventFoodPreferenceList } from "../../supabase/queries";

export default function EventFoodPreference({ documentId }: { documentId: string }) {
const { data, isLoading, isError } = useQuery({
queryKey: ["event-food-preference-list", documentId],
queryFn: () => getEventFoodPreferences({ documentId }),
queryFn: () => getEventFoodPreferenceList({ documentId }),
});

const cardProps = { border: true, padding: 3, radius: 2 };
Expand Down
207 changes: 207 additions & 0 deletions studio/components/event/EventInvitation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
import React, { useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import {
Box,
Button,
Card,
Flex,
Grid,
Heading,
Label,
Spinner,
Stack,
Text,
TextInput,
useToast,
} from "@sanity/ui";
import { getEvent, getEventInvitationList, insertInvitation } from "../../supabase/queries";
import { AddIcon } from "@sanity/icons";

export default function EventInvitation({ documentId }: { documentId: string }) {
const toast = useToast();

const [email, setEmail] = useState<string>("");
const [fullName, setFullName] = useState<string>("");

const { data: event } = useQuery({
queryKey: ["event", documentId],
queryFn: () => getEvent({ document_id: documentId }),
});

const { data, isLoading, isError } = useQuery({
queryKey: ["event-invitation-list", documentId],
queryFn: () => getEventInvitationList({ documentId }),
});

const queryClient = useQueryClient();

async function handleInvitationAdd() {
const emailRegex = new RegExp("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{1,}$");
if (!email || !emailRegex.test(email)) return;

try {
await insertInvitation({ document_id: documentId }, { full_name: fullName, email });

queryClient.invalidateQueries({ queryKey: ["event-invitation-list"] });

setEmail("");
setFullName("");

toast.push({
status: "success",
title: `${email} ble lagt til i listen`,
});
} catch (error) {
if (error instanceof Error) {
toast.push({
status: "error",
title: error.message,
});
}
}
}

const cardProps = { border: true, padding: 3, radius: 2 };

if (isLoading) {
return (
<Grid gap={4}>
<Spinner muted />
</Grid>
);
}

if (isError)
return (
<Grid gap={4}>
<Text muted size={1}>
Arrangement
</Text>
<Heading as={"h2"} size={4} style={{ paddingTop: "3.5px" }}>
En feil har oppstått
</Heading>
</Grid>
);

if (!data?.length) {
return (
<Grid gap={4}>
<Text muted size={1}>
Arrangement
</Text>
<Heading as="h2" size={4} style={{ paddingTop: "3.5px" }}>
Ingen invitasjoner
</Heading>

{event?.data ? (
<>
<Grid columns={[1]} gap={4} style={{ width: "100%", marginTop: "3rem" }}>
<Box>
<Text size={1} style={{ marginBottom: "0.75rem", fontWeight: 500 }}>
Fulltnavn
</Text>
<TextInput
aria-label="Fulltnavn"
type="text"
onChange={(event) => setFullName(event.currentTarget.value)}
padding={2}
value={fullName}
/>
</Box>
<Box>
<Text
aria-label="E-post"
size={1}
style={{ marginBottom: "0.75rem", fontWeight: 500 }}
>
E-post*
</Text>
<TextInput
type="email"
onChange={(event) => setEmail(event.currentTarget.value)}
padding={2}
value={email}
/>
</Box>
</Grid>
<Box style={{ display: "flex", justifyContent: "flex-end", width: "100%" }}>
<Button
fontSize={[1]}
icon={AddIcon}
mode="ghost"
onClick={() => handleInvitationAdd()}
padding={3}
text="Legg til"
/>
</Box>
</>
) : null}
</Grid>
);
}

return (
<>
<Grid gap={4}>
<Text muted size={1}>
Arrangement
</Text>
<Heading as={"h2"} size={4} style={{ paddingTop: "3.5px" }}>
Invitasjoner ({data.length})
</Heading>

<Grid columns={[1]} gap={4} style={{ width: "100%", marginTop: "3rem" }}>
<Box>
<Text
aria-label="Fulltnavn"
size={1}
style={{ marginBottom: "0.75rem", fontWeight: 500 }}
>
Fulltnavn
</Text>

<TextInput
onChange={(event) => setFullName(event.currentTarget.value)}
padding={2}
value={fullName}
/>
</Box>
<Box>
<Text aria-label="E-post" size={1} style={{ marginBottom: "0.75rem", fontWeight: 500 }}>
E-post*
</Text>
<TextInput
type="email"
onChange={(event) => setEmail(event.currentTarget.value)}
padding={2}
value={email}
/>
</Box>
</Grid>

<Box style={{ display: "flex", justifyContent: "flex-end", width: "100%" }}>
<Button
fontSize={[1]}
icon={AddIcon}
mode="ghost"
onClick={() => handleInvitationAdd()}
padding={3}
text="Legg til"
/>
</Box>
</Grid>

<Grid gap={4} style={{ maxHeight: "300px", overflowY: "scroll", marginTop: "3rem" }}>
{data.map(({ email, full_name }, index) => (
<Card {...cardProps} key={index}>
<Stack space={4}>
<Flex align="center">
<Text>{full_name ? `${full_name} - ${email}` : email}</Text>
</Flex>
</Stack>
</Card>
))}
</Grid>
</>
);
}
10 changes: 10 additions & 0 deletions studio/config/structure.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { QueryClient } from "@tanstack/react-query";
import EventFoodPreference from "../components/event/EventFoodPreference";
import EventLayout from "../components/event/EventLayout";
import EventParticipant from "../components/event/EventParticipant";
import EventInvitation from "../components/event/EventInvitation";

const queryClient = new QueryClient();

Expand Down Expand Up @@ -36,6 +37,15 @@ export const getDefaultDocumentNode = (
);
})
.title("Allergier/matpreferanser"),
S.view
.component(({ documentId }: { documentId: string }) => {
return (
<EventLayout queryClient={queryClient}>
<EventInvitation documentId={documentId} />
</EventLayout>
);
})
.title("Invitasjoner"),
]);
}
return S.document().views([S.view.form()]);
Expand Down
Loading

1 comment on commit 9c78e5a

@vercel
Copy link

@vercel vercel bot commented on 9c78e5a Jul 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.