fix: save and display professional profile address, payment methods, and docs
- DTO: add payment_methods field so whitelist pipe no longer strips it - Service upsert(): extract payment_methods and write as Prisma nested upsert instead of passing flat object - Admin detail page: fix image regex to handle Firebase URLs with query params; fix payment_methods display for 1:1 Prisma relation (object, not array) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
1e0de51ec5
commit
72777df52c
@@ -23,7 +23,8 @@ interface Professional {
|
||||
rate?: number; average_score?: number;
|
||||
identification_picture?: string; certificate_picture?: string; banner_picture?: string;
|
||||
users?: User; schedules?: Schedule[];
|
||||
specializations?: Specialization[]; payment_methods?: PaymentMethod[];
|
||||
specializations?: Specialization[];
|
||||
payment_methods?: PaymentMethod | PaymentMethod[] | null;
|
||||
}
|
||||
interface Service { id: string; description?: string; rate?: number; status: string; day: string; }
|
||||
|
||||
@@ -440,11 +441,12 @@ export default function ProfessionalDetailPage() {
|
||||
banner_picture: 'Foto de perfil / Banner',
|
||||
};
|
||||
const url = professional[field];
|
||||
const isImage = url && /\.(jpg|jpeg|png|webp|gif)(\?|$)/i.test(url);
|
||||
return (
|
||||
<div key={field} className="space-y-2">
|
||||
<p className="text-sm text-muted-foreground">{labels[field]}</p>
|
||||
{url ? (
|
||||
url.match(/\.(jpg|jpeg|png|webp)$/i) ? (
|
||||
isImage ? (
|
||||
<a href={url} target="_blank" rel="noreferrer">
|
||||
<img src={url} alt={labels[field]} className="rounded-lg border object-cover w-full max-h-48" />
|
||||
</a>
|
||||
@@ -463,15 +465,19 @@ export default function ProfessionalDetailPage() {
|
||||
</Card>
|
||||
|
||||
{/* Métodos de pago */}
|
||||
{professional.payment_methods && professional.payment_methods.length > 0 && (
|
||||
{professional.payment_methods && (
|
||||
<Card>
|
||||
<CardHeader><CardTitle>Métodos de pago aceptados</CardTitle></CardHeader>
|
||||
<CardContent>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{['nequi', 'datafono', 'transferencia']
|
||||
.filter((k) => (professional.payment_methods![0] as any)[k])
|
||||
.map((k) => <Badge key={k} variant="outline">{PAYMENT_LABELS[k]}</Badge>)}
|
||||
</div>
|
||||
{(() => {
|
||||
const pm = Array.isArray(professional.payment_methods)
|
||||
? (professional.payment_methods as PaymentMethod[])[0]
|
||||
: professional.payment_methods as PaymentMethod;
|
||||
const active = pm ? ['nequi', 'datafono', 'transferencia'].filter((k) => (pm as any)[k]) : [];
|
||||
return active.length > 0
|
||||
? <div className="flex flex-wrap gap-2">{active.map((k) => <Badge key={k} variant="outline">{PAYMENT_LABELS[k]}</Badge>)}</div>
|
||||
: <p className="text-sm text-muted-foreground">Ninguno configurado</p>;
|
||||
})()}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user