228 lines
9.9 KiB
TypeScript
228 lines
9.9 KiB
TypeScript
import { dateInputFormat, datetimeParse } from "@/utils/datetime";
|
|
import { FormStatus, ProjectActivity } from "@/types";
|
|
import { useForm } from "@inertiajs/react";
|
|
import { ActionIcon, Button, FileInput, Flex, Grid, Group, HoverCard, NumberInput, Paper, Radio, Select, SelectItem, SimpleGrid, Stack, Switch, Tabs, Text, TextInput, Textarea, Tooltip, rem } from "@mantine/core";
|
|
import { DatePickerInput } from "@mantine/dates";
|
|
import { useForm as useMantineForm } from "@mantine/form";
|
|
import { IconArrowIteration, IconDeviceFloppy, IconInfoCircle, IconListDetails, IconPlus, IconSeo, IconTimelineEventText, IconTrash, IconUserCheck } from "@tabler/icons-react";
|
|
import dayjs from "dayjs";
|
|
import { useEffect } from "react";
|
|
import { RichTextEditor } from '@mantine/tiptap';
|
|
import { useEditor } from '@tiptap/react';
|
|
import StarterKit from '@tiptap/starter-kit';
|
|
import Link from '@tiptap/extension-link';
|
|
|
|
interface Props {
|
|
activity?: ProjectActivity;
|
|
activityCategories?: any[];
|
|
status?: FormStatus;
|
|
projectId: number;
|
|
unassignedTickets?: any[];
|
|
formAction?: string;
|
|
formMethod?: 'post' | 'patch';
|
|
onSuccess?: () => void;
|
|
};
|
|
|
|
export default function ActivityForm({ activity, activityCategories, status, projectId, unassignedTickets,formAction, formMethod, onSuccess }: Props) {
|
|
|
|
// const activityCategoryOptions: SelectItem[] = activityCategories?.map((category) => ({
|
|
// label: category,
|
|
// value: category,
|
|
// }));
|
|
|
|
const ticketOptions: SelectItem[] = Object.entries(unassignedTickets).map(
|
|
([key, value], index) => ({
|
|
label: value,
|
|
value: key.toString(),
|
|
})
|
|
);
|
|
|
|
const { data, setData, post, patch, processing, errors, ...form } = useForm<{
|
|
task_description: string;
|
|
category: string | null;
|
|
estimated_completed_at: string | null;
|
|
activity_type: string;
|
|
// ticket_id: string | null;
|
|
notification_status: boolean;
|
|
}>({
|
|
task_description: activity?.task_description ?? '',
|
|
category: activity?.activity_type ?? null,
|
|
estimated_completed_at: activity?.estimated_completed_at ?? null,
|
|
activity_type: (!activity?.estimated_completed_at && !activity?.completed_at) ? 'report' : (activity?.estimated_completed_at && !activity?.completed_at) ? 'scheduled' : 'report',
|
|
// ticket_id: activity?.assignation?.ticket_id?.toString() ?? null,
|
|
notification_status: activity?.notification_status ?? false,
|
|
});
|
|
|
|
const editor = useEditor({
|
|
extensions: [StarterKit.configure({
|
|
bulletList: false,
|
|
orderedList: false,
|
|
}), Link],
|
|
content: activity?.task_description || '',
|
|
onUpdate({ editor }) {
|
|
setData('task_description', editor.getHTML());
|
|
},
|
|
});
|
|
|
|
useEffect(() => {
|
|
setData('task_description', activity?.task_description ?? '');
|
|
setData('category', activity?.activity_type ?? null);
|
|
setData('estimated_completed_at', activity?.estimated_completed_at ?? null);
|
|
setData('activity_type', (!activity?.estimated_completed_at && !activity?.completed_at) ? 'report' : (activity?.estimated_completed_at && !activity?.completed_at) ? 'scheduled' : 'report');
|
|
setData('notification_status', activity?.notification_status ?? false);
|
|
|
|
if (editor) {
|
|
editor.commands.setContent(activity?.task_description ?? '');
|
|
}
|
|
}, [activity, setData, editor]);
|
|
|
|
const handleSubmit = (e) => {
|
|
e.preventDefault();
|
|
const formStatus: FormStatus = status ?? 'create';
|
|
const actionUrl =
|
|
formAction ??
|
|
route('google-ads.accounts.activity.storeActivity', { id: projectId });
|
|
const method = formMethod ?? (formStatus === 'update' ? 'patch' : 'post');
|
|
const options = {
|
|
preserveScroll: true,
|
|
onSuccess: () => {
|
|
onSuccess?.();
|
|
},
|
|
};
|
|
|
|
if (method === 'patch') {
|
|
patch(actionUrl, { ...options, data });
|
|
return;
|
|
}
|
|
|
|
post(actionUrl, options);
|
|
//else if (status === 'update') {
|
|
// post(route('admin.project.activity.update', { id: activity?.id }), data);
|
|
// }
|
|
};
|
|
|
|
return (
|
|
<Grid>
|
|
<Grid.Col
|
|
md={12}
|
|
lg={12}
|
|
>
|
|
<form onSubmit={handleSubmit}>
|
|
<Stack>
|
|
<Stack>
|
|
<Radio.Group
|
|
name="activityType"
|
|
label="Activity Type"
|
|
value={data.activity_type}
|
|
onChange={(value) => setData("activity_type", value)}
|
|
withAsterisk
|
|
>
|
|
<Group mt="xs">
|
|
<Radio value="report" label="Report" />
|
|
<Radio value="scheduled" label="Scheduled" />
|
|
{/* <Radio value="customer_notes" label="Customer Notes" /> */}
|
|
</Group>
|
|
</Radio.Group>
|
|
{/* {data.activity_type != 'customer_notes' ? (
|
|
<Select
|
|
label={'Category'}
|
|
placeholder="Select One..."
|
|
data={activityCategoryOptions}
|
|
value={data.category}
|
|
onChange={(value) => setData('category', value ? value : '')}
|
|
error={errors.category}
|
|
required
|
|
searchable
|
|
clearable
|
|
/>
|
|
|
|
|
|
) : null} */}
|
|
|
|
<TextInput
|
|
placeholder="Insert Category"
|
|
label="Category"
|
|
required
|
|
withAsterisk
|
|
value={data.category ?? ''}
|
|
onChange={(event) => setData("category", event.target.value)}
|
|
error={errors.category}
|
|
/>
|
|
|
|
{data.activity_type == 'scheduled' ? (
|
|
<DatePickerInput
|
|
label={'Estimated Completion Date'}
|
|
// @ts-ignore
|
|
placeholder="Select a Date..."
|
|
valueFormat={dateInputFormat}
|
|
value={data.estimated_completed_at ? dayjs(data.estimated_completed_at).toDate() : null}
|
|
onChange={(value) => setData('estimated_completed_at', value ? dayjs(value).format(datetimeParse) : '')}
|
|
error={errors.estimated_completed_at}
|
|
required
|
|
/>
|
|
) : null}
|
|
|
|
<div>
|
|
<Text fw={500} mb={4}>
|
|
Description <Text span c="red">*</Text>
|
|
</Text>
|
|
|
|
<RichTextEditor editor={editor}>
|
|
<RichTextEditor.Toolbar sticky stickyOffset={60}>
|
|
<RichTextEditor.ControlsGroup>
|
|
<RichTextEditor.Bold />
|
|
<RichTextEditor.Italic />
|
|
<RichTextEditor.Link />
|
|
<RichTextEditor.Unlink />
|
|
</RichTextEditor.ControlsGroup>
|
|
</RichTextEditor.Toolbar>
|
|
|
|
<RichTextEditor.Content
|
|
style={{ minHeight: 300 }} // 👈 increase this
|
|
/>
|
|
</RichTextEditor>
|
|
|
|
{errors.description && (
|
|
<Text c="red" size="sm" mt={4}>
|
|
{errors.description}
|
|
</Text>
|
|
)}
|
|
</div>
|
|
|
|
{/* {data.activity_type != 'customer_notes' ? (
|
|
<Select
|
|
label={'Ticket Linkage'}
|
|
placeholder="Select One..."
|
|
data={ticketOptions}
|
|
value={data.ticket_id}
|
|
onChange={(value) => setData('ticket_id', value ? value : '')}
|
|
error={errors.ticket_id}
|
|
searchable
|
|
clearable
|
|
/>
|
|
) : null} */}
|
|
|
|
{/* <Switch
|
|
label={'Email Customer on Project Updates'}
|
|
checked={data.notification_status}
|
|
onChange={(e) => setData('notification_status', e.target.checked)}
|
|
error={errors.notification_status}
|
|
/> */}
|
|
|
|
</Stack>
|
|
|
|
<Button
|
|
type="submit"
|
|
leftIcon={(<IconDeviceFloppy />)}
|
|
disabled={processing}
|
|
>
|
|
Submit
|
|
</Button>
|
|
</Stack>
|
|
</form>
|
|
</Grid.Col>
|
|
</Grid>
|
|
)
|
|
|
|
}
|