TorbatYar/frontend/modules/beauty/components/BeautyComboboxes.tsx
Mortezakoohjani d579d0b142 feat(loyalty): add Loyalty Platform Frontend module
Add frontend/modules/loyalty with types, API client, design system, feature pages and thin App Router routes under app/loyalty/. BFF proxy at app/api/loyalty/. Include loyalty frontend docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 10:50:55 +03:30

172 lines
5.1 KiB
TypeScript
Raw Permalink 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.

"use client";
import { Select } from "@/components/ds";
import { useBeautyLookups } from "@/modules/beauty/hooks/useBeautyLookups";
import { useQuery } from "@tanstack/react-query";
import { beautyBusinessApi } from "@/modules/beauty/services/beauty-business-api";
import { useTenantId } from "@/hooks/useTenantId";
type SelectProps = {
value: string;
onChange: (v: string) => void;
required?: boolean;
label?: string;
organizationId?: string;
};
function FieldShell({
label,
required,
children,
}: {
label?: string;
required?: boolean;
children: React.ReactNode;
}) {
return (
<label className="block text-sm">
{label ? (
<span className="mb-1 block text-[var(--muted)]">
{label}
{required ? " *" : ""}
</span>
) : null}
{children}
</label>
);
}
export function OrganizationSelect({ value, onChange, required, label = "سازمان" }: SelectProps) {
const { organizations } = useBeautyLookups();
return (
<FieldShell label={label} required={required}>
<Select value={value} onChange={(e) => onChange(e.target.value)} required={required}>
<option value="">انتخاب</option>
{organizations.map((o) => (
<option key={o.id} value={o.id}>
{o.name}
</option>
))}
</Select>
</FieldShell>
);
}
export function BranchSelect({ value, onChange, required, label = "شعبه", organizationId }: SelectProps) {
const { branches } = useBeautyLookups();
const filtered = organizationId
? branches.filter((b) => b.organization_id === organizationId)
: branches;
return (
<FieldShell label={label} required={required}>
<Select value={value} onChange={(e) => onChange(e.target.value)} required={required}>
<option value="">انتخاب</option>
{filtered.map((b) => (
<option key={b.id} value={b.id}>
{b.name}
</option>
))}
</Select>
</FieldShell>
);
}
export function StaffSelect({ value, onChange, required, label = "پرسنل" }: SelectProps) {
const { staff } = useBeautyLookups();
return (
<FieldShell label={label} required={required}>
<Select value={value} onChange={(e) => onChange(e.target.value)} required={required}>
<option value="">انتخاب</option>
{staff.map((s) => (
<option key={s.id} value={s.id}>
{s.display_name}
</option>
))}
</Select>
</FieldShell>
);
}
export function CustomerSelect({ value, onChange, required, label = "مشتری" }: SelectProps) {
const { customers } = useBeautyLookups();
return (
<FieldShell label={label} required={required}>
<Select value={value} onChange={(e) => onChange(e.target.value)} required={required}>
<option value="">انتخاب</option>
{customers.map((c) => (
<option key={c.id} value={c.id}>
{c.display_name}
</option>
))}
</Select>
</FieldShell>
);
}
export function ServiceSelect({ value, onChange, required, label = "خدمت" }: SelectProps) {
const { services } = useBeautyLookups();
return (
<FieldShell label={label} required={required}>
<Select value={value} onChange={(e) => onChange(e.target.value)} required={required}>
<option value="">انتخاب</option>
{services.map((s) => (
<option key={s.id} value={s.id}>
{s.name}
</option>
))}
</Select>
</FieldShell>
);
}
export function CategorySelect({ value, onChange, required, label = "دسته‌بندی" }: SelectProps) {
const { tenantId } = useTenantId();
const q = useQuery({
queryKey: ["beauty", tenantId, "lookups", "categories"],
queryFn: () => beautyBusinessApi.serviceCategories.list(tenantId!),
enabled: !!tenantId,
});
return (
<FieldShell label={label} required={required}>
<Select value={value} onChange={(e) => onChange(e.target.value)} required={required}>
<option value="">انتخاب</option>
{(q.data ?? []).map((c) => (
<option key={c.id} value={c.id}>
{c.name}
</option>
))}
</Select>
</FieldShell>
);
}
export function RoomSelect({
value,
onChange,
required,
label = "اتاق",
organizationId,
}: SelectProps) {
const { tenantId } = useTenantId();
const q = useQuery({
queryKey: ["beauty", tenantId, "lookups", "rooms"],
queryFn: () => beautyBusinessApi.treatmentRooms.list(tenantId!),
enabled: !!tenantId,
});
const rooms = (q.data ?? []).filter(
(r) => !organizationId || r.organization_id === organizationId
);
return (
<FieldShell label={label} required={required}>
<Select value={value} onChange={(e) => onChange(e.target.value)} required={required}>
<option value="">انتخاب</option>
{rooms.map((r) => (
<option key={r.id} value={r.id}>
{r.name}
</option>
))}
</Select>
</FieldShell>
);
}