fix(web): wire up inquiry modal toast notification on listing detail page
The "Nhắn tin" button's inquiry modal now shows a success toast via sonner after submission instead of an in-dialog success state, and closes the modal automatically. Added sonner as a dependency and mounted <Toaster> in the root locale layout. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -3,6 +3,7 @@ import { Inter } from 'next/font/google';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { NextIntlClientProvider } from 'next-intl';
|
||||
import { getMessages, getTranslations } from 'next-intl/server';
|
||||
import { Toaster } from 'sonner';
|
||||
import { AuthProvider } from '@/components/providers/auth-provider';
|
||||
import { NotificationsProvider } from '@/components/providers/notifications-provider';
|
||||
import { QueryProvider } from '@/components/providers/query-provider';
|
||||
@@ -124,6 +125,7 @@ export default async function LocaleLayout({
|
||||
<QueryProvider>
|
||||
<AuthProvider>
|
||||
<NotificationsProvider>
|
||||
<Toaster position="top-right" richColors closeButton />
|
||||
<WebVitals />
|
||||
{children}
|
||||
</NotificationsProvider>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import { toast } from 'sonner';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
Dialog,
|
||||
@@ -38,7 +39,6 @@ export function InquiryModal({
|
||||
const [message, setMessage] = React.useState('');
|
||||
const [phone, setPhone] = React.useState('');
|
||||
const [error, setError] = React.useState<string | null>(null);
|
||||
const [success, setSuccess] = React.useState(false);
|
||||
|
||||
// Pre-fill phone from auth store when modal opens
|
||||
React.useEffect(() => {
|
||||
@@ -47,7 +47,6 @@ export function InquiryModal({
|
||||
}
|
||||
if (open) {
|
||||
setError(null);
|
||||
setSuccess(false);
|
||||
setMessage('');
|
||||
}
|
||||
}, [open, user?.phone]);
|
||||
@@ -81,7 +80,10 @@ export function InquiryModal({
|
||||
message: trimmedMessage,
|
||||
phone: trimmedPhone,
|
||||
});
|
||||
setSuccess(true);
|
||||
onOpenChange(false);
|
||||
toast.success('Đã gửi thành công!', {
|
||||
description: `Tin nhắn của bạn đã được gửi đến ${sellerName}. Họ sẽ liên hệ với bạn sớm nhất có thể.`,
|
||||
});
|
||||
} catch (err) {
|
||||
if (err instanceof ApiError && err.status === 401) {
|
||||
window.location.href = '/login';
|
||||
@@ -96,39 +98,6 @@ export function InquiryModal({
|
||||
}
|
||||
};
|
||||
|
||||
if (success) {
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Đã gửi thành công!</DialogTitle>
|
||||
<DialogDescription>
|
||||
Tin nhắn của bạn đã được gửi đến {sellerName}. Họ sẽ liên hệ với bạn sớm nhất có thể.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="flex justify-center py-4">
|
||||
<svg
|
||||
className="h-16 w-16 text-green-500"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button onClick={() => onOpenChange(false)}>Đóng</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent>
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"react-hook-form": "^7.72.1",
|
||||
"recharts": "^3.8.1",
|
||||
"socket.io-client": "^4.8.3",
|
||||
"sonner": "^2.0.7",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"web-vitals": "^5.2.0",
|
||||
"zod": "^4.3.6",
|
||||
|
||||
14
pnpm-lock.yaml
generated
14
pnpm-lock.yaml
generated
@@ -343,6 +343,9 @@ importers:
|
||||
socket.io-client:
|
||||
specifier: ^4.8.3
|
||||
version: 4.8.3
|
||||
sonner:
|
||||
specifier: ^2.0.7
|
||||
version: 2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
tailwind-merge:
|
||||
specifier: ^3.5.0
|
||||
version: 3.5.0
|
||||
@@ -6493,6 +6496,12 @@ packages:
|
||||
sonic-boom@4.2.1:
|
||||
resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==}
|
||||
|
||||
sonner@2.0.7:
|
||||
resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==}
|
||||
peerDependencies:
|
||||
react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
|
||||
react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc
|
||||
|
||||
source-map-js@1.2.1:
|
||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -14145,6 +14154,11 @@ snapshots:
|
||||
dependencies:
|
||||
atomic-sleep: 1.0.0
|
||||
|
||||
sonner@2.0.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
source-map-js@1.2.1: {}
|
||||
|
||||
source-map-support@0.5.21:
|
||||
|
||||
Reference in New Issue
Block a user