Skip to content
Open
2 changes: 1 addition & 1 deletion frontend/src/Pages/ComponentPage/ComponentPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export function ComponentPage() {
visibility_from_dt: new Date().toISOString(),
visibility_to_dt: '',
start_dt: new Date().toISOString(),
status: 'active',
status: 'public',
ticket_type: 'free',
title_en: 'Von August with a very long title just like this // 23:59',
title_nb: 'Von August // 23:59',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,15 @@ import type { EventDto } from '~/dto';
import { usePrevious, useTitle } from '~/hooks';
import { KEY } from '~/i18n/constants';
import { venueKeys } from '~/queryKeys';
import { EventAgeRestriction, type EventAgeRestrictionValue, EventCategory, type EventCategoryValue } from '~/types';
import { dbT, getAgeRestrictionKey, getEventCategoryKey, lowerCapitalize } from '~/utils';
import {
EventAgeRestriction,
type EventAgeRestrictionValue,
EventCategory,
type EventCategoryValue,
type EventStatus,
EventStatusChoice,
} from '~/types';
import { dbT, getAgeRestrictionKey, getEventCategoryKey, getEventStatusTranslationKey, lowerCapitalize } from '~/utils';
import { AdminPageLayout } from '../AdminPageLayout/AdminPageLayout';
import styles from './EventCreatorAdminPage.module.scss';
import { type FormType, useEventCreatorForm } from './hooks/useEventCreatorForm';
Expand Down Expand Up @@ -57,6 +64,11 @@ export function EventCreatorAdminPage() {
label: t(getAgeRestrictionKey(age)),
}));

const eventStatusOptions: DropdownOption<EventStatus>[] = Object.values(EventStatusChoice).map((status) => ({
value: status,
label: t(getEventStatusTranslationKey(status)),
}));

const { form, watchedValues, buildPayload } = useEventCreatorForm({
event,
defaultCategory: eventCategoryOptions[0]?.value ?? EventCategory.ART,
Expand All @@ -68,7 +80,7 @@ export function EventCreatorAdminPage() {
info: <InfoStep form={form} eventCategoryOptions={eventCategoryOptions} locationOptions={locationOptions} />,
payment: <PaymentStep form={form} ageLimitOptions={ageLimitOptions} />,
graphics: <GraphicsStep form={form} />,
summary: <SummaryStep form={form} />,
summary: <SummaryStep form={form} eventStatusOptions={eventStatusOptions} />,
};

// Fetch event data using the event ID
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
EVENT_LOCATION,
EVENT_REGISTRATION_URL,
EVENT_START_DT,
EVENT_STATUS,
EVENT_TICKET_TYPE,
EVENT_TITLE,
EVENT_VISIBILITY_FROM_DT,
Expand Down Expand Up @@ -51,6 +52,7 @@ export const eventSchema = z.object({
// Graphics
image: OPTIONAL_IMAGE,
// Summary/Publication date
status: EVENT_STATUS,
visibility_from_dt: EVENT_VISIBILITY_FROM_DT,
visibility_to_dt: EVENT_VISIBILITY_TO_DT,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export function useEventCreatorForm(params: {
custom_tickets: [],
billig_id: undefined,
image: undefined,
status: 'public',
Comment thread
BragonSB marked this conversation as resolved.
Outdated
visibility_from_dt: '',
visibility_to_dt: '',
},
Expand Down Expand Up @@ -75,6 +76,7 @@ export function useEventCreatorForm(params: {
custom_tickets: event.custom_tickets || [],
billig_id: event.billig?.id,
image: event.image ?? undefined,
status: event.status || 'public',
visibility_from_dt: event.visibility_from_dt ? utcTimestampToLocal(event.visibility_from_dt, false) : '',
visibility_to_dt: event.visibility_to_dt ? utcTimestampToLocal(event.visibility_to_dt, false) : '',
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,51 @@
import type { UseFormReturn } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '~/Components';
import { Dropdown, FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '~/Components';
import type { DropdownOption } from '~/Components/Dropdown/Dropdown';
import { KEY } from '~/i18n/constants';
import type { EventStatus } from '~/types';
import styles from '../EventCreatorAdminPage.module.scss';
import type { FormType } from '../hooks/useEventCreatorForm';

export function SummaryStep({ form }: { form: UseFormReturn<FormType> }) {
type Props = {
form: UseFormReturn<FormType>;
eventStatusOptions: DropdownOption<EventStatus>[];
Comment thread
BragonSB marked this conversation as resolved.
Outdated
};

export function SummaryStep({ form, eventStatusOptions }: Props) {
const { t } = useTranslation();

return (
<FormField
control={form.control}
name="visibility_from_dt"
key="visibility_from_dt"
render={({ field }) => (
<FormItem className={styles.form_item}>
<FormLabel>{t(KEY.saksdokumentpage_publication_date) ?? ''}</FormLabel>
<FormControl>
<Input type="datetime-local" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className={styles.input_row}>
<FormField
control={form.control}
name="visibility_from_dt"
key="visibility_from_dt"
render={({ field }) => (
<FormItem className={styles.form_item}>
<FormLabel>{t(KEY.saksdokumentpage_publication_date) ?? ''}</FormLabel>
<FormControl>
<Input type="datetime-local" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="status"
key="status"
render={({ field }) => (
<FormItem className={styles.form_item}>
<FormLabel>{t(KEY.event_status)}</FormLabel>
<FormControl>
<Dropdown options={eventStatusOptions} nullOption={{ label: t(KEY.common_choose) }} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@ export const steps: EventCreatorStep[] = [
title_nb: 'Oppsummering',
title_en: 'Summary',
customIcon: 'ic:outline-remove-red-eye',
validate: (d) => !!d.visibility_from_dt,
validate: (d) => !!d.visibility_from_dt && !!d.status,
},
];
2 changes: 2 additions & 0 deletions frontend/src/dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ export type EventDto = {
};

export type EventWriteDto = {
status?: EventStatus;
Comment thread
BragonSB marked this conversation as resolved.

title_nb: string;
title_en: string;
description_long_nb: string;
Expand Down
9 changes: 9 additions & 0 deletions frontend/src/i18n/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,14 @@ export const KEY = {
event_category_theme_party: 'event_category_theme_party',
event_category_uka_event: 'event_category_uka_event',

// Event statuses
event_status: 'event_status',
event_status_public: 'event_status_public',
event_status_private: 'event_status_private',
event_status_archived: 'event_status_archived',
event_status_cancelled: 'event_status_cancelled',
event_status_deleted: 'event_status_deleted',

// Venue Page:
venuepage_title: 'venuepage_title',

Expand Down Expand Up @@ -689,6 +697,7 @@ export const KEY = {
event_form_category_required: 'event_form_category_required',
event_form_age_restriction_required: 'event_form_age_restriction_required',
event_form_ticket_type_required: 'event_form_ticket_type_required',
event_form_status_required: 'event_form_status_required',
} as const;

// This will ensure that each value matches the key exactly.
Expand Down
18 changes: 18 additions & 0 deletions frontend/src/i18n/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,14 @@ export const nb = prepareTranslations({
[KEY.event_category_theme_party]: 'Temafest',
[KEY.event_category_uka_event]: 'UKE-arrangement',

// Event statuses
[KEY.event_status]: 'Status',
[KEY.event_status_public]: 'Offentlig',
[KEY.event_status_private]: 'Privat',
[KEY.event_status_archived]: 'Arkivert',
[KEY.event_status_cancelled]: 'Avlyst',
[KEY.event_status_deleted]: 'Slettet',
Comment thread
BragonSB marked this conversation as resolved.

//Purchase Ticket Info:
[KEY.invalid_email_message]: 'Ugyldig e-postformat',
[KEY.email_or_membership_number_message]: 'Du må oppgi enten en e-post eller et medlemsnummer',
Expand Down Expand Up @@ -708,6 +716,7 @@ export const nb = prepareTranslations({
[KEY.event_form_category_required]: 'Kategori er påkrevd',
[KEY.event_form_age_restriction_required]: 'Aldersgrense er påkrevd',
[KEY.event_form_ticket_type_required]: 'Billetttype er påkrevd',
[KEY.event_form_status_required]: 'Status er påkrevd',
Comment thread
aTrueYety marked this conversation as resolved.
});

export const en = prepareTranslations({
Expand Down Expand Up @@ -1003,6 +1012,14 @@ export const en = prepareTranslations({
[KEY.event_category_theme_party]: 'Theme party',
[KEY.event_category_uka_event]: 'UKA event',

// Event statuses
[KEY.event_status]: 'Status',
[KEY.event_status_public]: 'Public',
[KEY.event_status_private]: 'Private',
[KEY.event_status_archived]: 'Archived',
[KEY.event_status_cancelled]: 'Cancelled',
[KEY.event_status_deleted]: 'Deleted',
Comment thread
BragonSB marked this conversation as resolved.

// EventPage:
[KEY.event_registration_url]: 'Registration URL',
[KEY.event_add_ticket]: 'Add ticket',
Expand Down Expand Up @@ -1409,4 +1426,5 @@ export const en = prepareTranslations({
[KEY.event_form_category_required]: 'Category is required',
[KEY.event_form_age_restriction_required]: 'Age restriction is required',
[KEY.event_form_ticket_type_required]: 'Ticket type is required',
[KEY.event_form_status_required]: 'Status is required',
Comment thread
BragonSB marked this conversation as resolved.
});
3 changes: 2 additions & 1 deletion frontend/src/schema/event.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { z } from 'zod';
import { KEY } from '~/i18n/constants';
import { EventAgeRestriction, EventCategory, EventTicketType } from '~/types';
import { EventAgeRestriction, EventCategory, EventStatusChoice, EventTicketType } from '~/types';
import { zodEnum } from './utils';

export const EVENT_TITLE = z.string().min(1, { message: KEY.event_form_title_required });
Expand All @@ -26,3 +26,4 @@ export const EVENT_X_LINK = z.string().url().optional();
export const EVENT_CATEGORY = zodEnum(EventCategory, KEY.event_form_category_required);
export const EVENT_AGE_RESTRICTION = zodEnum(EventAgeRestriction, KEY.event_form_age_restriction_required);
export const EVENT_TICKET_TYPE = zodEnum(EventTicketType, KEY.event_form_ticket_type_required);
export const EVENT_STATUS = zodEnum(EventStatusChoice, KEY.event_form_status_required);
10 changes: 9 additions & 1 deletion frontend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,15 @@ export const ALL_DAYS: Day[] = ['monday', 'tuesday', 'wednesday', 'thursday', 'f
export const WEEK_DAYS: Day[] = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'];

/** Event types */
export type EventStatus = 'active' | 'cancelled' | 'archived' | 'deleted';
export const EventStatusChoice = {
PUBLIC: 'public',
PRIVATE: 'private',
ARCHIVED: 'archived',
CANCELLED: 'cancelled',
DELETED: 'deleted',
} as const;

export type EventStatus = (typeof EventStatusChoice)[keyof typeof EventStatusChoice];

export const EventAgeRestriction = {
NONE: 'none',
Expand Down
15 changes: 15 additions & 0 deletions frontend/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
EventAgeRestriction,
type EventAgeRestrictionValue,
type EventCategoryValue,
type EventStatus,
EventTicketType,
type EventTicketTypeValue,
} from './types';
Expand Down Expand Up @@ -280,6 +281,20 @@ export function getAgeRestrictionKey(age: EventAgeRestrictionValue): Translation
}
}

/**
* Gets the translation key for a given event status
*/
export function getEventStatusTranslationKey(status: EventStatus): TranslationKeys {
const map: Record<EventStatus, TranslationKeys> = {
public: KEY.event_status_public,
private: KEY.event_status_private,
archived: KEY.event_status_archived,
cancelled: KEY.event_status_cancelled,
deleted: KEY.event_status_deleted,
};
return map[status];
}

/**
* Converts a UTC timestring from django to
* a local timestring suitable for html input elements
Expand Down
Loading