Files
hounam-submit-form-frontend/ui/forms/ReferralForm.tsx
2026-05-31 14:22:39 +03:30

242 lines
5.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React from "react";
import {
Box,
Paper,
TextField,
Typography,
IconButton,
Button,
MenuItem,
Divider,
} from "@mui/material";
import AddIcon from "@mui/icons-material/Add";
import { DeleteOutlineOutlined } from "@mui/icons-material";
// ---------------- Types ----------------
export type AcquaintanceType = "Direct" | "Indirect";
export interface ReferralFormData {
firstName: string;
lastName: string;
relationship: string;
acquaintanceDuration: string; // optional in DB, but keep as string
acquaintanceType: AcquaintanceType;
jobTitle: string;
workplaceName: string;
phoneNumber: string;
}
interface ReferralItemFormProps {
index: number;
value: ReferralFormData;
onChange: (next: ReferralFormData) => void;
onRemove?: () => void;
disableRemove?: boolean;
}
// ---------------- Item Form ----------------
export function ReferralItemForm({
index,
value,
onChange,
onRemove,
disableRemove,
}: ReferralItemFormProps) {
const setField =
(key: keyof ReferralFormData) =>
(e: React.ChangeEvent<HTMLInputElement>) => {
onChange({ ...value, [key]: e.target.value });
};
return (
<Paper
elevation={0}
sx={{
p: { xs: 2, md: 2.5 },
borderRadius: 2,
border: "1px solid #e5e7eb",
backgroundColor: "#fff", // بدون سبز
}}
>
<Box
sx={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
mb: 1.5,
gap: 2,
}}
>
<Typography sx={{ fontWeight: 700 }}>معرف {index + 1}</Typography>
<IconButton
onClick={onRemove}
disabled={disableRemove}
color="error"
size="small"
aria-label="حذف معرف"
>
<DeleteOutlineOutlined />
</IconButton>
</Box>
<Box
sx={{
display: "grid",
gridTemplateColumns: { xs: "1fr", md: "1fr 1fr" },
gap: 2,
}}
>
<TextField
label="نام"
value={value.firstName}
onChange={setField("firstName")}
fullWidth
required
/>
<TextField
label="نام خانوادگی"
value={value.lastName}
onChange={setField("lastName")}
fullWidth
required
/>
<TextField
label="نسبت / رابطه"
value={value.relationship}
onChange={setField("relationship")}
fullWidth
required
placeholder="مثلاً: دوست، همکار، فامیل..."
/>
<TextField
label="مدت زمان آشنایی"
value={value.acquaintanceDuration}
onChange={setField("acquaintanceDuration")}
fullWidth
placeholder="مثلاً: ۵ سال"
/>
<TextField
select
label="نوع آشنایی"
value={value.acquaintanceType}
onChange={setField("acquaintanceType")}
fullWidth
required
>
<MenuItem value="Direct">مستقیم</MenuItem>
<MenuItem value="Indirect">غیرمستقیم</MenuItem>
</TextField>
<TextField
label="تلفن تماس"
value={value.phoneNumber}
onChange={setField("phoneNumber")}
fullWidth
required
placeholder="مثلاً: 0912xxxxxxx"
/>
<TextField
label="شغل معرف"
value={value.jobTitle}
onChange={setField("jobTitle")}
fullWidth
/>
<TextField
label="نام محل کار معرف"
value={value.workplaceName}
onChange={setField("workplaceName")}
fullWidth
/>
</Box>
</Paper>
);
}
// ---------------- Section (Multi) ----------------
interface ReferralSectionProps {
value: ReferralFormData[];
onChange: (next: ReferralFormData[]) => void;
minItems?: number; // پیش‌فرض 1
maxItems?: number; // اختیاری
title?: string;
}
const emptyReferral = (): ReferralFormData => ({
firstName: "",
lastName: "",
relationship: "",
acquaintanceDuration: "",
acquaintanceType: "Direct",
jobTitle: "",
workplaceName: "",
phoneNumber: "",
});
export function ReferralSection({
value,
onChange,
minItems = 1,
maxItems,
title = "معرف‌ها",
}: ReferralSectionProps) {
const items = value?.length ? value : Array.from({ length: minItems }, emptyReferral);
const addItem = () => {
if (maxItems && items.length >= maxItems) return;
onChange([...(items || []), emptyReferral()]);
};
const updateItem = (idx: number, nextItem: ReferralFormData) => {
const next = items.map((it, i) => (i === idx ? nextItem : it));
onChange(next);
};
const removeItem = (idx: number) => {
if (items.length <= minItems) return;
const next = items.filter((_, i) => i !== idx);
onChange(next);
};
return (
<Paper
elevation={0}
>
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 2 }}>
<Button
onClick={addItem}
variant="contained"
startIcon={<AddIcon />}
disabled={!!maxItems && items.length >= maxItems}
>
افزودن معرف جديد
</Button>
</Box>
<Divider sx={{ my: 2 }} />
<Box sx={{ display: "grid", gap: 2 }}>
{items.map((item, idx) => (
<ReferralItemForm
key={idx}
index={idx}
value={item}
onChange={(next) => updateItem(idx, next)}
onRemove={() => removeItem(idx)}
disableRemove={items.length <= minItems}
/>
))}
</Box>
</Paper>
);
}