update to use schema
This commit is contained in:
parent
701854e633
commit
16addfb9d0
6 changed files with 86 additions and 35 deletions
|
@ -41,7 +41,7 @@ const ASFundingSection: React.FC<ASFundingSectionProps> = ({ formData, onDataCha
|
||||||
// Handle multiple invoice files upload
|
// Handle multiple invoice files upload
|
||||||
const handleMultipleInvoiceFilesChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleMultipleInvoiceFilesChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
if (e.target.files && e.target.files.length > 0) {
|
if (e.target.files && e.target.files.length > 0) {
|
||||||
const files = Array.from(e.target.files);
|
const files = Array.from(e.target.files) as File[];
|
||||||
|
|
||||||
// Check file sizes
|
// Check file sizes
|
||||||
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB limit per file
|
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB limit per file
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { Update } from '../../../scripts/pocketbase/Update';
|
||||||
import { FileManager } from '../../../scripts/pocketbase/FileManager';
|
import { FileManager } from '../../../scripts/pocketbase/FileManager';
|
||||||
import { Get } from '../../../scripts/pocketbase/Get';
|
import { Get } from '../../../scripts/pocketbase/Get';
|
||||||
import type { EventRequest } from '../../../schemas/pocketbase';
|
import type { EventRequest } from '../../../schemas/pocketbase';
|
||||||
|
import { EventRequestStatus } from '../../../schemas/pocketbase';
|
||||||
|
|
||||||
// Form sections
|
// Form sections
|
||||||
import PRSection from './PRSection';
|
import PRSection from './PRSection';
|
||||||
|
@ -238,7 +239,7 @@ const EventRequestForm: React.FC = () => {
|
||||||
vendor: formData.invoiceData.vendor
|
vendor: formData.invoiceData.vendor
|
||||||
},
|
},
|
||||||
// Set the initial status to "submitted"
|
// Set the initial status to "submitted"
|
||||||
status: "submitted",
|
status: EventRequestStatus.SUBMITTED,
|
||||||
};
|
};
|
||||||
|
|
||||||
toast.loading('Creating event request record...', { id: submittingToast });
|
toast.loading('Creating event request record...', { id: submittingToast });
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { motion } from 'framer-motion';
|
||||||
import type { EventRequestFormData } from './EventRequestForm';
|
import type { EventRequestFormData } from './EventRequestForm';
|
||||||
import type { InvoiceItem } from './InvoiceBuilder';
|
import type { InvoiceItem } from './InvoiceBuilder';
|
||||||
import type { EventRequest } from '../../../schemas/pocketbase';
|
import type { EventRequest } from '../../../schemas/pocketbase';
|
||||||
|
import { FlyerTypes, LogoOptions, EventRequestStatus } from '../../../schemas/pocketbase';
|
||||||
|
|
||||||
interface EventRequestFormPreviewProps {
|
interface EventRequestFormPreviewProps {
|
||||||
formData?: EventRequestFormData; // Optional prop to directly pass form data
|
formData?: EventRequestFormData; // Optional prop to directly pass form data
|
||||||
|
|
|
@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import type { EventRequestFormData } from './EventRequestForm';
|
import type { EventRequestFormData } from './EventRequestForm';
|
||||||
import type { EventRequest } from '../../../schemas/pocketbase';
|
import type { EventRequest } from '../../../schemas/pocketbase';
|
||||||
|
import { FlyerTypes, LogoOptions } from '../../../schemas/pocketbase';
|
||||||
|
|
||||||
// Animation variants
|
// Animation variants
|
||||||
const itemVariants = {
|
const itemVariants = {
|
||||||
|
@ -19,24 +20,24 @@ const itemVariants = {
|
||||||
|
|
||||||
// Flyer type options
|
// Flyer type options
|
||||||
const FLYER_TYPES = [
|
const FLYER_TYPES = [
|
||||||
{ value: 'digital_with_social', label: 'Digital flyer (with social media advertising: Facebook, Instagram, Discord)' },
|
{ value: FlyerTypes.DIGITAL_WITH_SOCIAL, label: 'Digital flyer (with social media advertising: Facebook, Instagram, Discord)' },
|
||||||
{ value: 'digital_no_social', label: 'Digital flyer (with NO social media advertising)' },
|
{ value: FlyerTypes.DIGITAL_NO_SOCIAL, label: 'Digital flyer (with NO social media advertising)' },
|
||||||
{ value: 'physical_with_advertising', label: 'Physical flyer (with advertising)' },
|
{ value: FlyerTypes.PHYSICAL_WITH_ADVERTISING, label: 'Physical flyer (with advertising)' },
|
||||||
{ value: 'physical_no_advertising', label: 'Physical flyer (with NO advertising)' },
|
{ value: FlyerTypes.PHYSICAL_NO_ADVERTISING, label: 'Physical flyer (with NO advertising)' },
|
||||||
{ value: 'newsletter', label: 'Newsletter (IEEE, ECE, IDEA)' },
|
{ value: FlyerTypes.NEWSLETTER, label: 'Newsletter (IEEE, ECE, IDEA)' },
|
||||||
{ value: 'other', label: 'Other' }
|
{ value: FlyerTypes.OTHER, label: 'Other' }
|
||||||
];
|
];
|
||||||
|
|
||||||
// Logo options
|
// Logo options
|
||||||
const LOGO_OPTIONS = [
|
const LOGO_OPTIONS = [
|
||||||
{ value: 'IEEE', label: 'IEEE' },
|
{ value: LogoOptions.IEEE, label: 'IEEE' },
|
||||||
{ value: 'AS', label: 'AS (required if funded by AS)' },
|
{ value: LogoOptions.AS, label: 'AS (required if funded by AS)' },
|
||||||
{ value: 'HKN', label: 'HKN' },
|
{ value: LogoOptions.HKN, label: 'HKN' },
|
||||||
{ value: 'TESC', label: 'TESC' },
|
{ value: LogoOptions.TESC, label: 'TESC' },
|
||||||
{ value: 'PIB', label: 'PIB' },
|
{ value: LogoOptions.PIB, label: 'PIB' },
|
||||||
{ value: 'TNT', label: 'TNT' },
|
{ value: LogoOptions.TNT, label: 'TNT' },
|
||||||
{ value: 'SWE', label: 'SWE' },
|
{ value: LogoOptions.SWE, label: 'SWE' },
|
||||||
{ value: 'OTHER', label: 'OTHER (please upload transparent logo files)' }
|
{ value: LogoOptions.OTHER, label: 'OTHER (please upload transparent logo files)' }
|
||||||
];
|
];
|
||||||
|
|
||||||
// Format options
|
// Format options
|
||||||
|
@ -76,7 +77,7 @@ const PRSection: React.FC<PRSectionProps> = ({ formData, onDataChange }) => {
|
||||||
// Handle file upload for other logos
|
// Handle file upload for other logos
|
||||||
const handleLogoFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleLogoFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
if (e.target.files && e.target.files.length > 0) {
|
if (e.target.files && e.target.files.length > 0) {
|
||||||
const newFiles = Array.from(e.target.files);
|
const newFiles = Array.from(e.target.files) as File[];
|
||||||
setOtherLogoFiles(newFiles);
|
setOtherLogoFiles(newFiles);
|
||||||
onDataChange({ other_logos: newFiles });
|
onDataChange({ other_logos: newFiles });
|
||||||
}
|
}
|
||||||
|
@ -113,7 +114,7 @@ const PRSection: React.FC<PRSectionProps> = ({ formData, onDataChange }) => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Other flyer type input */}
|
{/* Other flyer type input */}
|
||||||
{formData.flyer_type.includes('other') && (
|
{formData.flyer_type.includes(FlyerTypes.OTHER) && (
|
||||||
<div className="mt-3 pl-7">
|
<div className="mt-3 pl-7">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -129,9 +130,9 @@ const PRSection: React.FC<PRSectionProps> = ({ formData, onDataChange }) => {
|
||||||
|
|
||||||
{/* Advertising start date */}
|
{/* Advertising start date */}
|
||||||
{formData.flyer_type.some(type =>
|
{formData.flyer_type.some(type =>
|
||||||
type === 'digital_with_social' ||
|
type === FlyerTypes.DIGITAL_WITH_SOCIAL ||
|
||||||
type === 'physical_with_advertising' ||
|
type === FlyerTypes.PHYSICAL_WITH_ADVERTISING ||
|
||||||
type === 'newsletter'
|
type === FlyerTypes.NEWSLETTER
|
||||||
) && (
|
) && (
|
||||||
<motion.div variants={itemVariants} className="form-control">
|
<motion.div variants={itemVariants} className="form-control">
|
||||||
<label className="label">
|
<label className="label">
|
||||||
|
@ -169,7 +170,7 @@ const PRSection: React.FC<PRSectionProps> = ({ formData, onDataChange }) => {
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
{/* Logo file upload */}
|
{/* Logo file upload */}
|
||||||
{formData.required_logos.includes('OTHER') && (
|
{formData.required_logos.includes(LogoOptions.OTHER) && (
|
||||||
<motion.div variants={itemVariants} className="form-control">
|
<motion.div variants={itemVariants} className="form-control">
|
||||||
<label className="label">
|
<label className="label">
|
||||||
<span className="label-text font-medium">Please share your logo files here</span>
|
<span className="label-text font-medium">Please share your logo files here</span>
|
||||||
|
|
|
@ -74,12 +74,12 @@ export interface EventRequest extends BaseRecord {
|
||||||
end_date_time: string;
|
end_date_time: string;
|
||||||
event_description: string;
|
event_description: string;
|
||||||
flyers_needed: boolean;
|
flyers_needed: boolean;
|
||||||
flyer_type?: string[];
|
flyer_type?: string[]; // digital_with_social, digital_no_social, physical_with_advertising, physical_no_advertising, newsletter, other
|
||||||
other_flyer_type?: string;
|
other_flyer_type?: string;
|
||||||
flyer_advertising_start_date?: string;
|
flyer_advertising_start_date?: string;
|
||||||
flyer_additional_requests?: string;
|
flyer_additional_requests?: string;
|
||||||
photography_needed: boolean;
|
photography_needed: boolean;
|
||||||
required_logos?: string[];
|
required_logos?: string[]; // IEEE, AS, HKN, TESC, PIB, TNT, SWE, OTHER
|
||||||
other_logos?: string[];
|
other_logos?: string[];
|
||||||
advertising_format?: string;
|
advertising_format?: string;
|
||||||
will_or_have_room_booking?: boolean;
|
will_or_have_room_booking?: boolean;
|
||||||
|
@ -89,9 +89,10 @@ export interface EventRequest extends BaseRecord {
|
||||||
food_drinks_being_served: boolean;
|
food_drinks_being_served: boolean;
|
||||||
itemized_invoice?: string; // JSON string
|
itemized_invoice?: string; // JSON string
|
||||||
invoice?: string;
|
invoice?: string;
|
||||||
|
invoice_files?: string[]; // Array of invoice file IDs
|
||||||
needs_graphics?: boolean;
|
needs_graphics?: boolean;
|
||||||
needs_as_funding?: boolean;
|
needs_as_funding?: boolean;
|
||||||
status: string;
|
status: "submitted" | "pending" | "completed" | "declined";
|
||||||
requested_user?: string;
|
requested_user?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +116,7 @@ export interface Log extends BaseRecord {
|
||||||
export interface Officer extends BaseRecord {
|
export interface Officer extends BaseRecord {
|
||||||
user: string; // Relation to User
|
user: string; // Relation to User
|
||||||
role: string;
|
role: string;
|
||||||
type: string; // e.g., "administrator"
|
type: "administrator" | "executive" | "general" | "honorary" | "past";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -195,3 +196,54 @@ export const Collections = {
|
||||||
RECEIPTS: "receipts",
|
RECEIPTS: "receipts",
|
||||||
SPONSORS: "sponsors",
|
SPONSORS: "sponsors",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flyer Type Options
|
||||||
|
* Constants for the flyer type options used in event requests
|
||||||
|
*/
|
||||||
|
export const FlyerTypes = {
|
||||||
|
DIGITAL_WITH_SOCIAL: "digital_with_social",
|
||||||
|
DIGITAL_NO_SOCIAL: "digital_no_social",
|
||||||
|
PHYSICAL_WITH_ADVERTISING: "physical_with_advertising",
|
||||||
|
PHYSICAL_NO_ADVERTISING: "physical_no_advertising",
|
||||||
|
NEWSLETTER: "newsletter",
|
||||||
|
OTHER: "other",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logo Options
|
||||||
|
* Constants for the logo options used in event requests
|
||||||
|
*/
|
||||||
|
export const LogoOptions = {
|
||||||
|
IEEE: "IEEE",
|
||||||
|
AS: "AS",
|
||||||
|
HKN: "HKN",
|
||||||
|
TESC: "TESC",
|
||||||
|
PIB: "PIB",
|
||||||
|
TNT: "TNT",
|
||||||
|
SWE: "SWE",
|
||||||
|
OTHER: "OTHER",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event Request Status Options
|
||||||
|
* Constants for the status options used in event requests
|
||||||
|
*/
|
||||||
|
export const EventRequestStatus = {
|
||||||
|
SUBMITTED: "submitted",
|
||||||
|
PENDING: "pending",
|
||||||
|
COMPLETED: "completed",
|
||||||
|
DECLINED: "declined",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Officer Type Options
|
||||||
|
* Constants for the officer type options
|
||||||
|
*/
|
||||||
|
export const OfficerTypes = {
|
||||||
|
ADMINISTRATOR: "administrator",
|
||||||
|
EXECUTIVE: "executive",
|
||||||
|
GENERAL: "general",
|
||||||
|
HONORARY: "honorary",
|
||||||
|
PAST: "past",
|
||||||
|
};
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
{
|
{
|
||||||
"extends": "astro/tsconfigs/strict",
|
"extends": "astro/tsconfigs/strict",
|
||||||
"include": [
|
"include": [".astro/types.d.ts", "**/*"],
|
||||||
".astro/types.d.ts",
|
"exclude": ["dist"],
|
||||||
"**/*"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
"jsxImportSource": "react"
|
"jsxImportSource": "react",
|
||||||
|
"esModuleInterop": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue