feat: implement Sonner notifications, add Setting model, and reorganize user management into settings navigation.
This commit is contained in:
@@ -2,52 +2,111 @@
|
||||
|
||||
import { useState } from 'react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Share2, Check } from 'lucide-react'
|
||||
import { Dialog, DialogContent, DialogTitle, DialogTrigger } from '@/components/ui/dialog'
|
||||
import { Share2, Check, Copy, MessageCircle, MessageSquare, Loader2 } from 'lucide-react'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { broadcastToMattermost, getSettings } from '@/app/actions'
|
||||
import { toast } from 'sonner'
|
||||
|
||||
interface ShareButtonProps {
|
||||
orderId: string
|
||||
orderTitle?: string
|
||||
className?: string
|
||||
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost"
|
||||
size?: "default" | "sm" | "lg" | "icon"
|
||||
showText?: boolean
|
||||
}
|
||||
|
||||
export function ShareButton({ orderId, className, variant = "outline", size = "sm", showText = true }: ShareButtonProps) {
|
||||
export function ShareButton({ orderId, orderTitle = 'Pesanan', className, variant = "outline", size = "sm", showText = true }: ShareButtonProps) {
|
||||
const [copied, setCopied] = useState(false)
|
||||
const [open, setOpen] = useState(false)
|
||||
const [broadcasting, setBroadcasting] = useState(false)
|
||||
|
||||
const handleShare = () => {
|
||||
const handleCopyLink = () => {
|
||||
const url = `${window.location.origin}/order/${orderId}`
|
||||
navigator.clipboard.writeText(url)
|
||||
setCopied(true)
|
||||
setTimeout(() => setCopied(false), 2000)
|
||||
}
|
||||
|
||||
const handleShareWA = async () => {
|
||||
const settings = await getSettings()
|
||||
let template = settings.WHATSAPP_TEMPLATE || 'Halo tim! Lagi ada orderan open nih untuk {title}. Mumpung belum di-checkout, yang mau ikutan nitip bisa langsung cek ke sini ya: {url}'
|
||||
|
||||
const url = `${window.location.origin}/order/${orderId}`
|
||||
const text = template.replace('{title}', orderTitle).replace('{url}', url)
|
||||
|
||||
window.open(`https://api.whatsapp.com/send?text=${encodeURIComponent(text)}`, '_blank')
|
||||
}
|
||||
|
||||
const handleBroadcastMattermost = async () => {
|
||||
setBroadcasting(true)
|
||||
const url = `${window.location.origin}/order/${orderId}`
|
||||
const res = await broadcastToMattermost(orderId, url)
|
||||
if (res.success) {
|
||||
toast.success('Broadcast Terkirim!', {
|
||||
description: 'Berhasil mengirim pesan ke Mattermost.',
|
||||
duration: 3000
|
||||
})
|
||||
setOpen(false)
|
||||
} else {
|
||||
toast.error('Gagal Broadcast', {
|
||||
description: res.error || 'Terjadi kesalahan saat mengirim.',
|
||||
duration: 3000
|
||||
})
|
||||
}
|
||||
setBroadcasting(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant={variant}
|
||||
size={size}
|
||||
onClick={handleShare}
|
||||
className={cn(
|
||||
"transition-all",
|
||||
copied
|
||||
? "bg-emerald-50 text-emerald-600 border-emerald-200 hover:bg-emerald-100 hover:text-emerald-700 dark:bg-emerald-950/30 dark:text-emerald-400 dark:border-emerald-800"
|
||||
: "",
|
||||
className
|
||||
)}
|
||||
title="Bagikan PO"
|
||||
>
|
||||
{copied ? (
|
||||
<>
|
||||
<Check className="w-3.5 h-3.5 shrink-0" />
|
||||
{showText && <span className="truncate hidden sm:inline">Tersalin</span>}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Share2 className="w-3.5 h-3.5 shrink-0" />
|
||||
{showText && <span className="truncate hidden sm:inline">Bagikan</span>}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
<>
|
||||
<Button
|
||||
variant={variant}
|
||||
size={size}
|
||||
className={cn("transition-all", className)}
|
||||
title="Bagikan PO"
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
<Share2 className="w-3.5 h-3.5 shrink-0" />
|
||||
{showText && <span className="truncate hidden sm:inline">Bagikan</span>}
|
||||
</Button>
|
||||
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogContent className="sm:max-w-xs p-6 rounded-3xl border-slate-200/90 dark:border-slate-800">
|
||||
<DialogTitle className="text-xl font-black text-center text-slate-900 dark:text-white mb-2">Bagikan Pesanan</DialogTitle>
|
||||
<p className="text-sm text-slate-500 text-center mb-4">
|
||||
Pilih metode untuk membagikan PO ini ke teman atau tim Anda.
|
||||
</p>
|
||||
|
||||
<div className="space-y-3">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={handleCopyLink}
|
||||
className="w-full h-11 rounded-xl justify-start font-bold gap-3 text-slate-700 dark:text-slate-300"
|
||||
>
|
||||
{copied ? <Check className="w-4 h-4 text-emerald-500" /> : <Copy className="w-4 h-4" />}
|
||||
{copied ? 'Tautan Disalin!' : 'Salin Tautan'}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
onClick={handleShareWA}
|
||||
className="w-full h-11 rounded-xl justify-start font-bold gap-3 bg-[#25D366] hover:bg-[#20bd5a] text-white"
|
||||
>
|
||||
<MessageCircle className="w-4 h-4" />
|
||||
Kirim ke WhatsApp
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
onClick={handleBroadcastMattermost}
|
||||
disabled={broadcasting}
|
||||
className="w-full h-11 rounded-xl justify-start font-bold gap-3 bg-[#0668E1] hover:bg-[#0557bc] text-white"
|
||||
>
|
||||
{broadcasting ? <Loader2 className="w-4 h-4 animate-spin" /> : <MessageSquare className="w-4 h-4" />}
|
||||
{broadcasting ? 'Mengirim...' : 'Broadcast ke Mattermost'}
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user