Auto commit: 2025-08-16T18:41:32.498Z
This commit is contained in:
parent
47a01dc1ff
commit
c481139899
File diff suppressed because one or more lines are too long
@ -0,0 +1,33 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: async (queryInterface, Sequelize) => {
|
||||||
|
// Add date field
|
||||||
|
await queryInterface.addColumn('bookings', 'date', {
|
||||||
|
type: Sequelize.DATEONLY,
|
||||||
|
allowNull: false,
|
||||||
|
});
|
||||||
|
// Add hour enum field (08:00 to 16:00)
|
||||||
|
await queryInterface.addColumn('bookings', 'hour', {
|
||||||
|
type: Sequelize.ENUM(
|
||||||
|
'08:00','09:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00'
|
||||||
|
),
|
||||||
|
allowNull: false,
|
||||||
|
});
|
||||||
|
// Add slot enum field (00, 20, 40)
|
||||||
|
await queryInterface.addColumn('bookings', 'slot', {
|
||||||
|
type: Sequelize.ENUM('00','20','40'),
|
||||||
|
allowNull: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: async (queryInterface, Sequelize) => {
|
||||||
|
// Remove newly added columns
|
||||||
|
await queryInterface.removeColumn('bookings', 'slot');
|
||||||
|
await queryInterface.removeColumn('bookings', 'hour');
|
||||||
|
await queryInterface.removeColumn('bookings', 'date');
|
||||||
|
// Drop enum types (Postgres)
|
||||||
|
await queryInterface.sequelize.query('DROP TYPE IF EXISTS "enum_bookings_hour";');
|
||||||
|
await queryInterface.sequelize.query('DROP TYPE IF EXISTS "enum_bookings_slot";');
|
||||||
|
},
|
||||||
|
};
|
||||||
@ -49,6 +49,23 @@ module.exports = function (sequelize, DataTypes) {
|
|||||||
allowNull: true,
|
allowNull: true,
|
||||||
unique: true,
|
unique: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// New fields for inspection booking
|
||||||
|
date: {
|
||||||
|
type: DataTypes.DATEONLY,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
hour: {
|
||||||
|
type: DataTypes.ENUM(
|
||||||
|
'08:00','09:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00'
|
||||||
|
),
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
slot: {
|
||||||
|
type: DataTypes.ENUM('00','20','40'),
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
timestamps: true,
|
timestamps: true,
|
||||||
|
|||||||
@ -1,19 +1,33 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import BaseButton from '../../../BaseButton';
|
import BaseButton from '../../../BaseButton';
|
||||||
|
|
||||||
const HeroTextCenter = ({ mainText, subTitle, buttonText, textSecondary }) => (
|
interface HeroTextCenterProps {
|
||||||
<div className='relative w-full h-auto flex items-center justify-center text-center'>
|
mainText: string;
|
||||||
<div className='absolute top-0 mt-2 left-0 w-full h-2/3 bg-gradient-to-b from-blue-700 to-transparent filter blur-lg opacity-25 z-0'></div>
|
subTitle: string;
|
||||||
<div className='relative container z-10 my-40 p-8 md:p-16 '>
|
buttonText: string;
|
||||||
<h1 className='text-4xl sm:text-5xl lg:text-6xl font-bold mb-4 '>
|
buttonLink: string;
|
||||||
|
textSecondary?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HeroTextCenter: React.FC<HeroTextCenterProps> = ({
|
||||||
|
mainText,
|
||||||
|
subTitle,
|
||||||
|
buttonText,
|
||||||
|
buttonLink,
|
||||||
|
textSecondary = '',
|
||||||
|
}) => (
|
||||||
|
<div className="relative w-full h-auto flex items-center justify-center text-center">
|
||||||
|
<div className="absolute top-0 mt-2 left-0 w-full h-2/3 bg-gradient-to-b from-blue-700 to-transparent filter blur-lg opacity-25 z-0" />
|
||||||
|
<div className="relative container z-10 my-40 p-8 md:p-16">
|
||||||
|
<h1 className="text-4xl sm:text-5xl lg:text-6xl font-bold mb-4">
|
||||||
{mainText}
|
{mainText}
|
||||||
</h1>
|
</h1>
|
||||||
<p className={`text-sm mb-8 ${textSecondary}`}>{subTitle}</p>
|
<p className={`text-sm mb-8 ${textSecondary}`}>{subTitle}</p>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
href='/login'
|
href={buttonLink}
|
||||||
label={`${buttonText}`}
|
label={buttonText}
|
||||||
color='info'
|
color="info"
|
||||||
className=' px-4 sm:px-6 py-2 '
|
className="px-4 sm:px-6 py-2"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -36,7 +36,8 @@ import moment from 'moment';
|
|||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
date: '',
|
date: '',
|
||||||
timeSlot: '',
|
hour: '08:00',
|
||||||
|
slot: '00',
|
||||||
vehiclenumber: '',
|
vehiclenumber: '',
|
||||||
phone: '',
|
phone: '',
|
||||||
email: '',
|
email: '',
|
||||||
|
|||||||
143
frontend/src/pages/bookings/bookings-new.tsx.temp
Normal file
143
frontend/src/pages/bookings/bookings-new.tsx.temp
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
import {
|
||||||
|
mdiAccount,
|
||||||
|
mdiChartTimelineVariant,
|
||||||
|
mdiMail,
|
||||||
|
mdiUpload,
|
||||||
|
} from '@mdi/js';
|
||||||
|
import { holidays } from '../../config';
|
||||||
|
import Head from 'next/head';
|
||||||
|
import React, { ReactElement } from 'react';
|
||||||
|
import CardBox from '../../components/CardBox';
|
||||||
|
import LayoutGuest from '../../layouts/Guest';
|
||||||
|
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 FormCheckRadio from '../../components/FormCheckRadio';
|
||||||
|
import FormCheckRadioGroup from '../../components/FormCheckRadioGroup';
|
||||||
|
import FormFilePicker from '../../components/FormFilePicker';
|
||||||
|
import FormImagePicker from '../../components/FormImagePicker';
|
||||||
|
import { SwitchField } from '../../components/SwitchField';
|
||||||
|
|
||||||
|
import { SelectField } from '../../components/SelectField';
|
||||||
|
import { SelectFieldMany } from '../../components/SelectFieldMany';
|
||||||
|
import { RichTextField } from '../../components/RichTextField';
|
||||||
|
|
||||||
|
import { create } from '../../stores/bookings/bookingsSlice';
|
||||||
|
import { useAppDispatch } from '../../stores/hooks';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
const initialValues = {
|
||||||
|
date: '',
|
||||||
|
hour: '08:00',
|
||||||
|
slot: '00',
|
||||||
|
vehiclenumber: '',
|
||||||
|
phone: '',
|
||||||
|
email: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
const BookingsNew = () => {
|
||||||
|
const router = useRouter();
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
// get from url params
|
||||||
|
const { dateRangeStart, dateRangeEnd } = router.query;
|
||||||
|
|
||||||
|
const handleSubmit = async (data) => {
|
||||||
|
await dispatch(create(data));
|
||||||
|
await router.push('/bookings/bookings-list');
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Head>
|
||||||
|
<title>{getPageTitle('New Item')}</title>
|
||||||
|
</Head>
|
||||||
|
<SectionMain>
|
||||||
|
<SectionTitleLineWithButton
|
||||||
|
icon={mdiChartTimelineVariant}
|
||||||
|
title='New Item'
|
||||||
|
main
|
||||||
|
>
|
||||||
|
{''}
|
||||||
|
</SectionTitleLineWithButton>
|
||||||
|
<CardBox>
|
||||||
|
{() => (
|
||||||
|
<Form>
|
||||||
|
<FormField label="Date">
|
||||||
|
<Field type="date" name="date" />
|
||||||
|
</FormField>
|
||||||
|
<FormField label="Hour">
|
||||||
|
<Field
|
||||||
|
component={SelectField}
|
||||||
|
name="hour"
|
||||||
|
options={[
|
||||||
|
{ label: '08:00', value: '08:00' },
|
||||||
|
{ label: '09:00', value: '09:00' },
|
||||||
|
{ label: '10:00', value: '10:00' },
|
||||||
|
{ label: '11:00', value: '11:00' },
|
||||||
|
{ label: '12:00', value: '12:00' },
|
||||||
|
{ label: '13:00', value: '13:00' },
|
||||||
|
{ label: '14:00', value: '14:00' },
|
||||||
|
{ label: '15:00', value: '15:00' },
|
||||||
|
{ label: '16:00', value: '16:00' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</FormField>
|
||||||
|
<FormField label="Slot">
|
||||||
|
<Field
|
||||||
|
component={SelectField}
|
||||||
|
name="slot"
|
||||||
|
options={[
|
||||||
|
{ label: '00', value: '00' },
|
||||||
|
{ label: '20', value: '20' },
|
||||||
|
{ label: '40', value: '40' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</FormField>
|
||||||
|
<FormField label="Vehicle Number">
|
||||||
|
<Field name="vehiclenumber" placeholder="Vehicle Number" />
|
||||||
|
</FormField>
|
||||||
|
<FormField label="Phone">
|
||||||
|
<Field name="phone" placeholder="Your phone" />
|
||||||
|
</FormField>
|
||||||
|
<FormField label="Email">
|
||||||
|
<Field name="email" placeholder="Your email" />
|
||||||
|
</FormField>
|
||||||
|
<BaseDivider />
|
||||||
|
<BaseButtons>
|
||||||
|
<BaseButton type="submit" color="info" label="Submit" />
|
||||||
|
<BaseButton type="reset" color="info" outline label="Reset" />
|
||||||
|
<BaseButton
|
||||||
|
type="button"
|
||||||
|
color="danger"
|
||||||
|
outline
|
||||||
|
label="Cancel"
|
||||||
|
onClick={() => router.push('/')}
|
||||||
|
/>
|
||||||
|
</BaseButtons>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Formik>
|
||||||
|
</Formik>
|
||||||
|
</CardBox>
|
||||||
|
</SectionMain>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
BookingsNew.getLayout = function getLayout(page: ReactElement) {
|
||||||
|
return (
|
||||||
|
<LayoutGuest>
|
||||||
|
{page}
|
||||||
|
</LayoutGuest>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BookingsNew;
|
||||||
Loading…
x
Reference in New Issue
Block a user