notification perfer
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
VITE_TOKEN_NAME = 'dmnu_a_t'
|
||||
VITE_REFRESH_TOKEN_NAME = 'dmnu-a-rt'
|
||||
|
||||
VITE_BASE_URL = 'https://dmenuplus-api.dev.danakcorp.com'
|
||||
# VITE_BASE_URL = 'http://192.168.99.242:4000'
|
||||
# VITE_BASE_URL = 'https://dmenuplus-api.dev.danakcorp.com'
|
||||
VITE_BASE_URL = 'http://192.168.99.242:4000'
|
||||
|
||||
VITE_SOCKET_URL = 'https://dmenuplus-api.dev.danakcorp.com'
|
||||
@@ -1,9 +1,8 @@
|
||||
import { type FC, useState, useEffect } from 'react'
|
||||
import DefaulModal from '@/components/DefaulModal'
|
||||
import Select from '@/components/Select'
|
||||
import Button from '@/components/Button'
|
||||
import { Checkbox } from '@/components/ui/checkbox'
|
||||
import { useUpdateNotification } from '../hooks/useNotificationData'
|
||||
import { NotificationType } from '../enum/Enum'
|
||||
import type { Notification } from '../types/Types'
|
||||
|
||||
interface Props {
|
||||
@@ -12,29 +11,50 @@ interface Props {
|
||||
notification: Notification | null
|
||||
}
|
||||
|
||||
type ChannelType = "sms" | "push" | "in-app"
|
||||
|
||||
const channelOptions: { value: ChannelType; label: string }[] = [
|
||||
{ value: "sms", label: 'پیامک' },
|
||||
{ value: "push", label: 'پوش' },
|
||||
{ value: "in-app", label: 'درون برنامه' },
|
||||
]
|
||||
|
||||
const getTitleLabel = (title: string): string => {
|
||||
const titleMap: Record<string, string> = {
|
||||
'order.created': 'سفارش ایجاد شد',
|
||||
'order.status.changed': 'تغییر وضعیت سفارش',
|
||||
'pager.created': 'پیجر ایجاد شد',
|
||||
'payment.success': 'پرداخت موفق',
|
||||
'review.created': 'نظر ایجاد شد',
|
||||
}
|
||||
return titleMap[title] || title
|
||||
}
|
||||
|
||||
const EditNotificationTypeModal: FC<Props> = ({ open, close, notification }) => {
|
||||
const [selectedType, setSelectedType] = useState<NotificationType>(NotificationType.NONE)
|
||||
const [selectedChannels, setSelectedChannels] = useState<ChannelType[]>([])
|
||||
const { mutate: updateNotification, isPending } = useUpdateNotification()
|
||||
|
||||
useEffect(() => {
|
||||
if (notification) {
|
||||
setSelectedType(notification.notificationType as NotificationType)
|
||||
setSelectedChannels([...notification.channels])
|
||||
}
|
||||
}, [notification])
|
||||
|
||||
if (!notification) return null
|
||||
|
||||
const notificationTypeOptions = [
|
||||
{ value: NotificationType.SMS, label: 'پیامک' },
|
||||
{ value: NotificationType.PUSH, label: 'پوش' },
|
||||
{ value: NotificationType.Both, label: 'هر دو' },
|
||||
]
|
||||
const handleToggleChannel = (channel: ChannelType, checked: boolean) => {
|
||||
if (checked) {
|
||||
setSelectedChannels((prev) => [...prev, channel])
|
||||
} else {
|
||||
setSelectedChannels((prev) => prev.filter((c) => c !== channel))
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = () => {
|
||||
updateNotification(
|
||||
{
|
||||
id: notification.id,
|
||||
notificationType: selectedType,
|
||||
channels: selectedChannels,
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
@@ -58,17 +78,29 @@ const EditNotificationTypeModal: FC<Props> = ({ open, close, notification }) =>
|
||||
عنوان
|
||||
</label>
|
||||
<p className="text-sm font-medium">
|
||||
{notification.title || '-'}
|
||||
{notification.title ? getTitleLabel(notification.title) : '-'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Select
|
||||
label="نوع اعلان"
|
||||
items={notificationTypeOptions}
|
||||
value={selectedType}
|
||||
onChange={(e) => setSelectedType(e.target.value as NotificationType)}
|
||||
/>
|
||||
<label className="text-sm mb-3 block">
|
||||
کانالهای اعلان
|
||||
</label>
|
||||
<div className="space-y-3">
|
||||
{channelOptions.map((option) => (
|
||||
<div key={option.value} className="flex items-center gap-2">
|
||||
<Checkbox
|
||||
checked={selectedChannels.includes(option.value)}
|
||||
onCheckedChange={(checked) =>
|
||||
handleToggleChannel(option.value, checked as boolean)
|
||||
}
|
||||
/>
|
||||
<label className="text-sm cursor-pointer">
|
||||
{option.label}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end gap-3 mt-6 border-t border-gray-200 pt-4">
|
||||
|
||||
@@ -4,13 +4,33 @@ import type { Notification } from '../types/Types'
|
||||
import { formatOptionalDate } from '@/helpers/func'
|
||||
import Status from '@/components/Status'
|
||||
|
||||
const getNotificationTypeVariant = (type: string): 'success' | 'error' | 'warning' | 'info' | 'pending' => {
|
||||
const getChannelVariant = (channel: string): 'success' | 'error' | 'warning' | 'info' | 'pending' => {
|
||||
const variantMap: Record<string, 'success' | 'error' | 'warning' | 'info' | 'pending'> = {
|
||||
'sms': 'info',
|
||||
'push': 'warning',
|
||||
'both': 'success',
|
||||
'in-app': 'success',
|
||||
}
|
||||
return variantMap[type] || 'info'
|
||||
return variantMap[channel] || 'info'
|
||||
}
|
||||
|
||||
const getChannelLabel = (channel: string): string => {
|
||||
const labels: Record<string, string> = {
|
||||
'sms': 'پیامک',
|
||||
'push': 'پوش',
|
||||
'in-app': 'درون برنامه',
|
||||
}
|
||||
return labels[channel] || channel
|
||||
}
|
||||
|
||||
const getTitleLabel = (title: string): string => {
|
||||
const titleMap: Record<string, string> = {
|
||||
'order.created': 'سفارش ایجاد شد',
|
||||
'order.status.changed': 'تغییر وضعیت سفارش',
|
||||
'pager.created': 'پیجر ایجاد شد',
|
||||
'payment.success': 'پرداخت موفق',
|
||||
'review.created': 'نظر ایجاد شد',
|
||||
}
|
||||
return titleMap[title] || title
|
||||
}
|
||||
|
||||
type Props = {
|
||||
@@ -25,25 +45,28 @@ export const getNotificationTableColumns = ({ onEdit }: Props): ColumnType<Notif
|
||||
render: (item: Notification) => {
|
||||
return (
|
||||
<div className="max-w-xs truncate" title={item.title}>
|
||||
{item.title || '-'}
|
||||
{item.title ? getTitleLabel(item.title) : '-'}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'notificationType',
|
||||
title: 'نوع اعلان',
|
||||
key: 'channels',
|
||||
title: 'کانالهای اعلان',
|
||||
render: (item: Notification) => {
|
||||
const typeLabels: Record<string, string> = {
|
||||
'sms': 'پیامک',
|
||||
'push': 'پوش',
|
||||
'both': 'هر دو',
|
||||
if (!item.channels || item.channels.length === 0) {
|
||||
return <span className="text-gray-400">-</span>
|
||||
}
|
||||
return (
|
||||
<Status
|
||||
variant={getNotificationTypeVariant(item.notificationType)}
|
||||
label={typeLabels[item.notificationType] || item.notificationType}
|
||||
/>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{item.channels.map((channel, index) => (
|
||||
<Status
|
||||
key={index}
|
||||
variant={getChannelVariant(channel)}
|
||||
label={getChannelLabel(channel)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
export const enum NotificationType {
|
||||
NONE = "none",
|
||||
IN_APP = "in-app",
|
||||
SMS = "sms",
|
||||
PUSH = "push",
|
||||
Both = "both",
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { NotificationType } from "../enum/Enum";
|
||||
import * as api from "../service/NotificationService";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
@@ -16,11 +15,11 @@ export const useUpdateNotification = () => {
|
||||
return useMutation({
|
||||
mutationFn: ({
|
||||
id,
|
||||
notificationType,
|
||||
channels,
|
||||
}: {
|
||||
id: string;
|
||||
notificationType: NotificationType;
|
||||
}) => api.updateNotification(id, notificationType),
|
||||
channels: ("sms" | "push" | "in-app")[];
|
||||
}) => api.updateNotification(id, channels),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ["notifications"] });
|
||||
},
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import axios from "@/config/axios";
|
||||
import type { GetNotificationsResponse } from "../types/Types";
|
||||
import type { NotificationType } from "../enum/Enum";
|
||||
|
||||
export const getNotifications = async (
|
||||
params?: Record<string, string | number>
|
||||
@@ -14,10 +13,10 @@ export const getNotifications = async (
|
||||
|
||||
export const updateNotification = async (
|
||||
id: string,
|
||||
notificationType: NotificationType
|
||||
channels: ("sms" | "push" | "in-app")[]
|
||||
) => {
|
||||
const { data } = await axios.patch(`/admin/notification-preferences/${id}`, {
|
||||
notificationType,
|
||||
channels,
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@ export interface Notification extends RowDataType {
|
||||
deletedAt: string | null;
|
||||
restaurant: string;
|
||||
title: string;
|
||||
notificationType: "sms" | "push" | "both";
|
||||
channels: ("sms" | "push" | "in-app")[];
|
||||
}
|
||||
|
||||
export type GetNotificationsResponse = IResponse<Notification[]>;
|
||||
|
||||
Reference in New Issue
Block a user