39948-vm/frontend/src/pages/page_elements/page_elements-edit.tsx
2026-03-24 08:20:27 +04:00

254 lines
7.6 KiB
TypeScript

/**
* Edit Page Elements Page
* Cleaned up version with consolidated useEffect hooks
*/
import { mdiChartTimelineVariant } from '@mdi/js';
import Head from 'next/head';
import React, { ReactElement, useEffect, useState } from 'react';
import CardBox from '../../components/CardBox';
import LayoutAuthenticated from '../../layouts/Authenticated';
import SectionMain from '../../components/SectionMain';
import SectionTitleLineWithButton from '../../components/SectionTitleLineWithButton';
import { getPageTitle } from '../../config';
import { Field, Form, Formik } from 'formik';
import FormField from '../../components/FormField';
import BaseDivider from '../../components/BaseDivider';
import BaseButtons from '../../components/BaseButtons';
import BaseButton from '../../components/BaseButton';
import { SelectField } from '../../components/SelectField';
import { SwitchField } from '../../components/SwitchField';
import { update, fetch } from '../../stores/page_elements/page_elementsSlice';
import { useAppDispatch, useAppSelector } from '../../stores/hooks';
import { useRouter } from 'next/router';
import type { PageElement } from '../../types/entities';
interface FormValues {
page: unknown;
element_type: string;
name: string;
sort_order: string;
is_visible: boolean;
x_percent: string;
y_percent: string;
width_percent: string;
height_percent: string;
rotation_deg: string;
style_json: string;
content_json: string;
}
const initVals: FormValues = {
page: null,
element_type: '',
name: '',
sort_order: '',
is_visible: false,
x_percent: '',
y_percent: '',
width_percent: '',
height_percent: '',
rotation_deg: '',
style_json: '',
content_json: '',
};
const EditPage_elementsPage = () => {
const router = useRouter();
const dispatch = useAppDispatch();
const [initialValues, setInitialValues] = useState<FormValues>(initVals);
const pageElementsState = useAppSelector((state) => state.page_elements);
const page_elements = pageElementsState.page_elements as
| PageElement
| PageElement[]
| undefined;
const pageElement = Array.isArray(page_elements)
? page_elements[0]
: page_elements;
const { id } = router.query;
const idStr = Array.isArray(id) ? id[0] : id;
// Fetch entity data
useEffect(() => {
if (idStr) {
dispatch(fetch({ id: idStr }));
}
}, [idStr, dispatch]);
// Sync form values with fetched data (consolidated from redundant useEffects)
useEffect(() => {
if (pageElement && typeof pageElement === 'object') {
const newInitialVal = { ...initVals };
const pageElementRecord = pageElement as unknown as Record<
string,
unknown
>;
(Object.keys(initVals) as Array<keyof FormValues>).forEach((key) => {
if (key in pageElementRecord) {
(newInitialVal as Record<string, unknown>)[key] =
pageElementRecord[key];
}
});
setInitialValues(newInitialVal);
}
}, [pageElement]);
const handleSubmit = async (data: FormValues) => {
if (idStr) {
await dispatch(
update({ id: idStr, data: data as unknown as Partial<PageElement> }),
);
await router.push('/page_elements/page_elements-list');
}
};
return (
<>
<Head>
<title>{getPageTitle('Edit page_elements')}</title>
</Head>
<SectionMain>
<SectionTitleLineWithButton
icon={mdiChartTimelineVariant}
title='Edit page_elements'
main
>
{''}
</SectionTitleLineWithButton>
<CardBox>
<Formik
enableReinitialize
initialValues={initialValues}
onSubmit={(values) => handleSubmit(values)}
>
<Form>
<FormField label='Page' labelFor='page'>
<Field
name='page'
id='page'
component={SelectField}
options={initialValues.page}
itemRef='tour_pages'
showField='name'
/>
</FormField>
<FormField label='Element Type' labelFor='element_type'>
<Field name='element_type' id='element_type' component='select'>
<option value='nav_button'>nav_button</option>
<option value='spot'>spot</option>
<option value='description'>description</option>
<option value='tooltip'>tooltip</option>
<option value='gallery'>gallery</option>
<option value='carousel'>carousel</option>
<option value='logo'>logo</option>
<option value='video_player'>video_player</option>
<option value='popup'>popup</option>
</Field>
</FormField>
<FormField label='Name'>
<Field name='name' placeholder='Name' />
</FormField>
<FormField label='Sort Order'>
<Field
type='number'
name='sort_order'
placeholder='Sort Order'
/>
</FormField>
<FormField label='Is Visible' labelFor='is_visible'>
<Field
name='is_visible'
id='is_visible'
component={SwitchField}
/>
</FormField>
<FormField label='X (%)'>
<Field type='number' name='x_percent' placeholder='X (%)' />
</FormField>
<FormField label='Y (%)'>
<Field type='number' name='y_percent' placeholder='Y (%)' />
</FormField>
<FormField label='Width (%)'>
<Field
type='number'
name='width_percent'
placeholder='Width (%)'
/>
</FormField>
<FormField label='Height (%)'>
<Field
type='number'
name='height_percent'
placeholder='Height (%)'
/>
</FormField>
<FormField label='Rotation (deg)'>
<Field
type='number'
name='rotation_deg'
placeholder='Rotation (deg)'
/>
</FormField>
<FormField label='Style JSON' hasTextareaHeight>
<Field
name='style_json'
as='textarea'
placeholder='Style JSON'
/>
</FormField>
<FormField label='Content JSON' hasTextareaHeight>
<Field
name='content_json'
as='textarea'
placeholder='Content JSON'
/>
</FormField>
<BaseDivider />
<BaseButtons>
<BaseButton type='submit' color='info' label='Submit' />
<BaseButton type='reset' color='info' outline label='Reset' />
<BaseButton
type='reset'
color='danger'
outline
label='Cancel'
onClick={() =>
router.push('/page_elements/page_elements-list')
}
/>
</BaseButtons>
</Form>
</Formik>
</CardBox>
</SectionMain>
</>
);
};
EditPage_elementsPage.getLayout = function getLayout(page: ReactElement) {
return (
<LayoutAuthenticated permission='UPDATE_PAGE_ELEMENTS'>
{page}
</LayoutAuthenticated>
);
};
export default EditPage_elementsPage;