feat : add modal details
This commit is contained in:
@@ -36,13 +36,16 @@ export default function MuiModal({
|
|||||||
className="relative w-full h-full flex justify-center items-center border-none outline-none"
|
className="relative w-full h-full flex justify-center items-center border-none outline-none"
|
||||||
>
|
>
|
||||||
<motion.div
|
<motion.div
|
||||||
className="max-md:max-w-72 md:w-80 lg:w-96 min-h-80 shadow-xl shadow-[rgb(20,20,20)] bg-[rgb(20,20,20,0.99)] rounded-lg p-4 relative flex flex-col justify-between items-center gap-4"
|
className="max-md:w-72 md:w-80 lg:w-96 min-h-80 shadow-xl shadow-[rgb(20,20,20)] bg-[rgb(20,20,20,0.99)] rounded-lg p-4 relative flex flex-col justify-between items-center gap-4"
|
||||||
initial={{ y: "-100vw" }}
|
initial={{ y: "-100vw" }}
|
||||||
animate={{ y: 0 }}
|
animate={{ y: 0 }}
|
||||||
>
|
>
|
||||||
<motion.div className="w-full h-full flex justify-between">
|
<motion.div className="w-full h-full flex gap-2 justify-between">
|
||||||
<h1 className="text-lg md:text-xl font-bold">
|
<h1 className="text-lg md:text-xl font-bold">
|
||||||
{title} {nameService && <span className="text-green-600"> {nameService} </span>}
|
{title && title}
|
||||||
|
{nameService && (
|
||||||
|
<span className="text-green-600"> {nameService} </span>
|
||||||
|
)}
|
||||||
</h1>
|
</h1>
|
||||||
<button onClick={handleClose}>
|
<button onClick={handleClose}>
|
||||||
<IoClose className="w-7 h-7" />
|
<IoClose className="w-7 h-7" />
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ const Alert = ({ children, type = "info", message }: AlertProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`flex items-center p-4 mb-4 text-sm ${text} rounded-lg ${bg} ${darkText} ${darkBg}`}
|
className={`w-full h-full flex items-center p-4 mb-4 text-xs md:text-sm ${text} rounded-lg ${bg} ${darkText} ${darkBg}`}
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
@@ -71,7 +71,7 @@ const Alert = ({ children, type = "info", message }: AlertProps) => {
|
|||||||
</svg>
|
</svg>
|
||||||
<span className="sr-only">{children}</span>
|
<span className="sr-only">{children}</span>
|
||||||
<div>
|
<div>
|
||||||
<span className="font-medium">{children}</span> {message}
|
<span className="font-medium">{children}</span> {message && message}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import ConfigItem from "./components/ConfigItem";
|
import ConfigItem from "./components/ConfigItem";
|
||||||
|
import ProfileImage from "./components/ProfileImage";
|
||||||
|
|
||||||
const ProductConfigList = () => {
|
const ProductConfigList = () => {
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full p-4 glass flex flex-col gap-3 pt-14">
|
<div className="w-full h-full p-5 glass flex flex-col gap-3">
|
||||||
|
<ProfileImage />
|
||||||
<p className="max-md:text-lg text-xl font-bold text-center">
|
<p className="max-md:text-lg text-xl font-bold text-center">
|
||||||
لیست کانفیگ ها
|
لیست کانفیگ ها
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ const ProfileDetails = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="relative z-[10] w-full h-32 max-md:h-20 flex flex-row-reverse justify-between glass items-center py-2 px-4">
|
<div className="relative z-[10] w-full h-32 max-md:h-20 flex flex-row-reverse justify-between glass items-center py-2 px-4">
|
||||||
<EditProfile />
|
<EditProfile />
|
||||||
<ProfileImage />
|
|
||||||
<ProductDetails />
|
<ProductDetails />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -21,7 +20,7 @@ const EditProfile = () => {
|
|||||||
<div className="w-full h-full flex justify-end items-center">
|
<div className="w-full h-full flex justify-end items-center">
|
||||||
<ModalEditProfile isOpen={isOpen} setIsOpen={setIsOpen} />
|
<ModalEditProfile isOpen={isOpen} setIsOpen={setIsOpen} />
|
||||||
<Button
|
<Button
|
||||||
extra="!py-4 max-md:!py-2 max-md:px-2 md:ml-4"
|
extra="!py-4 max-md:!py-2 max-md:px-2"
|
||||||
onClick={() => setIsOpen(true)}
|
onClick={() => setIsOpen(true)}
|
||||||
>
|
>
|
||||||
<MdEdit className="scale-[1.4] max-md:scale-100" />
|
<MdEdit className="scale-[1.4] max-md:scale-100" />
|
||||||
@@ -30,29 +29,17 @@ const EditProfile = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const ProfileImage = () => {
|
|
||||||
return (
|
|
||||||
<div className="relative w-full h-full flex justify-center items-center">
|
|
||||||
<div className="absolute w-auto h-auto border-4 border-secondTheme rounded-full max-md:scale-90 max-md:top-1/3 top-1/2">
|
|
||||||
<svg height="100" width="100" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<circle r="45" cx="50" cy="50" fill="#111" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const ProductDetails = () => {
|
const ProductDetails = () => {
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full flex justify-start items-center">
|
<div className="w-full h-full flex justify-start items-center">
|
||||||
<div className="md:mr-4 w-auto h-auto flex flex-col max-md:text-[12px] text-lg md:gap-2">
|
<div className="md:mr-4 w-auto h-auto flex flex-col max-md:text-[12px] text-lg md:gap-2">
|
||||||
<p className="text-nowrap">
|
<p className="text-nowrap">
|
||||||
کانفیگ های فعال :{" "}
|
کانفیگ های فعال :{" "}
|
||||||
<span className="px-2 rounded-md bg-green-600"> 2 </span>
|
<span className="px-1 md:px-2 rounded-md bg-green-600"> 2 </span>
|
||||||
</p>
|
</p>
|
||||||
<p className="text-nowrap">
|
<p className="text-nowrap">
|
||||||
کانفیگ های غیر فعال :{" "}
|
کانفیگ های غیر فعال :{" "}
|
||||||
<span className="px-2 rounded-md bg-yellow-400"> 10 </span>
|
<span className="px-1 md:px-2 rounded-md bg-yellow-400"> 10 </span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,34 +1,63 @@
|
|||||||
import { IoCopy } from "react-icons/io5";
|
import { IoCopy } from "react-icons/io5";
|
||||||
import Button from "../../../../components/button";
|
import Button from "../../../../components/button";
|
||||||
import { ConfigItemProps } from "../../../../types/props";
|
import { ConfigItemProps } from "../../../../types/props";
|
||||||
|
import ModalConfigDetails from "./ModalConfigDetails";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
const ConfigItem = ({ dateBuy, configName, isDisabled }: ConfigItemProps) => {
|
const ConfigItem = ({ dateBuy, configName, isDisabled }: ConfigItemProps) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
return (
|
return (
|
||||||
<div className="relative w-full h-full rounded-md">
|
<>
|
||||||
{isDisabled && (
|
<ModalConfigDetails
|
||||||
<div className="absolute inset-0 flex items-center justify-center bg-opacity-50 rounded-md backdrop-blur-sm z-10">
|
isOpen={isOpen}
|
||||||
<p className="text-white font-bold px-1 bg-red-600 text-xs md:text-base rounded-md shadow-md shadow-red-600">
|
setIsOpen={setIsOpen}
|
||||||
کانفیگ <span className="text-secondTheme">{configName}</span> غیر فعال است
|
dateBuy={dateBuy}
|
||||||
</p>
|
isDisabled={isDisabled}
|
||||||
</div>
|
nameConfig={configName}
|
||||||
)}
|
/>
|
||||||
<div
|
<div className="relative w-full h-full rounded-md">
|
||||||
className={`w-full h-full p-3 rounded-md text-xs md:text-base gap-2 flex justify-between items-center text-secondTheme bg-gray-900 shadow-md shadow-gray-900 ${
|
{isDisabled && (
|
||||||
isDisabled ? "filter blur-sm" : ""
|
<div className="absolute inset-0 flex items-center justify-center bg-opacity-50 rounded-md backdrop-blur-sm z-10">
|
||||||
}`}
|
<p className="text-white font-bold px-1 bg-red-600 text-xs md:text-base rounded-md shadow-md shadow-red-600">
|
||||||
>
|
کانفیگ <span className="text-secondTheme">{configName}</span> غیر
|
||||||
<p>تاریخ خرید : {dateBuy}</p>
|
فعال است .{" "}
|
||||||
<li className="px-2 py-1 bg-secondTheme shadow-md shadow-secondTheme rounded-md w-auto h-auto text-gray-900 font-bold list-none">
|
<span
|
||||||
{configName}
|
className="text-secondTheme cursor-pointer"
|
||||||
</li>
|
onClick={() => setIsOpen(true)}
|
||||||
<div className="flex flex-row-reverse gap-2 justify-end items-center">
|
>
|
||||||
<Button extra="!m-0 !px-2 !py-1.5 shadow-md shadow-white">
|
تمدید
|
||||||
<IoCopy />
|
</span>
|
||||||
</Button>
|
</p>
|
||||||
<Button extra="!m-0 !px-2 !py-1 shadow-md shadow-white">آموزش</Button>
|
</div>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
className={`w-full h-full p-3 rounded-md text-xs md:text-base gap-2 flex justify-between items-center text-secondTheme bg-gray-900 shadow-md shadow-gray-900 ${
|
||||||
|
isDisabled ? "filter blur-sm" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<p className="max-md:hidden">تاریخ خرید : {dateBuy}</p>
|
||||||
|
<li className="px-2 py-1 bg-secondTheme shadow-md shadow-secondTheme rounded-md w-auto h-auto text-gray-900 font-bold list-none">
|
||||||
|
{configName}
|
||||||
|
</li>
|
||||||
|
<div className="max-md:hidden flex flex-row-reverse gap-2 justify-end items-center">
|
||||||
|
<Button extra="!m-0 !px-2 !py-1.5 shadow-md shadow-white">
|
||||||
|
<IoCopy />
|
||||||
|
</Button>
|
||||||
|
<Button extra="!m-0 !px-2 !py-1 shadow-md shadow-white">
|
||||||
|
آموزش
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="md:hidden flex flex-row-reverse gap-2 justify-end items-center">
|
||||||
|
<Button
|
||||||
|
extra="!m-0 !px-2 !py-1 shadow-md shadow-white"
|
||||||
|
onClick={() => setIsOpen(true)}
|
||||||
|
>
|
||||||
|
مشاهده جزئیات
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default ConfigItem;
|
export default ConfigItem;
|
||||||
|
|||||||
53
src/pages/profile/section/components/ModalConfigDetails.tsx
Normal file
53
src/pages/profile/section/components/ModalConfigDetails.tsx
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { Dispatch, SetStateAction } from "react";
|
||||||
|
import MuiModal from "../../../../common/modal";
|
||||||
|
import Button from "../../../../components/button";
|
||||||
|
import { IoCopy } from "react-icons/io5";
|
||||||
|
import Alert from "../../../../components/alert/Alert";
|
||||||
|
|
||||||
|
const ModalConfigDetails = ({
|
||||||
|
isOpen,
|
||||||
|
setIsOpen,
|
||||||
|
isDisabled,
|
||||||
|
dateBuy,
|
||||||
|
nameConfig,
|
||||||
|
}: {
|
||||||
|
isOpen: boolean;
|
||||||
|
setIsOpen: Dispatch<SetStateAction<boolean>>;
|
||||||
|
isDisabled: boolean;
|
||||||
|
dateBuy: string;
|
||||||
|
nameConfig: string;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<MuiModal
|
||||||
|
isOpenModal={isOpen}
|
||||||
|
setIsOpenModal={setIsOpen}
|
||||||
|
submitText="باشه"
|
||||||
|
nameService={nameConfig}
|
||||||
|
>
|
||||||
|
{isDisabled && <Alert type="warning"> {nameConfig} غیر فعال است </Alert>}
|
||||||
|
<div className="w-full h-full flex flex-col p-3 gap-4 border-2 border-gray-800 rounded-md max-sm:text-xs max-md:text-sm text-base">
|
||||||
|
<h1 className="w-full h-full text-center rounded-md p-1 md:p-2 bg-gray-800">
|
||||||
|
تاریخ خرید : {dateBuy}
|
||||||
|
</h1>
|
||||||
|
<div className="w-full h-full flex flex-row-reverse gap-2 justify-center items-center">
|
||||||
|
{isDisabled ? (
|
||||||
|
<Button extra="!m-0 !px-2 !py-1 shadow-md shadow-secondTheme !bg-secondTheme ">
|
||||||
|
تمدید
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Button extra="!m-0 !px-2 !py-1.5 shadow-md shadow-white">
|
||||||
|
<IoCopy />
|
||||||
|
</Button>
|
||||||
|
<Button extra="!m-0 !px-2 !py-1 shadow-md shadow-white">
|
||||||
|
آموزش
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</MuiModal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalConfigDetails;
|
||||||
13
src/pages/profile/section/components/ProfileImage.tsx
Normal file
13
src/pages/profile/section/components/ProfileImage.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
const ProfileImage = () => {
|
||||||
|
return (
|
||||||
|
<div className="relative w-full h-full flex justify-center items-center">
|
||||||
|
<div className="relative w-auto h-auto border-4 border-secondTheme rounded-full max-md:scale-90">
|
||||||
|
<svg height="100" width="100" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<circle r="45" cx="50" cy="50" fill="#111" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ProfileImage;
|
||||||
5
src/types/props.d.ts
vendored
5
src/types/props.d.ts
vendored
@@ -4,7 +4,7 @@ export type MessageType = "info" | "danger" | "success" | "warning" | "dark";
|
|||||||
export interface AlertProps {
|
export interface AlertProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
type?: "info" | "danger" | "success" | "warning" | "dark";
|
type?: "info" | "danger" | "success" | "warning" | "dark";
|
||||||
message: string;
|
message?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// begin Button.tsx
|
// begin Button.tsx
|
||||||
@@ -99,7 +99,7 @@ export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
|||||||
export interface MuiModalProps {
|
export interface MuiModalProps {
|
||||||
isOpenModal: boolean;
|
isOpenModal: boolean;
|
||||||
setIsOpenModal: SetStateAction;
|
setIsOpenModal: SetStateAction;
|
||||||
title: string;
|
title?: string;
|
||||||
nameService?: string;
|
nameService?: string;
|
||||||
submitText: string;
|
submitText: string;
|
||||||
submitOnClick?: () => void;
|
submitOnClick?: () => void;
|
||||||
@@ -111,3 +111,4 @@ export interface ConfigItemProps {
|
|||||||
configName: string;
|
configName: string;
|
||||||
isDisabled: boolean;
|
isDisabled: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user