-
Notifications
You must be signed in to change notification settings - Fork 1
Add social media links to create events #2093
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 23 commits
007fe64
2428fd8
107d940
f034209
efc59a9
7a9f47f
95a7b5a
d183925
9f8097d
ae18ed7
9b4cf65
f193a8c
09f1996
e8380e4
a5c72ca
64fe9be
8e48756
854cbe6
944a5e0
9ea1636
b1f515c
ad03022
6f4f865
cf1a508
378b8bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| # Generated by Django 5.2.11 on 2026-03-05 17:52 | ||
|
|
||
| from django.db import migrations, models | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ('samfundet', '0005_medlemsinfo'), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.AddField( | ||
| model_name='event', | ||
| name='general_link', | ||
| field=models.URLField(blank=True, null=True), | ||
| ), | ||
| migrations.AddField( | ||
| model_name='event', | ||
| name='lastfm_link', | ||
| field=models.URLField(blank=True, null=True), | ||
| ), | ||
| migrations.AddField( | ||
| model_name='event', | ||
| name='soundcloud_link', | ||
| field=models.URLField(blank=True, null=True), | ||
| ), | ||
| migrations.AddField( | ||
| model_name='event', | ||
| name='spotify_uri', | ||
| field=models.CharField(blank=True, max_length=200, null=True), | ||
| ), | ||
| migrations.AddField( | ||
| model_name='event', | ||
| name='vimeo_link', | ||
| field=models.URLField(blank=True, null=True), | ||
| ), | ||
| migrations.AddField( | ||
| model_name='event', | ||
| name='youtube_embed', | ||
| field=models.URLField(blank=True, null=True), | ||
| ), | ||
| migrations.AddField( | ||
| model_name='event', | ||
| name='youtube_link', | ||
| field=models.URLField(blank=True, null=True), | ||
| ), | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -62,6 +62,7 @@ | |
| } | ||
| } | ||
|
|
||
|
|
||
| .half { | ||
| flex-basis: 50%; | ||
| display: flex; | ||
|
|
@@ -87,3 +88,33 @@ | |
| padding-bottom: 3.75em; | ||
| gap: 0.5em; | ||
| } | ||
|
|
||
| .socialMediaGrid { | ||
| display: grid; | ||
| gap: 2em; | ||
| grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); | ||
| align-items: start; | ||
| } | ||
|
|
||
| .socialMediaItem { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 0.25em; | ||
| } | ||
|
|
||
|
|
||
| .socialMediaLabel { | ||
| font-weight: 600; | ||
| } | ||
|
|
||
| .socialMediaInput { | ||
| height: 2.25em; | ||
| } | ||
|
|
||
| .gridItemFull { | ||
| grid-column: 1 / -1; | ||
| } | ||
|
|
||
| .gridItemFull .socialGrid { | ||
| max-width:max-content ; | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Kan ikke se at dette har blitt brukt noe sted. Fjerne? Lav viktighet.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ja, glemte å fjerne så fjernet dem nå |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,6 +28,7 @@ import { EventPreviewCard } from './components/EventPreviewCard'; | |
| import { GraphicsStep } from './steps/GraphicsStep'; | ||
| import { InfoStep } from './steps/InfoStep'; | ||
| import { PaymentStep } from './steps/PaymentStep'; | ||
| import { SocialMediaStep } from './steps/SocialMediaStep'; | ||
| import { SummaryStep } from './steps/SummaryStep'; | ||
| import { TextStep } from './steps/TextStep'; | ||
|
|
||
|
|
@@ -57,6 +58,19 @@ export function EventCreatorAdminPage() { | |
| label: t(getAgeRestrictionKey(age)), | ||
| })); | ||
|
|
||
| const SOCIAL_FIELDS = [ | ||
| 'spotify_uri', | ||
| 'youtube_link', | ||
| 'youtube_embed', | ||
| 'facebook_link', | ||
| 'soundcloud_link', | ||
| 'instagram_link', | ||
| 'x_link', | ||
| 'lastfm_link', | ||
| 'vimeo_link', | ||
| 'general_link', | ||
| ] as const; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Er samme liste som i Forslag er å heller eksportere listen fra
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
|
|
||
| const { form, watchedValues, buildPayload } = useEventCreatorForm({ | ||
| event, | ||
| defaultCategory: eventCategoryOptions[0]?.value ?? EventCategory.ART, | ||
|
|
@@ -67,10 +81,13 @@ export function EventCreatorAdminPage() { | |
| text: <TextStep form={form} />, | ||
| info: <InfoStep form={form} eventCategoryOptions={eventCategoryOptions} locationOptions={locationOptions} />, | ||
| payment: <PaymentStep form={form} ageLimitOptions={ageLimitOptions} />, | ||
| socialmedia: <SocialMediaStep form={form} />, | ||
| graphics: <GraphicsStep form={form} />, | ||
| summary: <SummaryStep form={form} />, | ||
| }; | ||
|
|
||
| const hasSocialMediaErrors = SOCIAL_FIELDS.some((name) => !!form.formState.errors[name]); | ||
|
|
||
| // Fetch event data using the event ID | ||
| useEffect(() => { | ||
| if (id) { | ||
|
|
@@ -96,7 +113,7 @@ export function EventCreatorAdminPage() { | |
|
|
||
| const formTabs: Tab[] = steps.map((step: EventCreatorStep) => { | ||
| const custom = step.customIcon !== undefined; | ||
| const valid = step.validate(watchedValues) && !custom; | ||
| const valid = !custom && (step.key === 'socialmedia' ? !hasSocialMediaErrors : step.validate(watchedValues)); | ||
|
|
||
| const visited = visitedTabs[step.key] === true && !custom; | ||
| const error = !valid && visited && !custom; | ||
|
|
@@ -158,7 +175,9 @@ export function EventCreatorAdminPage() { | |
| } | ||
|
|
||
| // Ready to save? | ||
| const allStepsComplete = steps.every((step) => step.validate(watchedValues)); | ||
| const allStepsComplete = steps.every((step) => | ||
| step.key === 'socialmedia' ? !hasSocialMediaErrors : step.validate(watchedValues), | ||
| ); | ||
|
|
||
| // ================================== // | ||
| // Navigation Logic // | ||
|
|
@@ -185,7 +204,7 @@ export function EventCreatorAdminPage() { | |
| ) : null; | ||
|
|
||
| const onInvalid = (errors: FieldErrors<FormType>) => { | ||
| toast.error(KEY.event_invalid_form_error); | ||
| toast.error(t(KEY.event_invalid_form_error)); | ||
| const allVisited: Record<string, boolean> = {}; | ||
| for (const s of steps) allVisited[s.key] = true; | ||
| setVisitedTabs(allVisited); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| import type { UseFormReturn } from 'react-hook-form'; | ||
| import { useTranslation } from 'react-i18next'; | ||
| import { FormControl, FormField, FormItem, FormLabel, FormMessage, Input } from '~/Components'; | ||
| import { FormDescription } from '~/Components/Forms/Form'; | ||
| import { KEY } from '~/i18n/constants'; | ||
| import styles from '../EventCreatorAdminPage.module.scss'; | ||
| import type { EventFormType } from '../EventCreatorSchema'; | ||
| import type { FormType } from '../hooks/useEventCreatorForm'; | ||
|
|
||
| type SocialLinkKey = Extract< | ||
| keyof EventFormType, | ||
| | 'spotify_uri' | ||
| | 'youtube_link' | ||
| | 'youtube_embed' | ||
| | 'facebook_link' | ||
| | 'soundcloud_link' | ||
| | 'instagram_link' | ||
| | 'x_link' | ||
| | 'lastfm_link' | ||
| | 'vimeo_link' | ||
| | 'general_link' | ||
| >; | ||
|
|
||
| type Props = { | ||
| form: UseFormReturn<FormType>; | ||
| }; | ||
|
|
||
| const SOCIAL_KEYS: readonly SocialLinkKey[] = [ | ||
| 'spotify_uri', | ||
| 'youtube_link', | ||
| 'youtube_embed', | ||
| 'facebook_link', | ||
| 'soundcloud_link', | ||
| 'instagram_link', | ||
| 'x_link', | ||
| 'lastfm_link', | ||
| 'vimeo_link', | ||
| 'general_link', | ||
| ] as const; | ||
|
|
||
| export function SocialMediaStep({ form }: Props) { | ||
| const { t } = useTranslation(); | ||
|
|
||
| const SOCIAL_LABELS: Record<SocialLinkKey, string> = { | ||
| spotify_uri: 'Spotify URI', | ||
| youtube_link: 'YouTube link', | ||
| youtube_embed: 'YouTube embed', | ||
| facebook_link: 'Facebook link', | ||
| soundcloud_link: 'SoundCloud link', | ||
| instagram_link: 'Instagram link', | ||
| x_link: 'X link', | ||
| lastfm_link: 'Last.fm link', | ||
| vimeo_link: 'Vimeo link', | ||
| general_link: t(KEY.event_general_link), | ||
| }; | ||
|
Comment on lines
+44
to
+55
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bruke translation her? Er vell egentlig "lenke" istedenfor "link" på norsk. Usikker på "Spotify URI" og "YouTube embed" for det blir jo likt mellom norsk og engelsk. Har lav betydning, for folk forstår "link".
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. La til oversettelse for link/lenke nå |
||
|
|
||
| const SOCIAL_MEDIA_HELP: Partial<Record<SocialLinkKey, string>> = { | ||
| spotify_uri: t(KEY.event_spotify_uri_help), | ||
| youtube_link: t(KEY.event_youtube_link_help), | ||
| youtube_embed: t(KEY.event_youtube_embed_help), | ||
| }; | ||
|
|
||
| return ( | ||
| <> | ||
| <div className={styles.socialMediaGrid}> | ||
| {SOCIAL_KEYS.map((name) => ( | ||
| <FormField | ||
| key={name} | ||
| name={name} | ||
| control={form.control} | ||
| render={({ field }) => ( | ||
| <FormItem className={styles.socialMediaItem}> | ||
| <FormLabel className={styles.socialMediaLabel}>{SOCIAL_LABELS[name]}</FormLabel> | ||
| <FormControl> | ||
| <Input | ||
| className={styles.socialMediaInput} | ||
| type="text" | ||
| {...field} | ||
| placeholder={name === 'spotify_uri' ? 'spotify:...' : 'https://...'} | ||
| /> | ||
| </FormControl> | ||
| {SOCIAL_MEDIA_HELP[name] ? <FormDescription>{SOCIAL_MEDIA_HELP[name]}</FormDescription> : null} | ||
| <FormMessage /> | ||
| </FormItem> | ||
| )} | ||
| /> | ||
| ))} | ||
| </div> | ||
| </> | ||
| ); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Funnet noen steder med ekstra tomme linjer i denne filen. Kjøre linter?
Lav viktighet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed