Skip to content
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

Add promo video to form #1292

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions backend/samfundet/migrations/0008_recruitment_promo_media.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.2 on 2024-09-10 19:39

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('samfundet', '0007_recruitmentgangstat'),
]

operations = [
migrations.AddField(
model_name='recruitment',
name='promo_media',
field=models.CharField(default=None, help_text='Youtube video id', max_length=11, null=True),
),
]
1 change: 1 addition & 0 deletions backend/samfundet/models/recruitment.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class Recruitment(CustomBaseModel):
organization = models.ForeignKey(null=False, blank=False, to=Organization, on_delete=models.CASCADE, help_text='The organization that is recruiting')

max_applications = models.PositiveIntegerField(null=True, blank=True, verbose_name='Max applications per applicant')
promo_media = models.CharField(max_length=11 ,help_text='Youtube video id', null=True, default=None)

def recruitment_progress(self) -> float:
applications = RecruitmentApplication.objects.filter(recruitment=self)
Expand Down
10 changes: 10 additions & 0 deletions backend/samfundet/serializers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import re
import itertools
from typing import TYPE_CHECKING
from collections import defaultdict
Expand Down Expand Up @@ -719,11 +720,20 @@ class Meta:

class RecruitmentSerializer(CustomBaseSerializer):
separate_positions = RecruitmentSeparatePositionSerializer(many=True, read_only=True)
promo_media = serializers.CharField(max_length=100)
Copy link
Contributor

Choose a reason for hiding this comment

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

Tror ikke dette er nødvendig, ettersom det er allerede gjort gjennom at det er et innkludert felt

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Det var nødvendig for å tillate input lenger enn 11 characters i api-interface


class Meta:
model = Recruitment
fields = '__all__'

def validate_promo_media(self, value: str | None) -> str | None:
if (value is None):
return None
match = re.search(r'(youtu.*be.*)\/(watch\?v=|embed\/|v|shorts|)(.*?((?=[&#?])|$))', value)
if (match):
return match.group(3)
raise ValidationError("Invalid youtube url")

Comment on lines +729 to +736
Copy link
Contributor

Choose a reason for hiding this comment

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

Hvor brukes denne? Bør nok være i recruitment og ikke serializer. Validate blir brukt i andre steder i recruitment model objektet, kan sette dette opp der

Copy link
Contributor

Choose a reason for hiding this comment

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

Kan i samme sleng påkreve kun siste biten av url, og så manuellt legge den til når den vises

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Den kjøres av seg selv, django magic ellerno

Copy link
Member

Choose a reason for hiding this comment

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


class RecruitmentForRecruiterSerializer(CustomBaseSerializer):
seperate_positions = RecruitmentSeparatePositionSerializer(many=True, read_only=True)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import styles from './OrganizationRecruitmentPage.module.scss';
import { RecruitmentTabs, GangTypeContainer, GangSeparatePositions } from './Components';
import { Text, Page, Video, Logo, OccupiedFormModal, SamfundetLogoSpinner, ToggleSwitch } from '~/Components';
import { PersonalRow } from '~/Pages/RecruitmentPage';
import { OrgNameType, OrgNameTypeValue } from '~/types';
import { useDesktop } from '~/hooks';
import { useParams } from 'react-router-dom';
import { KEY } from '~/i18n/constants';
import { dbT } from '~/utils';
import { useTranslation } from 'react-i18next';
import classNames from 'classnames';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useParams } from 'react-router-dom';
import { getOrganization, getRecruitment } from '~/api';
import { Logo, OccupiedFormModal, Page, SamfundetLogoSpinner, Text, ToggleSwitch, Video } from '~/Components';
import { useOrganizationContext } from '~/context/OrgContextProvider';
import { RecruitmentDto } from '~/dto';
import { getOrganization, getRecruitment } from '~/api';
import classNames from 'classnames';
import { useDesktop } from '~/hooks';
import { KEY } from '~/i18n/constants';
import { PersonalRow } from '~/Pages/RecruitmentPage';
import { OrgNameType, OrgNameTypeValue } from '~/types';
import { dbT } from '~/utils';
import { GangSeparatePositions, GangTypeContainer, RecruitmentTabs } from './Components';
import styles from './OrganizationRecruitmentPage.module.scss';

export function OrganizationRecruitmentPage() {
const isDesktop = useDesktop();
const embededId = '-nYQb8_TvQ4'; // TODO: Make this dynamic DO IN ISSUE #1121 for backend. #1274 for frontend
const { recruitmentID } = useParams<{ recruitmentID: string }>();
const [viewAllPositions, setViewAllPositions] = useState<boolean>(true);
const { t } = useTranslation();
Expand Down Expand Up @@ -76,9 +75,9 @@ export function OrganizationRecruitmentPage() {
{dbT(recruitment, 'name')}
</Text>
</div>
{embededId ? (
{recruitment?.promo_media ? (
<>
<Video embedId={embededId} className={styles.video}></Video>
<Video embedId={recruitment.promo_media} className={styles.video}></Video>
</>
) : (
<></>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next';
import { useNavigate, useParams, useRouteLoaderData } from 'react-router-dom';
import { toast } from 'react-toastify';
import { DropDownOption } from '~/Components/Dropdown/Dropdown';
import { SamfForm } from '~/Forms/SamfForm';
import { SamfError, SamfForm } from '~/Forms/SamfForm';
import { SamfFormField } from '~/Forms/SamfFormField';
import { getOrganizations, postRecruitment, putRecruitment } from '~/api';
import { OrganizationDto, RecruitmentDto } from '~/dto';
Expand All @@ -24,8 +24,18 @@ type FormType = {
reprioritization_deadline_for_applicant: string;
reprioritization_deadline_for_groups: string;
organization: number;
promo_media: string;
};

function youtubeLinkValidator(state: FormType): SamfError {
Copy link
Member

Choose a reason for hiding this comment

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

Anbefaler å holde komponentfilen ren. Kan flyttes til ./utils.ts

const link = state.promo_media;
const regex = /(youtu.*be.*)\/(watch\?v=|embed\/|v|shorts|)(.*?((?=[&#?])|$))/;
if (link && !link.match(regex)) {
return 'Not valid youtbue link';
}
return true;
}

export function RecruitmentFormAdminPage() {
const { t } = useTranslation();
const navigate = useNavigate();
Expand Down Expand Up @@ -190,6 +200,14 @@ export function RecruitmentFormAdminPage() {
required={true}
/>
</div>
<div className={styles.row}>
<SamfFormField
field="promo_media"
type="text"
label={t(KEY.promo_media)}
validator={youtubeLinkValidator}
/>
</div>
</SamfForm>
</div>
</AdminPageLayout>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ export type RecruitmentDto = {
organization: number;
separate_positions?: RecruitmentSeparatePositionDto[];
recruitment_progress?: number;
promo_media?: string;
};

export type RecruitmentSeparatePositionDto = {
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ export const KEY = {
recrutment_default_application_letter: 'recrutment_default_application_letter',
reprioritization_deadline_for_groups: 'reprioritization_deadline_for_groups',
max_applications: 'max_applications',
promo_media: 'promo_video',
Comment on lines 295 to +296
Copy link
Contributor

Choose a reason for hiding this comment

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

feil navngivning, se toppen av filen

recruitment_norwegian_applicants_only: 'recruitment_norwegian_applicants_only',
reprioritization_deadline_for_applicant: 'reprioritization_deadline_for_applicant',
recruitment_show_unprocessed_applicants: 'recruitment_show_unprocessed_applicants',
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/i18n/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ export const nb: Record<KeyValues, string> = {
[KEY.recrutment_default_application_letter]: 'Standard søknadstekst',
[KEY.reprioritization_deadline_for_groups]: 'Flaggefrist',
[KEY.max_applications]: 'Maks søknader per bruker',
[KEY.promo_media]: 'Promo video',
[KEY.recruitment_norwegian_applicants_only]: 'Kun norsktalende søkere',
[KEY.reprioritization_deadline_for_applicant]: 'Omprioriteringsfrist',
[KEY.recruitment_show_unprocessed_applicants]: 'Vis ubehandlede søkere',
Expand Down Expand Up @@ -692,6 +693,7 @@ export const en: Record<KeyValues, string> = {
[KEY.recrutment_default_application_letter]: 'Default application letter',
[KEY.reprioritization_deadline_for_groups]: 'Group reprioritization deadline',
[KEY.max_applications]: 'Max applications per user',
[KEY.promo_media]: "Promo Video",
Comment on lines 695 to +696
Copy link
Contributor

Choose a reason for hiding this comment

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

liten V?

[KEY.reprioritization_deadline_for_applicant]: 'Reprioritization deadline',
[KEY.recruitment_show_unprocessed_applicants]: 'Show unprocessed applicants',
[KEY.recruitment_show_all_applicants]: 'Show all applicants',
Expand Down
Loading