Browse Source

feat: update development server port, adjust chat component styles, and add new SVG icons

master
sina_sajjadi 2 weeks ago
parent
commit
1bfb7fe9aa
  1. 2
      next.config.js
  2. 2
      package.json
  3. 2055
      public/image/Frame-48098164.svg
  4. 3
      public/image/face-smile.svg
  5. 3
      public/image/icon-park-outline_link.svg
  6. 4
      public/image/link-simple.svg
  7. 3
      public/image/microphone-01.svg
  8. 3
      public/image/send-01.svg
  9. 10
      src/components/chat/chat-input.tsx
  10. 80
      src/components/chat/file-input.tsx
  11. 6
      src/components/chat/file-message.tsx
  12. 99
      src/components/chat/message.tsx
  13. 2
      src/components/chat/messages-list.tsx
  14. 2
      src/components/product/form-utils.ts
  15. 22
      src/contexts/WebSocket.context.tsx
  16. 2
      src/data/client/user.ts
  17. 2
      src/data/shop.ts
  18. 6
      src/pages/chat/chat-box.tsx
  19. 2
      src/pages/chat/converstions.tsx
  20. 27
      src/pages/shop/index.tsx

2
next.config.js

@ -12,7 +12,7 @@ const { i18n } = require('./next-i18next.config');
const nextConfig = {
basePath: '/dashboard',
// assetPrefix: '/dashboard/',
reactStrictMode: true,
reactStrictMode: false,
i18n,
publicRuntimeConfig: {

2
package.json

@ -3,7 +3,7 @@
"version": "6.6.0",
"private": true,
"scripts": {
"dev": "next dev -p 3000",
"dev": "next dev -p 3001",
"build": "next build",
"start": "next start -p 3000",
"lint": "next lint"

2055
public/image/Frame-48098164.svg
File diff suppressed because it is too large
View File

3
public/image/face-smile.svg

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.667 18.667C10.667 18.667 12.667 21.3337 16.0003 21.3337C19.3337 21.3337 21.3337 18.667 21.3337 18.667M20.0003 12.0003H20.0137M12.0003 12.0003H12.0137M29.3337 16.0003C29.3337 23.3641 23.3641 29.3337 16.0003 29.3337C8.63653 29.3337 2.66699 23.3641 2.66699 16.0003C2.66699 8.63653 8.63653 2.66699 16.0003 2.66699C23.3641 2.66699 29.3337 8.63653 29.3337 16.0003ZM20.667 12.0003C20.667 12.3685 20.3685 12.667 20.0003 12.667C19.6321 12.667 19.3337 12.3685 19.3337 12.0003C19.3337 11.6321 19.6321 11.3337 20.0003 11.3337C20.3685 11.3337 20.667 11.6321 20.667 12.0003ZM12.667 12.0003C12.667 12.3685 12.3685 12.667 12.0003 12.667C11.6321 12.667 11.3337 12.3685 11.3337 12.0003C11.3337 11.6321 11.6321 11.3337 12.0003 11.3337C12.3685 11.3337 12.667 11.6321 12.667 12.0003Z" stroke="#363636" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

3
public/image/icon-park-outline_link.svg

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.4718 6.37661L6.57248 16.2766C5.44745 17.4018 4.81543 18.9278 4.81543 20.5189C4.81543 22.1101 5.44745 23.6361 6.57248 24.7613C7.12963 25.3184 7.79107 25.7604 8.51903 26.0619C9.24699 26.3635 10.0272 26.5187 10.8151 26.5187C11.6031 26.5187 12.3833 26.3635 13.1113 26.0619C13.8392 25.7604 14.5007 25.3184 15.0578 24.7613L26.8431 12.9766C27.2147 12.6052 27.5094 12.1642 27.7104 11.6788C27.9115 11.1935 28.015 10.6733 28.015 10.1479C28.015 9.6226 27.9115 9.1024 27.7104 8.61705C27.5094 8.1317 27.2147 7.69072 26.8431 7.31927C26.4717 6.94777 26.0307 6.65307 25.5454 6.45201C25.06 6.25095 24.5398 6.14746 24.0145 6.14746C23.4891 6.14746 22.9689 6.25095 22.4836 6.45201C21.9982 6.65307 21.5573 6.94777 21.1858 7.31927L9.40115 19.1046C9.2154 19.2903 9.06805 19.5108 8.96752 19.7535C8.86699 19.9962 8.81524 20.2563 8.81524 20.5189C8.81524 20.7816 8.86699 21.0417 8.96752 21.2844C9.06805 21.5271 9.2154 21.7476 9.40115 21.9333C9.7762 22.3082 10.2848 22.5188 10.8151 22.5188C11.3455 22.5188 11.8541 22.3082 12.2291 21.9333L22.1291 12.0333" stroke="#212121" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

4
public/image/link-simple.svg

@ -0,0 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.17177 14.8286L14.8286 9.17177M6.34334 10.586L4.57557 12.3537C2.62295 14.3064 2.62295 17.4722 4.57557 19.4248V19.4248C6.52819 21.3774 9.69402 21.3774 11.6466 19.4248L13.4144 17.657M10.586 6.34334L12.3537 4.57557C14.3064 2.62295 17.4722 2.62295 19.4248 4.57557V4.57557C21.3774 6.5282 21.3774 9.69402 19.4248 11.6466L17.657 13.4144" stroke="#222222" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9.17177 14.8286L14.8286 9.17177M6.34334 10.586L4.57557 12.3537C2.62295 14.3064 2.62295 17.4722 4.57557 19.4248V19.4248C6.52819 21.3774 9.69402 21.3774 11.6466 19.4248L13.4144 17.657M10.586 6.34334L12.3537 4.57557C14.3064 2.62295 17.4722 2.62295 19.4248 4.57557V4.57557C21.3774 6.5282 21.3774 9.69402 19.4248 11.6466L17.657 13.4144" stroke="#222222" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

3
public/image/microphone-01.svg

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M25.3337 13.3337V16.0003C25.3337 21.155 21.155 25.3337 16.0003 25.3337M6.66699 13.3337V16.0003C6.66699 21.155 10.8457 25.3337 16.0003 25.3337M16.0003 25.3337V29.3337M10.667 29.3337H21.3337M16.0003 20.0003C13.7912 20.0003 12.0003 18.2095 12.0003 16.0003V6.66699C12.0003 4.45785 13.7912 2.66699 16.0003 2.66699C18.2095 2.66699 20.0003 4.45785 20.0003 6.66699V16.0003C20.0003 18.2095 18.2095 20.0003 16.0003 20.0003Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

3
public/image/send-01.svg

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7 12L4.83771 17.7661C4.52632 18.5965 5.36976 19.3912 6.18018 19.031L19.9439 12.9138C20.7357 12.5619 20.7357 11.4381 19.9439 11.0862L6.18018 4.96897C5.36976 4.60878 4.52632 5.40351 4.83771 6.2339L7 12ZM7 12H13" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

10
src/components/chat/chat-input.tsx

@ -1,13 +1,13 @@
import { PiTrash } from "react-icons/pi";
import Image from "next/image";
import SendIcon from "public/assets/images/send-01.svg";
import MicIcon from "public/assets/images/microphone-01.svg";
import LinkIcon from "public/assets/images/link-simple.svg";
import SmileIcon from "public/assets/images/face-smile.svg";
import SendIcon from "public/image/send-01.svg";
import MicIcon from "public/image/microphone-01.svg";
import LinkIcon from "public/image/link-simple.svg";
import SmileIcon from "public/image/face-smile.svg";
import { MdClose } from "react-icons/md";
import { useEffect, useState, useRef } from "react";
import { useWebSocket } from "@/contexts/WebSocket.context";
import FileInput from "../ui/file-input";
import FileInput from "./file-input";
import dynamic from "next/dynamic";
import EmojiPicker from "emoji-picker-react";
import { BsFillReplyFill } from "react-icons/bs";

80
src/components/chat/file-input.tsx

@ -0,0 +1,80 @@
import { useWebSocket } from "@/contexts/WebSocket.context";
import Image from "next/image";
import FaPlus from "public/image/icon-park-outline_link.svg";
import { useEffect, useState } from "react";
import { toast } from "react-toastify"; // Import toast from react-toastify
import "react-toastify/dist/ReactToastify.css"; // Import CSS for toast
// Define the allowed image, video, and audio extensions
const IMAGE_EXTENSIONS = ["jpg", "jpeg", "png", "gif", "bmp", "tiff", "webp", "svg"];
const VIDEO_EXTENSIONS = ["mp4", "mkv", "webm", "avi", "mov", "flv", "wmv"];
const AUDIO_EXTENSIONS = ["mp3", "wav", "ogg", "flac", "aac", "m4a"];
const getFileType = (extension : string) => {
const ext = extension.toLowerCase();
// Check if it's an image
if (IMAGE_EXTENSIONS.includes(ext)) {
return "image";
}
// Check if it's a video
if (VIDEO_EXTENSIONS.includes(ext)) {
return "video";
}
// Check if it's an audio file
if (AUDIO_EXTENSIONS.includes(ext)) {
return "audio";
}
// Everything else is a generic file
return "file";
};
const FileInput = () => {
const {setLoadingMessage} = useWebSocket()
const { sendFile } = useWebSocket();
const [file, setFile] = useState(null); // To store the selected file
const MAX_FILE_SIZE = 300 * 1024 * 1024; // 300 MB in bytes
const handleFileChange = async (event : any) => {
const selectedFile = event.target.files[0];
if (selectedFile) {
// Check file size
if (selectedFile.size > MAX_FILE_SIZE) {
toast.error("File is too large. Please select a file smaller than 300 MB.");
return; // Prevent further processing if the file is too large
}
selectedFile.status = "loading"
setLoadingMessage((prev) => [...prev, selectedFile]);
}
};
// Send the file when it's available
return (
<div>
{/* Hidden file input */}
<input
id="file-input"
type="file"
className="hidden"
onChange={handleFileChange} // Handle file change
/>
{/* Label triggers the file input */}
<label
htmlFor="file-input" // This associates the label with the file input
className="text-white px-3 py-2 rounded-md transition flex content-center hover:bg-slate-100"
>
<Image width={25} height={25} src={FaPlus} />
</label>
</div>
);
};
export default FileInput;

6
src/components/chat/file-message.tsx

@ -19,6 +19,8 @@ const fileTypes = {
};
const FileMessage = ({ file }) => {
console.log( "file Message",file);
const { sendFile } = useWebSocket();
const [percentage, setPercentage] = useState(1);
const isLoading = file.status === "loading";
@ -95,7 +97,9 @@ const FileMessage = ({ file }) => {
})
.then((res) => {
const fileType = getFileType(fileExtension);
sendFile({ ...res.data, type: fileType });
console.log("file sent");
sendFile({ ...res, type: fileType });
})
.catch((err) => console.error(err));
}

99
src/components/chat/message.tsx

@ -1,26 +1,26 @@
import { useState, useEffect, useCallback, useRef } from "react";
import { useRouter } from "next/router";
import ContextMenu from "./contex-menu"; // Import the ContextMenu component
import Image from "next/image";
import Seen from "public/image/quill_checkmark-double.svg";
import UnSeen from "public/image/State=Send.svg";
import Pending from "public/image/clock-fast-forward.png";
import { useWebSocket } from "@/contexts/WebSocket.context";
import Button from "../ui/button";
import { Routes as ROUTES } from "@/config/routes";
import { useState, useEffect, useCallback, useRef } from 'react';
import { useRouter } from 'next/router';
import ContextMenu from './contex-menu'; // Import the ContextMenu component
import Image from 'next/image';
import Seen from 'public/image/quill_checkmark-double.svg';
import UnSeen from 'public/image/State=Send.svg';
import Pending from 'public/image/clock-fast-forward.png';
import { useWebSocket } from '@/contexts/WebSocket.context';
import Button from '../ui/button';
import { Routes as ROUTES } from '@/config/routes';
import { HttpClient as http } from "@/data/client/http-client";
import FileMessage from "./file-message";
import ImageMessage from "./image-message";
import AudioMessage from "./audio-message";
import { HttpClient as http } from '@/data/client/http-client';
import FileMessage from './file-message';
import ImageMessage from './image-message';
import AudioMessage from './audio-message';
const Message = ({ msg }) => {
const isFileMessage = msg.status || msg?.mime_type === "file" ? true : false;
const isFileMessage = msg.status || msg?.mime_type === 'file' ? true : false;
const isLoadingMessage = msg.status ? true : false;
const isAudioMessage = msg?.mime_type === "audio" ? true : false;
const isAudioMessage = msg?.mime_type === 'audio' ? true : false;
const isImageMessage =
msg?.mime_type === "image" || msg?.mime_type === "video" ? true : false;
const isTextMessage = msg.mime_type === "text" ? true : false;
msg?.mime_type === 'image' || msg?.mime_type === 'video' ? true : false;
const isTextMessage = msg.mime_type === 'text' ? true : false;
if (isLoadingMessage) {
return <FileMessage file={msg} />;
}
@ -46,7 +46,7 @@ const Message = ({ msg }) => {
const date = new Date(timestamp);
let hours = date.getHours();
const minutes = date.getMinutes();
const ampm = hours >= 12 ? "PM" : "AM";
const ampm = hours >= 12 ? 'PM' : 'AM';
hours %= 12;
hours = hours || 12; // Convert '0' to '12'
@ -55,16 +55,15 @@ const Message = ({ msg }) => {
return `${hours}:${formattedMinutes} ${ampm}`;
}, []);
// Handlers for context menu actions
const handleCopy = useCallback(() => {
navigator.clipboard
.writeText(typeof msg === "string" ? msg : msg.content)
.writeText(typeof msg === 'string' ? msg : msg.content)
.then(() => {
console.log("Copied to clipboard");
console.log('Copied to clipboard');
})
.catch((err) => {
console.error("Failed to copy: ", err);
console.error('Failed to copy: ', err);
});
setShowMenu(false);
}, [msg]);
@ -85,7 +84,7 @@ const Message = ({ msg }) => {
e.preventDefault();
setShowMenu((prev) => !prev);
},
[setShowMenu]
[setShowMenu],
);
// Close menu if clicked outside
@ -100,43 +99,43 @@ const Message = ({ msg }) => {
setShowMenu(false);
}
},
[menuRef, messageRef]
[menuRef, messageRef],
);
// Handle escape key to close menu
const handleKeyDown = useCallback(
(e) => {
if (e.key === "Escape") {
if (e.key === 'Escape') {
setShowMenu(false);
}
},
[setShowMenu]
[setShowMenu],
);
useEffect(() => {
if (showMenu) {
document.addEventListener("mousedown", handleClickOutside);
document.addEventListener("keydown", handleKeyDown);
document.addEventListener('mousedown', handleClickOutside);
document.addEventListener('keydown', handleKeyDown);
} else {
document.removeEventListener("mousedown", handleClickOutside);
document.removeEventListener("keydown", handleKeyDown);
document.removeEventListener('mousedown', handleClickOutside);
document.removeEventListener('keydown', handleKeyDown);
}
// Cleanup on unmount
return () => {
document.removeEventListener("mousedown", handleClickOutside);
document.removeEventListener("keydown", handleKeyDown);
document.removeEventListener('mousedown', handleClickOutside);
document.removeEventListener('keydown', handleKeyDown);
};
}, [showMenu, handleClickOutside, handleKeyDown]);
const isStringMessage = typeof msg === "string";
const isStringMessage = typeof msg === 'string';
const messageContent = isStringMessage ? msg : msg.content;
const messageKey = isStringMessage ? msg : msg.id;
const messageTime = isStringMessage
? formatTime()
: formatTime(msg.created_at);
const isUser = !isStringMessage && msg?.by_user?.account_type === "user";
const isUser = !isStringMessage && msg?.by_user?.account_type === 'merchant';
const isSeen = !isStringMessage && msg?.is_read;
const product =
!isStringMessage && Object.keys(msg?.product_reply).length
@ -161,14 +160,14 @@ const Message = ({ msg }) => {
key={messageKey}
className={`rounded-lg border p-2 mb-2 max-w-[525px] flex flex-col whitespace-pre-line break-words relative ${
isUser
? "self-end bg-[#323232] text-white"
? 'self-end bg-[#323232] text-white'
: isStringMessage
? "self-end bg-[#323232] text-white"
: "self-start bg-white text-gray-800"
? 'self-end bg-[#323232] text-white'
: 'self-start bg-white text-gray-800'
}`}
tabIndex={0}
onKeyDown={(e) => {
if (e.key === "ContextMenu" || (e.shiftKey && e.key === "F10")) {
if (e.key === 'ContextMenu' || (e.shiftKey && e.key === 'F10')) {
e.preventDefault();
setShowMenu(true);
}
@ -184,28 +183,30 @@ const Message = ({ msg }) => {
onDelete={handleDelete}
menuRef={menuRef}
isUser={isUser}
className={isUser ? "-right-2" : ""}
className={isUser ? '-right-2' : ''}
/>
{/* Render file message */}
{product && (
<div
className={`w-[510px] border rounded-lg mb-4 ${
className={`w-full border rounded-lg mb-4 ${
isUser
? "border-[#626262] bg-[#3F3F3F] text-[#F2F2F2]"
: "border-[#D8D8D8] bg-[#F2F2F2] text-black "
? 'border-[#626262] bg-[#3F3F3F] text-[#F2F2F2]'
: 'border-[#D8D8D8] bg-[#F2F2F2] text-black '
} p-3`}
>
<div className="flex mb-4">
<div>
{product?.get_first_image && (
<Image
className="rounded-lg"
width={130}
height={130}
src={product?.get_first_image}
alt='product'
/>
</div>
)}
<div></div>
<div className="flex flex-col justify-between">
<p
className={`font-bold text-2xl w-96 mb-0 px-3 overflow-hidden text-ellipsis whitespace-nowrap`}
@ -223,17 +224,17 @@ const Message = ({ msg }) => {
<div className="flex gap-4 justify-between">
<Button
onClick={() => {
router.push(`${ROUTES.PRODUCT}/${product.slug}`, undefined, {
router.push(`https://mesbahi.nwhco.ir/products/${product.slug}`, undefined, {
locale: router.locale,
});
}}
className="w-full bg-[#C5C5C5]"
className="w-[calc(50%-12px)] bg-[#C5C5C5]"
>
Product details
</Button>
<Button
className={`w-full ${
isUser && "bg-white"
className={`w-[calc(50%-12px)] ${
isUser && 'bg-white'
} !text-black hover:!text-white`}
>
Add to cart

2
src/components/chat/messages-list.tsx

@ -51,7 +51,7 @@ const MessageList = ({ messages }) => {
role="log" // Optional: Improves accessibility
aria-live="polite" // Optional: Announces new messages to screen readers
style={{
backgroundImage: "url('/assets/images/Frame 48098164.svg')", // Replace with your image path
backgroundImage: "url('/dashboard/image/Frame-48098164.svg')", // Replace with your image path
backgroundSize: "conrain",
backgroundPosition: "center",
}}

2
src/components/product/form-utils.ts

@ -262,7 +262,7 @@ export function getProductInputValues(
tags: tags.map((tag) => tag?.id),
images: omitTypename<any>(images),
is_active : values.is_active === "publish" ? true : false ,
discount : `${values.discount}` ,
discount : values.discount ,
...(product_type?.value === ProductType?.Simple && {
quantity,
...(is_digital && {

22
src/contexts/WebSocket.context.tsx

@ -8,7 +8,8 @@ import React, {
} from "react";
import { useRouter } from "next/router";
import { useMeQuery } from "@/data/user";
import { AUTH_CRED } from "@/utils/constants";
import Cookies from "js-cookie";
interface WebSocketData {
event: string;
token?: string;
@ -53,7 +54,7 @@ interface WebSocketProviderProps {
export const WebSocketProvider: React.FC<WebSocketProviderProps> = ({
children,
}) => {
const { user } = useMeQuery()
// const { data : user } = useMeQuery()
const [chatRooms, setChatRooms] = useState<ChatRoom[]>([]);
const [roomInfo, setRoomInfo] = useState<ChatRoom[]>([]);
const [messages, setMessages] = useState<[]>([]);
@ -63,30 +64,32 @@ export const WebSocketProvider: React.FC<WebSocketProviderProps> = ({
const [editingMessage, setEditingMessage] = useState({});
const [roomID, setRommID] = useState<number>();
const [nextPage, setNextPage] = useState(2);
const router = useRouter();
const userID = router.query.room;
const {
query: { slug },
} = router;
const token = Cookies.get(AUTH_CRED)
const getRooms = () => {
socketRef.current?.send(
JSON.stringify({
event: "get_rooms",
account_type: "user",
account_type: "merchant",
page: "1",
per_page: "16",
} as WebSocketData)
);
};
console.log(user);
console.log(token);
useEffect(() => {
socketRef.current = new WebSocket("wss://mesbahi.nwhco.ir/chat/ws");
setMessages([]);
if (user?.token) {
if (token) {
socketRef.current.onopen = () => {
console.log("WebSocket Connected");
@ -94,7 +97,7 @@ export const WebSocketProvider: React.FC<WebSocketProviderProps> = ({
socketRef.current?.send(
JSON.stringify({
event: "connect",
token: user?.token, // Pass user token
token: JSON.parse(token),
})
);
if (socketRef.current?.readyState === WebSocket.OPEN) {
@ -179,7 +182,7 @@ export const WebSocketProvider: React.FC<WebSocketProviderProps> = ({
socketRef.current.close();
}
};
}, [user, userID]);
}, [token , userID]);
const getNextPage = () => {
setNextPage((prevPage) => {
@ -244,6 +247,7 @@ export const WebSocketProvider: React.FC<WebSocketProviderProps> = ({
},
id?: number
) => {
if (socketRef.current && connected) {
if (!file) return; // Avoid sending empty messages

2
src/data/client/user.ts

@ -28,6 +28,8 @@ export const userClient = {
return HttpClient.get<User>(API_ENDPOINTS.ME);
},
login: (variables: {password : string ,phone_number : string , user_type: 'merchant'}) => {
console.log("LOGING IN");
return HttpClient.post<AuthResponse>(API_ENDPOINTS.TOKEN, variables);
},
logout: () => {

2
src/data/shop.ts

@ -96,6 +96,8 @@ export const useShopQuery = (options?: any) => {
return useQuery<Shop, Error>(
API_ENDPOINTS.GET_SHOPS,
() => shopClient.get().then((data) => {
console.log(data);
return data;
}),
{

6
src/pages/chat/chat-box.tsx

@ -1,6 +1,6 @@
import ContactInfo from "@/components/chat/contact-info";
import MessageList from "@/components/chat/messages-list";
import Input from "@/components/ui/input";
import Input from "@/components/chat/chat-input";
import { useWebSocket } from "@/contexts/WebSocket.context";
import noMessages from "public/image/Frame 1000005529.svg";
import { useRouter } from "next/router";
@ -25,10 +25,10 @@ export default function ChatBox({ product , searchValue }) {
}
return (
<div className="relative flex flex-col w-full h-[calc(100%+65px)] bg-white shadow-md border border-[#D9D9D9]">
<div className="relative flex flex-col w-full h-[calc(100%+62px)] bg-white shadow-md border border-[#D9D9D9]">
<ContactInfo />
<div className="relative flex h-full">
<div className="relative flex h-full">
{/* Chat Content */}
<MessageList messages={messages} />

2
src/pages/chat/converstions.tsx

@ -54,7 +54,7 @@ export default function Conversations() {
};
return (
<div className="border border-[#D9D9D9] h-[calc(100%+65px)]">
<div className="border border-[#D9D9D9] h-[calc(100%+62px)]">
<div className="bg-white shadow rounded-md h-full w-[450px] mx-auto">
{/* Header Section */}
<div className="border-b border-[#D9D9D9] justify-end flex flex-row-reverse h-24 items-center p-4">

27
src/pages/shop/index.tsx

@ -40,6 +40,7 @@ import { useFormatPhoneNumber } from '@/utils/format-phone-number';
import { useSettingsQuery } from '@/data/settings';
import { IosArrowDown } from '@/components/icons/ios-arrow-down';
import { OWNERSHIP_TRANSFER_STATUS } from '@/utils/constants';
import { useGetActiveSubscription } from '@/data/subscription';
export default function ShopPage() {
const router = useRouter();
@ -53,12 +54,8 @@ export default function ShopPage() {
const { settings } = useSettingsQuery({
language: locale!,
});
const {
data,
isLoading: loading,
error,
} = useShopQuery();
console.log(data);
const { data, isLoading: loading, error } = useShopQuery();
const {data : subscription} = useGetActiveSubscription()
const { price: totalEarnings } = usePrice(
data && {
@ -79,7 +76,6 @@ export default function ShopPage() {
if (error) return <ErrorMessage message={error.message} />;
const {
name,
is_active,
logo,
cover_image,
description,
@ -93,13 +89,11 @@ export default function ShopPage() {
id: shop_id,
ownership_history,
} = data ?? {};
const has_shop = data?.detail !== 'No merchant associated with this merchant account.';
if (
!hasAccess(adminOnly, permissions) &&
!me?.shops?.map((shop) => shop.id).includes(shop_id) &&
me?.managed_shop?.id != shop_id
) {
router.replace(Routes.dashboard);
const is_active = subscription?.status !== "no_subscription"
if (!has_shop) {
router.replace(Routes.shop.create);
}
return (
@ -203,10 +197,12 @@ export default function ShopPage() {
<div className="self-end pt-4 xl:pt-0 space-x-4">
<Link
className="inline-flex items-center gap-1 rounded-full bg-accent px-[0.625rem] py-[0.5625rem] text-xs font-medium text-white hover:bg-accent-hover"
href={`/shop/edit`}
href={has_shop ? `/shop/edit` : `/shop/create`}
>
<EditFillIcon />
{t('common:text-edit-shop')}
{!has_shop
? t('common:text-edit-shop')
: t('common:text-create-shop')}
</Link>
{!OWNERSHIP_TRANSFER_STATUS?.includes(
@ -308,4 +304,3 @@ export const getStaticProps = async ({ locale }: any) => ({
...(await serverSideTranslations(locale, ['form', 'common', 'table'])),
},
});
Loading…
Cancel
Save