inspiren-sem-tool/resources/js/pages/campaigns/account/edit.tsx
brian-inspiren 221d3f8173
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
feat: sem codebase
2026-05-21 11:28:03 +08:00

207 lines
8.4 KiB
TypeScript

import React from "react";
import AppLayout from "@/layouts/app-layout";
import { useForm } from "@inertiajs/react";
import {
Button,
Card,
Container,
Group,
Paper,
SimpleGrid,
Stack,
Text,
TextInput,
Select,
Title,
Divider,
} from "@mantine/core";
import { IconArrowLeft, IconDeviceFloppy } from "@tabler/icons-react";
import { Link } from "@inertiajs/react";
import { Client } from "@/types";
interface AssignmentRole {
id: number;
label: string;
field: "assigned_person" | "sales_person";
}
interface SelectOption {
value: string;
label: string;
}
interface AccountFormData {
name: string;
customer_id: string;
industry: string;
sql_acc_code: string;
assigned_person: string;
sales_person: string;
}
interface Props {
id: string;
client: Client;
clientAssignmentRoles: AssignmentRole[];
clientAssignments: Record<number, number | null>;
assignmentUsers: SelectOption[];
}
export default function Page({
id,
client,
clientAssignmentRoles,
clientAssignments,
assignmentUsers,
}: Props) {
const initialData: AccountFormData = {
name: client.name ?? "",
customer_id: client.customer_id ?? id,
industry: client.industry ?? "",
sql_acc_code: client.sql_acc_code ?? "",
assigned_person: "",
sales_person: "",
};
clientAssignmentRoles.forEach((role) => {
const value = clientAssignments?.[role.id];
initialData[role.field] = value ? String(value) : "";
});
const form = useForm<AccountFormData>(initialData);
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
form.transform((data) => ({
...data,
industry: data.industry || null,
sql_acc_code: data.sql_acc_code || null,
assigned_person: parseInt(data.assigned_person) || null,
sales_person: parseInt(data.sales_person) || null,
}));
form.post(route("google-ads.accounts.account.update", { id }));
};
return (
<AppLayout>
<Container size="lg" px="xs">
<Group position="apart" mb="md">
<Title order={2}>Edit Account</Title>
<Button
component={Link}
href={route("google-ads.accounts.show", { id })}
leftIcon={<IconArrowLeft size={16} />}
variant="outline"
>
Back to account
</Button>
</Group>
<Card withBorder shadow="sm" radius="md">
<form onSubmit={handleSubmit}>
<Stack spacing="lg">
<Card.Section>
<Stack spacing={4} px="md" py="sm">
<Text size="sm" color="dimmed">
Update the foundational account info and responsible teammates. These changes are scoped to
the current Google Ads account.
</Text>
</Stack>
</Card.Section>
<Paper withBorder radius="md" p="md">
<Stack spacing="md">
<Group position="apart">
<Text weight={600}>Account Details</Text>
</Group>
<Divider />
<SimpleGrid cols={2} breakpoints={[{ maxWidth: "sm", cols: 1 }]}>
<TextInput
label="Account name"
value={form.data.name}
onChange={(event) => form.setData("name", event.target.value)}
error={form.errors.name}
required
/>
<TextInput
label="Google customer ID"
value={form.data.customer_id}
onChange={(event) => form.setData("customer_id", event.target.value)}
error={form.errors.customer_id}
required
/>
<TextInput
label="Industry"
placeholder="e.g. SaaS, Hospitality"
value={form.data.industry}
onChange={(event) => form.setData("industry", event.target.value)}
error={form.errors.industry}
/>
<TextInput
label="Customer Code"
placeholder="SQL account code"
value={form.data.sql_acc_code}
onChange={(event) => form.setData("sql_acc_code", event.target.value)}
error={form.errors.sql_acc_code}
/>
</SimpleGrid>
</Stack>
</Paper>
<Paper
withBorder
radius="md"
p="md"
sx={(theme) => ({
backgroundColor:
theme.colorScheme === "dark"
? theme.colors.dark[6]
: theme.white,
})}
>
<Stack spacing="md">
<Text weight={600}>Assignments</Text>
<Divider />
<SimpleGrid
cols={2}
breakpoints={[{ maxWidth: "md", cols: 1 }]}
spacing="md"
>
{clientAssignmentRoles.map((role) => (
<Select
key={role.id}
label={role.label}
placeholder={`Select ${role.label}`}
data={assignmentUsers}
value={form.data[role.field]}
onChange={(value) => form.setData(role.field, value ?? "")}
error={form.errors[role.field]}
clearable
searchable
/>
))}
</SimpleGrid>
</Stack>
</Paper>
<Group position="right" pt="xs">
<Button
type="submit"
loading={form.processing}
leftIcon={<IconDeviceFloppy size={16} />}
variant="gradient"
gradient={{ from: "indigo", to: "cyan" }}
>
Save account
</Button>
</Group>
</Stack>
</form>
</Card>
</Container>
</AppLayout>
);
}