207 lines
8.4 KiB
TypeScript
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>
|
|
);
|
|
}
|