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:
Ho Ngoc Hai
2026-04-16 10:56:56 +07:00
parent 25f415f3bc
commit 44533a88f4
4 changed files with 22 additions and 36 deletions

View File

@@ -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>

View File

@@ -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 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>

View File

@@ -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
View File

@@ -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: