Skip to content

Commit

Permalink
feat(custom-options): add radio buttons as option (#79)
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 Jun 28, 2024
1 parent 8a03ff6 commit 21f6be3
Show file tree
Hide file tree
Showing 21 changed files with 137 additions and 89 deletions.
59 changes: 31 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,7 @@ Design drodling finner man her: [Nettside design](https://www.figma.com/design/Z

## Sanity

### Deploy

Sanity Studio blir deployet til [https://capra.sanity.studio/](https://capra.sanity.studio/). Github Actions deploy utløses ved push til main-branch og endring i /studio. Det er også mulig å gjøre det manuelt ved å navigere til /studio og kjøre følgende kommando:

```bash
sanity deploy
```

Administrering av Sanity instansen kan gjøres via [https://www.sanity.io/manage/personal/project/<project-id>](https://www.sanity.io/manage/personal/project/<project-id>).

## Bygg
### Bygg

For å bygge en produksjonsversjon av Sanity studio lokalt, naviger deg til /studio og kjør følgende kommando:

Expand All @@ -82,21 +72,29 @@ pnpm build

Bygg bør alltid kjøres som en del av vår pull request policy 👷

## Lint
### Deploy

Sanity/SvelteKit templaten [sanity-template-sveltekit-clean](https://github.com/sanity-io/sanity-template-sveltekit-clean) hadde en broken eslint konfigurasjon. Har derfor prøvd å oppgradere til eslint 9 med flatconfig fra denne [issuen](https://github.com/sveltejs/eslint-plugin-svelte/issues/732). 👷 Det er en del lint-errors som må undersøkes.
Sanity Studio blir deployet til [https://capra.sanity.studio/](https://capra.sanity.studio).
GitHub Actions CI/CD deploy kjører automatisk ved push til main-branch og ved endringer i /studio mappen. Alternativt kan deploy også utføres manuelt ved å navigere til /studio-katalogen og kjøre følgende kommando:

## SvelteKit
```bash
sanity deploy
```

### Deploy
Administrering av Sanity instansen kan gjøres via [https://www.sanity.io/manage/personal/project/<project-id>](https://www.sanity.io/manage/personal/project/<project-id>).

SvelteKit blir foreløpig deployet til [https://capra-web.vercel.app/](https://capra-web.vercel.app/) fra /app med følgenden kommando:
### TypeScript Generering

```bash
vercel deploy
For å generere typer av innholdsskjemaer, kjør følgende kommandoer fra /studio:

```sh
sanity schema extract --enforce-required-fields
sanity typegen generate
```

👷 Vi er på en Vercel-plan som ikke tillater bygg og deploy i en organisasjon. Må undersøke CI/CD-løsninger på et tidspunkt for å automatisere vår deploy prosess.
NB: Når sanity.model.ts er generert i /studio/models, skal den også kopieres til /app.

## SvelteKit

### Bygg

Expand All @@ -108,16 +106,19 @@ pnpm build

Bygg bør alltid kjøres som en del av vår pull request policy 👷

### TypeScript Generering
### Deploy

For å generere typer av innholdsskjemaer, kjør følgende kommandoer fra /studio:
SvelteKit blir foreløpig deployet til [https://capra-web.vercel.app/](https://capra-web.vercel.app/) fra /app med følgenden kommando:

```sh
sanity schema extract --enforce-required-fields
sanity typegen generate
```bash
vercel deploy
```

NB: Når sanity.model.ts er generert i /studio/models, skal den også kopieres til /app.
👷 Vi er på en Vercel-plan som ikke tillater bygg og deploy i en organisasjon. Må undersøke CI/CD-løsninger på et tidspunkt for å automatisere vår deploy prosess.

### Lint

SvelteKit templaten [sanity-template-sveltekit-clean](https://github.com/sanity-io/sanity-template-sveltekit-clean) hadde en broken eslint konfigurasjon. Har derfor prøvd å oppgradere til eslint 9 med flatconfig fra denne [issuen](https://github.com/sveltejs/eslint-plugin-svelte/issues/732). 👷 Det er en del lint-errors som må undersøkes.

## Supabase

Expand Down Expand Up @@ -155,7 +156,7 @@ Vil du klikke deg rundt i browser for å se hva som skjer i testene, sleng på `

Plausible tilbyr en måte å analysere trafikk på nettstedet. Den er fritt for cookies og samler ingen personopplysninger. Vi trenger derfor ingen cookie consent. For å integrere Plausible er det lagt til et sporingsskriptet i HTML-headeren. Sporingen for å måle og analysere besøksstatistikk vises i et Sanity dashboard.

Vi er på en trial versjon foreløpig 👷
Vi er på en trial-plan foreløpig 👷

## Slack

Expand All @@ -165,6 +166,8 @@ Når et arrangement publiseres for første gang, vil det automatisk genereres en

E-post med kalenderinvitasjon (.ics-fil) sendes fra SvelteKit på serversiden. På grunn av manglende tilgang til en server fra Sanity, har vi satt opp et API-endepunkt i SvelteKit som Sanity kan kommunisere med for å sende e-post. Som SMTP host benytter vi oss av [Mandrill](https://mandrillapp.com/). Innlogging skjer via Capra sin Mailchimp bruker siden Mandrill er en underleverandær av dem.

E-post domene for alle selskaper må verifiseres. Vi er på en trial-plan her og 👷

### Påmelding

Når en bruker melder seg på et arrangement, utløses følgende prosess:
Expand Down Expand Up @@ -209,8 +212,8 @@ Ved avlysing av et arrangement i Sanity:

For å teste e-postfunksjonaliteten lokalt:

1. Legg til `localhost` i `Access-Control-Allow-Origin`.
2. Fjern "development"-sjekker i funksjonskallene for å kjøre i lokalt miljø.
1. Fjern "development"-sjekker i funksjonskallene for å kjøre i lokalt miljø.
2. For å teste e-post sendt fra Sanity: Legg til `http://localhost:3333` i `Access-Control-Allow-Origin`.

### Kalenderinvitasjon 👷

Expand Down
3 changes: 2 additions & 1 deletion app/src/components/external/EventFormExternal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
delayed: registrationDelayed,
enhance: registrationEnhance,
} = superForm<RegistrationFormExternalType>(data.registrationForm, {
resetForm: false,
dataType: "json",
validators: zod(registrationSchemaExternal),
delayMs: 500,
async onSubmit() {
Expand All @@ -38,7 +40,6 @@
enhance: unregistrationEnhance,
} = superForm<UnregistrationFormExternalType>(data.unregistrationForm, {
validators: zod(unregistrationSchemaExternal),
dataType: "json",
delayMs: 500,
async onSubmit() {
await new Promise((result) => setTimeout(result, 500));
Expand Down
6 changes: 3 additions & 3 deletions app/src/components/external/RegistrationFormExternal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import Deadline from "$components/shared/Deadline.svelte";
import RegistrationCustomOption from "$components/shared/RegistrationCustomOption.svelte";
import { dateHasPassed } from "$lib/utils/date.util";
import { vercelStegaCleanAll } from "@sanity/client/stega";
import { stegaClean } from "@sanity/client/stega";
export let event: Event;
export let numberOfParticipants: number;
Expand Down Expand Up @@ -97,8 +97,8 @@
{#each event.customOptions as customOption}
<RegistrationCustomOption
{form}
inputType={vercelStegaCleanAll(customOption.fieldType)}
optionLabel={vercelStegaCleanAll(customOption.fieldOption)}
inputType={stegaClean(customOption.fieldType)}
optionLabel={stegaClean(customOption.fieldOption)}
/>
{/each}
{#if $errors.customOptions}
Expand Down
10 changes: 5 additions & 5 deletions app/src/components/external/UnregistrationFormExternal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
<input type="text" name="subject" id="subject" class="hidden" />

<div
class="mb-8 flex flex-col items-start justify-center gap-4 rounded-lg border p-4 dark:border-gray-700 dark:bg-gray-800 sm:p-8"
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"
>
<div class="flex flex-col items-center gap-5">
<div class="flex flex-col items-start gap-4">
<div class="items-start-4 flex flex-col">
<h4
class="text-2xl font-bold leading-none tracking-tight text-gray-900 dark:text-white sm:text-2xl"
class="text-2xl font-bold leading-none tracking-tight text-gray-900 sm:text-2xl dark:text-white"
>
<p class="text-2xl">Ønsker du å melde deg av?</p>
<h2 class="pb-4 text-base font-bold sm:text-xl">Ønsker du å melde deg av?</h2>
</h4>

<ButtonGroup class="w-100">
Expand All @@ -34,7 +34,7 @@
name="email"
bind:value={$form.email}
/>
<Button class="w-48" type="submit" color="alternative" disabled={$delayed}>
<Button class="w-48" type="submit" color="light" disabled={$delayed}>
Meld meg av
<span class="w-3">
{#if $delayed}
Expand Down
1 change: 1 addition & 0 deletions app/src/components/internal/EventFormInternal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
enhance: registrationEnhance,
} = superForm<RegistrationFormInternalType>(data.registrationForm, {
validators: zod(registrationSchemaInternal),
resetForm: false,
dataType: "json",
delayMs: 500,
async onSubmit() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{#if names.length}
{#each names as name}
<span>
<Badge rounded class="mr-1 h-6 border border-black bg-transparent dark:bg-zinc-800"
<Badge rounded class="mb-1 mr-1 h-6 border border-black bg-transparent dark:bg-zinc-800"
>{name}</Badge
>
</span>
Expand Down
8 changes: 4 additions & 4 deletions app/src/components/internal/RegistrationFormInternal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import RegistrationCustomOption from "$components/shared/RegistrationCustomOption.svelte";
import { dateHasPassed } from "$lib/utils/date.util";
import Deadline from "$components/shared/Deadline.svelte";
import { vercelStegaCleanAll } from "@sanity/client/stega";
import { stegaClean } from "@sanity/client/stega";
export let event: Event;
export let numberOfParticipants: number;
Expand Down Expand Up @@ -49,8 +49,8 @@
{#each event.customOptions as customOption}
<RegistrationCustomOption
{form}
inputType={vercelStegaCleanAll(customOption.fieldType)}
optionLabel={vercelStegaCleanAll(customOption.fieldOption)}
inputType={stegaClean(customOption.fieldType)}
optionLabel={stegaClean(customOption.fieldOption)}
/>
{/each}
{#if $errors.customOptions}
Expand All @@ -59,7 +59,7 @@
{/if}

<div class="flex w-full">
<Button pill color="dark" type="submit" disabled={$delayed}
<Button class="mt-4" pill color="dark" type="submit" disabled={$delayed}
><span class="ml-3">Meld meg på</span>
<span class="w-3">
{#if $delayed}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
use:enhance
>
<div class="flex w-full">
<Button pill color="alternative" type="submit" disabled={$delayed}>
<Button pill color="light" type="submit" disabled={$delayed}>
<span class="ml-3">Meld meg av</span>
<span class="w-3">
{#if $delayed}
Expand Down
5 changes: 3 additions & 2 deletions app/src/components/shared/Deadline.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
</script>

<div class="flex gap-1">
<p>Fristen for å melde seg på er</p>
{formatDateWithWeekDay(deadline)} kl {formatTime(deadline)}
<p>
Fristen for å melde seg på er {formatDateWithWeekDay(deadline)} kl {formatTime(deadline)}
</p>
</div>
4 changes: 2 additions & 2 deletions app/src/components/shared/EventSummary.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<h1 class="pb-6 text-3xl font-semibold sm:text-5xl">{event.title}</h1>

{#if event.summary}
<p class="pb-6 text-base font-light sm:text-xl">{event.summary}</p>
<p class="pb-6 text-base font-light sm:w-[60%] sm:text-xl">{event.summary}</p>
{/if}

<div class="flex flex-col gap-5 pb-6 sm:h-60 sm:flex-row">
Expand Down Expand Up @@ -52,7 +52,7 @@
</div>

{#if event.body}
<div class="flex flex-col gap-4 text-base">
<div class="flex flex-col gap-4 text-base sm:w-[60%]">
<PortableText components={{}} value={event.body} />
</div>
{/if}
30 changes: 23 additions & 7 deletions app/src/components/shared/RegistrationCustomOption.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { Checkbox, Textarea } from "flowbite-svelte";
import { Checkbox, Radio, Textarea } from "flowbite-svelte";
import { writable } from "svelte/store";
export let form = writable<FormData>({ customOptions: [] });
Expand All @@ -15,6 +15,11 @@
customOptions: CustomOption[];
}
const handleRadioChange = (event: Event) => {
const { value } = event.target as HTMLInputElement;
updateFormValue(optionLabel, value);
};
const handleCheckboxChange = (event: Event) => {
const { checked } = event.target as HTMLInputElement;
updateFormValue(optionLabel, checked ? "Ja" : "");
Expand All @@ -30,22 +35,33 @@
const updatedOptions = currentForm.customOptions.filter(
(customOption) => customOption.option !== option
);
if (value) {
updatedOptions.push({ option, value });
}
if (value) updatedOptions.push({ option, value });
return { ...currentForm, customOptions: updatedOptions };
});
};
if (inputType === "radio") {
updateFormValue(optionLabel, "Ja");
}
</script>

<div class="flex flex-col gap-1">
<span class="block text-sm font-bold text-gray-900 rtl:text-right dark:text-gray-300">
{optionLabel}
</span>
{#if inputType === "checkbox"}
<Checkbox name="customOptions" on:change={handleCheckboxChange}>Ja!</Checkbox>
<Checkbox name="customOptions" on:change={handleCheckboxChange}>Ja</Checkbox>
{:else if inputType === "radio"}
<div class="flex gap-6 text-sm">
<div class="flex gap-2">
<Radio inline name="customOptions" group="Ja" value="Ja" on:change={handleRadioChange}>
Ja
</Radio>
</div>
<div class="flex gap-2">
<Radio inline name="customOptions" value="Nei" on:change={handleRadioChange}>Nei</Radio>
</div>
</div>
{:else}
<Textarea name="customOptions" class="bg-white" on:input={handleInputChange} />
{/if}
Expand Down
4 changes: 2 additions & 2 deletions app/src/lib/actions/internal/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const submitRegistrationInternal: Actions["submitRegistrationInternal"] =

if (await limiter.isLimited(requestEvent)) {
return message(registrationForm, {
text: "Du har nådd grensen for antall påmeldinger. Vennligst vent en stund før du prøver igjen.",
text: "Du har nådd grensen for antall forsøk. Vennligst vent en stund før du prøver igjen.",
error: true,
});
}
Expand Down Expand Up @@ -224,7 +224,7 @@ export const submitUnregistrationInternal: Actions["submitUnregistrationInternal

if (await limiter.isLimited(requestEvent)) {
return message(unregistrationForm, {
text: "Du har nådd grensen for antall avmeldinger. Vennligst vent en stund før du prøver igjen.",
text: "Du har nådd grensen for antall forsøk. Vennligst vent en stund før du prøver igjen.",
error: true,
});
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/lib/auth/secret.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { APP_SECRET } from "$env/static/private";
import type { TokenData } from "$models/jwt.model";

export const getUnsubscribeSecret = ({ document_id, event_id, email }: TokenData) => {
const secret = `${document_id}-${event_id}-${email}-${APP_SECRET}`;
const secret = `${document_id}-${String(event_id)}-${email}-${APP_SECRET}`;
return secret;
};
19 changes: 18 additions & 1 deletion app/src/lib/email/event/registration.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { PUBLIC_APP_BASE_URL } from "$env/static/public";
import ical, { ICalAttendeeRole, ICalAttendeeStatus, ICalCalendarMethod } from "ical-generator";
import ical, {
ICalAlarmType,
ICalAttendeeRole,
ICalAttendeeStatus,
ICalCalendarMethod,
} from "ical-generator";
import { sendMail } from "$lib/email/nodemailer";

interface EventProps {
Expand Down Expand Up @@ -78,6 +83,18 @@ const createIcsFile = ({
name: organiser,
email: "[email protected]",
},
alarms: [
{
type: ICalAlarmType.display,
description: "Arrangementet starter straks",
relatesTo: "START", // -> 10 minutes before event starts
},
{
type: ICalAlarmType.display,
description: "Påminnelse om arrangement i morgen",
trigger: 86400, // -> 24 hours before event starts
},
],
});

return Buffer.from(calendar.toString());
Expand Down
2 changes: 1 addition & 1 deletion app/src/lib/email/event/unregistration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const sendConfirmUnregistration = async (props: {
const html = `<span style="font-family: Roboto, sans-serif;
font-style: normal;
font-weight: 400;
font-size: 16px;
font-size: 14px;
line-height: 20px;
letter-spacing: 0.2px;
color: #3c4043;">
Expand Down
Loading

0 comments on commit 21f6be3

Please sign in to comment.