- Introduced ShareDocumentButton component for sharing documents. - Added ShareDocumentDialog for email and WhatsApp sharing options. - Integrated document sharing in estimates, invoices, inspections, job cards, bills, and purchase orders. - Implemented useDocumentShare hook for handling share logic. - Created DocumentShareClient for API interactions related to document sharing. - Updated layouts and actions to include sharing options for relevant entities.
182 lines
7.8 KiB
TypeScript
182 lines
7.8 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect, useState } from "react"
|
|
import type { DocumentShareType } from "@garage/api"
|
|
import { Button } from "@/shared/components/ui/button"
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from "@/shared/components/ui/dialog"
|
|
import { Input } from "@/shared/components/ui/input"
|
|
import { Label } from "@/shared/components/ui/label"
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/shared/components/ui/tabs"
|
|
import { Textarea } from "@/shared/components/ui/textarea"
|
|
import { useDocumentShare } from "@/shared/hooks/use-document-share"
|
|
|
|
interface ShareDocumentDialogProps {
|
|
type: DocumentShareType
|
|
id: string | number
|
|
open: boolean
|
|
onOpenChange: (open: boolean) => void
|
|
}
|
|
|
|
const DEFAULT_MESSAGES: Record<string, { email: string; whatsapp: string }> = {
|
|
estimate: {
|
|
email: "Hello, please find your estimate at the link below. Kindly review the details and let us know if you'd like to proceed.",
|
|
whatsapp: "Hello, here is your estimate. Please review and let us know if you'd like to proceed.",
|
|
},
|
|
invoice: {
|
|
email: "Hello, please find your invoice at the link below. Let us know once payment has been arranged.",
|
|
whatsapp: "Hello, here is your invoice. Let us know once payment is arranged.",
|
|
},
|
|
job_card: {
|
|
email: "Hello, please find the job card for your vehicle at the link below.",
|
|
whatsapp: "Hello, here is the job card for your vehicle.",
|
|
},
|
|
inspection: {
|
|
email: "Hello, please find your vehicle inspection report at the link below.",
|
|
whatsapp: "Hello, here is your vehicle inspection report.",
|
|
},
|
|
payment_received: {
|
|
email: "Hello, please find your payment receipt at the link below. Thank you.",
|
|
whatsapp: "Hello, here is your payment receipt. Thank you.",
|
|
},
|
|
purchase_order: {
|
|
email: "Hello, please find our purchase order at the link below. Kindly confirm receipt.",
|
|
whatsapp: "Hello, here is our purchase order. Kindly confirm receipt.",
|
|
},
|
|
bill: {
|
|
email: "Hello, please find the bill at the link below for your reference.",
|
|
whatsapp: "Hello, here is the bill for your reference.",
|
|
},
|
|
expense: {
|
|
email: "Hello, please find the expense document at the link below.",
|
|
whatsapp: "Hello, here is the expense document.",
|
|
},
|
|
payment_made: {
|
|
email: "Hello, please find the payment confirmation at the link below.",
|
|
whatsapp: "Hello, here is the payment confirmation.",
|
|
},
|
|
}
|
|
|
|
function getDefaultMessage(type: DocumentShareType, channel: "email" | "whatsapp"): string {
|
|
return DEFAULT_MESSAGES[type as string]?.[channel] ?? ""
|
|
}
|
|
|
|
export function ShareDocumentDialog({ type, id, open, onOpenChange }: ShareDocumentDialogProps) {
|
|
const { shareEmail, shareWhatsapp, isSharing } = useDocumentShare(type, id)
|
|
const [email, setEmail] = useState("")
|
|
const [phone, setPhone] = useState("")
|
|
const [emailMessage, setEmailMessage] = useState("")
|
|
const [whatsappMessage, setWhatsappMessage] = useState("")
|
|
|
|
useEffect(() => {
|
|
if (open) {
|
|
setEmailMessage(getDefaultMessage(type, "email"))
|
|
setWhatsappMessage(getDefaultMessage(type, "whatsapp"))
|
|
}
|
|
}, [open, type])
|
|
|
|
const close = () => {
|
|
onOpenChange(false)
|
|
setEmail("")
|
|
setPhone("")
|
|
setEmailMessage("")
|
|
setWhatsappMessage("")
|
|
}
|
|
|
|
const handleEmail = async () => {
|
|
if (!email) return
|
|
await shareEmail({ email, message: emailMessage || undefined })
|
|
close()
|
|
}
|
|
|
|
const handleWhatsapp = async () => {
|
|
await shareWhatsapp({ phone: phone || undefined, message: whatsappMessage || undefined })
|
|
close()
|
|
}
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
<DialogContent className="sm:max-w-md">
|
|
<DialogHeader>
|
|
<DialogTitle>Share document</DialogTitle>
|
|
</DialogHeader>
|
|
<Tabs defaultValue="email" className="w-full">
|
|
<TabsList className="grid w-full grid-cols-2">
|
|
<TabsTrigger value="email">Email</TabsTrigger>
|
|
<TabsTrigger value="whatsapp">WhatsApp</TabsTrigger>
|
|
</TabsList>
|
|
<TabsContent value="email" className="space-y-3 py-2">
|
|
<div className="space-y-1.5">
|
|
<Label htmlFor="share-email">Recipient email</Label>
|
|
<Input
|
|
id="share-email"
|
|
type="email"
|
|
value={email}
|
|
onChange={(e) => setEmail(e.target.value)}
|
|
placeholder="customer@example.com"
|
|
/>
|
|
</div>
|
|
<div className="space-y-1.5">
|
|
<Label htmlFor="share-email-message">Message</Label>
|
|
<Textarea
|
|
id="share-email-message"
|
|
value={emailMessage}
|
|
onChange={(e) => setEmailMessage(e.target.value)}
|
|
rows={4}
|
|
/>
|
|
</div>
|
|
<DialogFooter className="pt-2">
|
|
<Button variant="outline" type="button" onClick={close}>
|
|
Cancel
|
|
</Button>
|
|
<Button type="button" onClick={handleEmail} disabled={!email || isSharing}>
|
|
{isSharing ? "Sending..." : "Send email"}
|
|
</Button>
|
|
</DialogFooter>
|
|
</TabsContent>
|
|
<TabsContent value="whatsapp" className="space-y-3 py-2">
|
|
<div className="space-y-1.5">
|
|
<Label htmlFor="share-phone">Phone with country code (optional)</Label>
|
|
<Input
|
|
id="share-phone"
|
|
type="tel"
|
|
value={phone}
|
|
onChange={(e) => setPhone(e.target.value)}
|
|
placeholder="+971501234567"
|
|
/>
|
|
<p className="text-xs text-muted-foreground">
|
|
Leave empty to pick recipient inside WhatsApp.
|
|
</p>
|
|
</div>
|
|
<div className="space-y-1.5">
|
|
<Label htmlFor="share-wa-message">Message</Label>
|
|
<Textarea
|
|
id="share-wa-message"
|
|
value={whatsappMessage}
|
|
onChange={(e) => setWhatsappMessage(e.target.value)}
|
|
rows={4}
|
|
/>
|
|
</div>
|
|
<DialogFooter className="pt-2">
|
|
<Button variant="outline" type="button" onClick={close}>
|
|
Cancel
|
|
</Button>
|
|
<Button type="button" onClick={handleWhatsapp} disabled={isSharing}>
|
|
{isSharing ? "Opening..." : "Open WhatsApp"}
|
|
</Button>
|
|
</DialogFooter>
|
|
</TabsContent>
|
|
</Tabs>
|
|
<p className="text-xs text-muted-foreground text-center">
|
|
Share link expires 24 hours after creation.
|
|
</p>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
}
|