Skip to content

Commit

Permalink
update gang admin
Browse files Browse the repository at this point in the history
  • Loading branch information
magsyg committed Mar 25, 2024
1 parent 5488791 commit eff8517
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 19 deletions.
14 changes: 11 additions & 3 deletions frontend/src/Components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Icon } from '@iconify/react';
import { default as classNames, default as classnames } from 'classnames';
import { ChangeEvent, ReactElement } from 'react';
import { ChangeEvent, ReactElement, useEffect, useState } from 'react';
import styles from './Dropdown.module.scss';
import { init } from 'i18next';

export type DropDownOption<T> = {
label: string;
Expand Down Expand Up @@ -29,13 +30,20 @@ export function Dropdown<T>({
disabled = false,
error,
}: DropdownProps<T>) {
const [startVal, setStartValue] = useState<number>(-1);
/**
* Handles the raw change event from <option>
* The raw value choice is an index where -1 is reserved for
* the empty/default option. Depending on the index selected
* the onChange callback is provided with the respective DropDownOption
* @param e Standard onChange HTML event for dropdown
*/
useEffect(() => {
if (options.length > 0 && initialValue !== undefined) {
setStartValue(initialValue !== undefined ? options.map((e) => e.value).indexOf(initialValue) : -1);
}
}, [initialValue, options]);

function handleChange(e?: ChangeEvent<HTMLSelectElement>) {
const choice = (e?.currentTarget.value ?? 0) as number;
if (choice >= 0 && choice <= options.length) {
Expand All @@ -51,12 +59,12 @@ export function Dropdown<T>({
className={classNames(styles.samf_select, error && styles.error)}
onChange={handleChange}
disabled={disabled}
defaultValue={initialValue !== undefined ? options.map((e) => e.value).indexOf(initialValue) : -1}
defaultValue={startVal}
>
{defaultValue ? <option value={-1}>{defaultValue.label}</option> : <option value={-1}></option>}
{options.map((opt, index) => {
return (
<option value={index} key={index}>
<option value={index} key={index} selected={index == startVal}>
{opt.label}
</option>
);
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/Forms/SamfFormFieldTypes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export type SamfFormFieldArgs = {
error: string | boolean; // True or string message if error, false or undefined if OK
label?: string; // Text label above the input
// Custom args for options type
defaultOption?: DropDownOption<unknown>;
defaultOption?: unknown;
options?: DropDownOption<unknown>[];
props?: FieldProps;
};
Expand Down Expand Up @@ -148,7 +148,7 @@ function makeOptionsInput(args: SamfFormFieldArgs) {
<Dropdown
{...(args.props as DropdownProps<number | string>)}
key={args.field}
defaultValue={args.defaultOption}
initialValue={args.value}
options={args.options}
onChange={args.onChange}
label={args.label}
Expand Down
91 changes: 77 additions & 14 deletions frontend/src/PagesAdmin/GangsFormAdminPage/GangsFormAdminPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,52 @@ import { useParams } from 'react-router-dom';
import { toast } from 'react-toastify';
import { SamfForm } from '~/Forms/SamfForm';
import { SamfFormField } from '~/Forms/SamfFormField';
import { getGang } from '~/api';
import { GangDto } from '~/dto';
import { getGang, postGang, putGang, getGangList, getInformationPages } from '~/api';
import { DropDownOption } from '~/Components/Dropdown/Dropdown';
import { GangDto, GangTypeDto, InformationPageDto } from '~/dto';
import { useCustomNavigate } from '~/hooks';
import { STATUS } from '~/http_status_codes';
import { KEY } from '~/i18n/constants';
import { ROUTES } from '~/routes';
import { AdminPageLayout } from '../AdminPageLayout/AdminPageLayout';
import styles from './GangsFormAdminPage.module.scss';
import { lowerCapitalize } from '~/utils';
import { dbT, lowerCapitalize } from '~/utils';

export function GangsFormAdminPage() {
const navigate = useCustomNavigate();
const [showSpinner, setShowSpinner] = useState<boolean>(true);
const { t } = useTranslation();

const [externalErrors, setExternalErrors] = useState<object>({});
// If form has a id, check if it exists, and then load that item.
const { id } = useParams();
const [gang, setGang] = useState<Partial<GangDto>>({});

const [gangTypeOptions, setGangTypeOptions] = useState<DropDownOption<number>[]>([]);
const [infoPageOptions, setInfoPageOptions] = useState<DropDownOption<string>[]>([]);
//TODO add permissions on render

useEffect(() => {
getGangList().then((data) => {
setGangTypeOptions(
data.map(
(gangType: GangTypeDto) =>
({
label: dbT(gangType, 'title'),
value: gangType.id,
}) as DropDownOption<number>,
),
);
});
getInformationPages().then((data) => {
setInfoPageOptions(
data.map(
(infoPage: InformationPageDto) =>
({
label: dbT(infoPage, 'title'),
value: infoPage.slug_field,
}) as DropDownOption<string>,
),
);
});
if (id) {
getGang(id)
.then((gang) => {
Expand All @@ -44,27 +68,55 @@ export function GangsFormAdminPage() {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [id]);

const initialData: Partial<GangDto> = {
name_nb: gang?.name_nb,
name_en: gang?.name_en,
abbreviation: gang?.abbreviation,
webpage: gang?.webpage,
gang_type: gang?.gang_type,
info_page: gang?.info_page,
logo: gang?.logo,
};

function handleOnSubmit(data: GangDto) {
setExternalErrors({});
if (id) {
// TODO patch
// Update page.
putGang(id, data)
.then(() => {
toast.success(t(KEY.common_update_successful));
})
.catch((error) => {
toast.error(t(KEY.common_something_went_wrong));
setExternalErrors(error.response.data);
});
navigate({ url: ROUTES.frontend.admin_gangs });
} else {
// TODO post
// Post new page.
postGang(data)
.then(() => {
navigate({ url: ROUTES.frontend.admin_gangs });
toast.success(t(KEY.common_creation_successful));
})
.catch((error) => {
toast.error(t(KEY.common_something_went_wrong));
setExternalErrors(error.response.data);
});
}
alert('TODO');
console.log(JSON.stringify(data));
}

const submitText = id ? t(KEY.common_save) : lowerCapitalize(`${t(KEY.common_create)} ${t(KEY.common_gang)}`);
const title = id ? t(KEY.common_edit) : lowerCapitalize(`${t(KEY.common_create)} ${t(KEY.common_gang)}`);

return (
<AdminPageLayout title={title} loading={showSpinner}>
<SamfForm
initialData={gang}
<SamfForm<GangDto>
initialData={initialData}
onSubmit={handleOnSubmit}
submitText={submitText}
validateOnInit={id !== undefined}
devMode={false}
externalErrors={externalErrors}
>
<div className={styles.row}>
<SamfFormField
Expand All @@ -90,9 +142,20 @@ export function GangsFormAdminPage() {
label={lowerCapitalize(`${t(KEY.admin_gangsadminpage_webpage)}`)}
/>
</div>
{/* TODO fetch options */}
{/* <SamfFormField field="gang_type" type="options" label={`${t(KEY.webpage)}`} /> */}
{/* <SamfFormField field="info_page" type="options" label={`${t(KEY.information_page)}`} /> */}
<div className={styles.row}>
<SamfFormField
field="gang_type"
type="options"
options={gangTypeOptions}
label={lowerCapitalize(`${t(KEY.common_gang)} ${t(KEY.common_type)}`)}
/>
<SamfFormField
field="info_page"
type="options"
options={infoPageOptions}
label={lowerCapitalize(`${t(KEY.information_page_short)}`)}
/>
</div>
</SamfForm>
</AdminPageLayout>
);
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 @@ -46,6 +46,7 @@ export const KEY = {

// No category:
common_to: 'common_to',
common_type: 'common_type',
common_price: 'common_price',
common_buy: 'common_buy',
common_here: 'common_here',
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 @@ -35,6 +35,7 @@ export const nb: Record<KeyValues, string> = {

// Other common
[KEY.common_to]: 'Til',
[KEY.common_type]: 'Type',
[KEY.common_price]: 'Pris',
[KEY.common_buy]: 'Kjøp',
[KEY.common_from]: 'Fra',
Expand Down Expand Up @@ -322,6 +323,7 @@ export const en: Record<KeyValues, string> = {

// No category:
[KEY.common_to]: 'To',
[KEY.common_type]: 'Type',
[KEY.common_price]: 'Price',
[KEY.common_buy]: 'Buy',
[KEY.common_here]: 'here',
Expand Down

0 comments on commit eff8517

Please sign in to comment.