Amir Hossein Khademi 2024-10-20 13:54:37 +03:30
commit 1724ff78b8
38 changed files with 958 additions and 211 deletions

View File

@ -1,5 +1,5 @@
"use client"; "use client";
import React from "react";
import "../../style/globals.css"; import "../../style/globals.css";
import { Inter } from "next/font/google"; import { Inter } from "next/font/google";
import "../../style/fontiran.css"; import "../../style/fontiran.css";
@ -25,12 +25,7 @@ import moment from "jalali-moment";
const inter = Inter({ subsets: ["latin"] }); const inter = Inter({ subsets: ["latin"] });
// export const metadata = { const RootData = ({ children }) => {
// title: "Create Next App",
// description: "Generated by create next app",
// };
export default function RootLayout({ children }) {
// BottomSheet // BottomSheet
const [BottomSheetCreateRoleOpen, setBottomSheetCreateRoleOpen] = const [BottomSheetCreateRoleOpen, setBottomSheetCreateRoleOpen] =
useState(false); useState(false);
@ -1589,27 +1584,27 @@ export default function RootLayout({ children }) {
useEffect(() => { useEffect(() => {
console.log(` console.log(`
bbbbbbbb bbbbbbbb
b::::::b iiii b::::::b iiii
b::::::b i::::i b::::::b i::::i
b::::::b iiii b::::::b iiii
b:::::b b:::::b
b:::::bbbbbbbbb rrrrr rrrrrrrrr iiiiiiizzzzzzzzzzzzzzzzz cccccccccccccccc ooooooooooo b:::::bbbbbbbbb rrrrr rrrrrrrrr iiiiiiizzzzzzzzzzzzzzzzz cccccccccccccccc ooooooooooo
b::::::::::::::bb r::::rrr:::::::::ri:::::iz:::::::::::::::z cc:::::::::::::::coo:::::::::::oo b::::::::::::::bb r::::rrr:::::::::ri:::::iz:::::::::::::::z cc:::::::::::::::coo:::::::::::oo
b::::::::::::::::br:::::::::::::::::ri::::iz::::::::::::::z c:::::::::::::::::o:::::::::::::::o b::::::::::::::::br:::::::::::::::::ri::::iz::::::::::::::z c:::::::::::::::::o:::::::::::::::o
b:::::bbbbb:::::::rr::::::rrrrr::::::i::::izzzzzzzz::::::z c:::::::cccccc:::::o:::::ooooo:::::o b:::::bbbbb:::::::rr::::::rrrrr::::::i::::izzzzzzzz::::::z c:::::::cccccc:::::o:::::ooooo:::::o
b:::::b b::::::br:::::r r:::::i::::i z::::::z c::::::c cccccco::::o o::::o b:::::b b::::::br:::::r r:::::i::::i z::::::z c::::::c cccccco::::o o::::o
b:::::b b:::::br:::::r rrrrrri::::i z::::::z c:::::c o::::o o::::o b:::::b b:::::br:::::r rrrrrri::::i z::::::z c:::::c o::::o o::::o
b:::::b b:::::br:::::r i::::i z::::::z c:::::c o::::o o::::o b:::::b b:::::br:::::r i::::i z::::::z c:::::c o::::o o::::o
b:::::b b:::::br:::::r i::::i z::::::z c::::::c cccccco::::o o::::o b:::::b b:::::br:::::r i::::i z::::::z c::::::c cccccco::::o o::::o
b:::::bbbbbb::::::br:::::r i::::::i z::::::zzzzzzzc:::::::cccccc:::::o:::::ooooo:::::o b:::::bbbbbb::::::br:::::r i::::::i z::::::zzzzzzzc:::::::cccccc:::::o:::::ooooo:::::o
b::::::::::::::::b r:::::r i::::::iz::::::::::::::zc:::::::::::::::::o:::::::::::::::o b::::::::::::::::b r:::::r i::::::iz::::::::::::::zc:::::::::::::::::o:::::::::::::::o
b:::::::::::::::b r:::::r i::::::z:::::::::::::::z cc:::::::::::::::coo:::::::::::oo b:::::::::::::::b r:::::r i::::::z:::::::::::::::z cc:::::::::::::::coo:::::::::::oo
bbbbbbbbbbbbbbbb rrrrrrr iiiiiiizzzzzzzzzzzzzzzzz cccccccccccccccc ooooooooooo bbbbbbbbbbbbbbbb rrrrrrr iiiiiiizzzzzzzzzzzzzzzzz cccccccccccccccc ooooooooooo
soli chizi bood bgo hossein__masoomi soli chizi bood bgo hossein__masoomi
`); `);
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");
// if (!token) { // if (!token) {
// router.push("/app/login"); // router.push("/app/login");
@ -1619,7 +1614,6 @@ export default function RootLayout({ children }) {
CheckUser(); CheckUser();
} }
}, []); }, []);
return ( return (
<AppContext.Provider <AppContext.Provider
value={{ value={{
@ -1841,18 +1835,16 @@ export default function RootLayout({ children }) {
GetUnReadNotif, GetUnReadNotif,
}} }}
> >
<html lang="en"> {children}
<body className={inter.className}> {shouldRenderComponent && <NavBAr />}
{children} <ToastContainer position="bottom-right" closeOnClick={true} rtl />
{shouldRenderComponent && <NavBAr />} <Loading />
<ToastContainer position="bottom-right" closeOnClick={true} rtl /> <BottomSheetReport />
<Loading /> <BottomSheetReportManageShift />
<BottomSheetReport />
<BottomSheetReportManageShift />
{openTimePicker && <TimePicker />} {openTimePicker && <TimePicker />}
</body>
</html>
</AppContext.Provider> </AppContext.Provider>
); );
} };
export default RootData;

View File

@ -9,7 +9,8 @@ import SimpleReactValidator from "simple-react-validator";
import PersianNumber from "plugins/PersianNumber"; import PersianNumber from "plugins/PersianNumber";
import moment from "jalali-moment"; import moment from "jalali-moment";
const ActivityCardFake = ({ data }) => { const ActivityCardFake = ({ data, type }) => {
console.log("data", data);
const CTX = useContext(AppContext); const CTX = useContext(AppContext);
const [conditionTask, setConditionTask] = useState(0); const [conditionTask, setConditionTask] = useState(0);
@ -52,7 +53,7 @@ const ActivityCardFake = ({ data }) => {
return ( return (
<div <div
className={` p-3 overflow-hidden bg-[#11211e] rounded-2xl w-full realtive ${ className={` p-3 overflow-hidden bg-[#11211e] rounded-2xl w-full realtive ${
conditionTask == 3 || conditionTask == 3 ||
conditionTask == 4 || conditionTask == 4 ||
data?.status == 4 || data?.status == 4 ||
@ -60,19 +61,33 @@ const ActivityCardFake = ({ data }) => {
data?.status == 3 data?.status == 3
? "fuck-click " ? "fuck-click "
: "" : ""
}`} }${type == "fa" ? "rtl" : "ltr"}`}
> >
<div className="flex pl-3"> <div className="flex pl-3">
<div className="flex"> <div className="flex">
<div className="flex w-fit "> <div className="flex w-fit ">
<div className="relative text-[11px] text-primary-500"> <div className="relative text-[11px] text-primary-500">
{data?.scheduleType == 0 {type == "fa" ? (
? "daily" <>
: data?.scheduleType == 1 {data?.scheduleType == 0
? "weekly" ? "روزانه"
: data?.scheduleType == 2 : data?.scheduleType == 1
? "special" ? "هفتگی"
: ""} : data?.scheduleType == 2
? "مخصوص"
: ""}
</>
) : (
<>
{data?.scheduleType == 0
? "daily"
: data?.scheduleType == 1
? "weekly"
: data?.scheduleType == 2
? "special"
: ""}
</>
)}
</div> </div>
<div className="w-[2px] h-3 mx-1 bg-primary-200 opacity-30 mt-[1px]"></div> <div className="w-[2px] h-3 mx-1 bg-primary-200 opacity-30 mt-[1px]"></div>
<div className=" w-fit relative text-[11px] text-secondary-400"> <div className=" w-fit relative text-[11px] text-secondary-400">

View File

@ -12,12 +12,41 @@ import "react-vertical-timeline-component/style.min.css";
import { SectionWrapper } from "src/hoc"; import { SectionWrapper } from "src/hoc";
import { textVariant } from "src/utils/motion"; import { textVariant } from "src/utils/motion";
import { styles } from "src/style"; import { styles } from "src/style";
import { experiences } from "src/constans"; import { activityFake, activityFakeFa } from "datacalender";
import { activityFake } from "datacalender";
import ActivityCardFake from "@comp/TaskPage/ActivityCardFake/page"; import ActivityCardFake from "@comp/TaskPage/ActivityCardFake/page";
import { useLocale, useTranslations } from "next-intl";
const experiences = () => {
const t = useTranslations("experiences");
return [
{
title: t("insertTasks.title"),
points: t("insertTasks.points"),
},
{
title: t("createShiftPlan.title"),
points: t("createShiftPlan.points"),
},
{
title: t("specificPerson.title"),
points: t("specificPerson.points"),
},
{
title: t("realTime.title"),
points: t("realTime.points"),
},
{
title: t("confirmsCompletion.title"),
points: t("confirmsCompletion.points"),
},
];
};
const ExperienceCard = ({ experience }) => { const ExperienceCard = ({ experience }) => {
console.log(experience);
const [isMobile, setIsMobile] = useState(false); const [isMobile, setIsMobile] = useState(false);
const locale = useLocale();
const isRTL = locale === "fa";
useEffect(() => { useEffect(() => {
// Check window size after the component mounts // Check window size after the component mounts
@ -40,9 +69,7 @@ const ExperienceCard = ({ experience }) => {
borderRadius: "15px", borderRadius: "15px",
}} }}
contentArrowStyle={{ borderRight: "7px solid #35685952" }} contentArrowStyle={{ borderRight: "7px solid #35685952" }}
date={experience.date}
iconStyle={{ iconStyle={{
background: experience.iconBg, // Customize background
color: "#fff", // Customize icon color color: "#fff", // Customize icon color
boxShadow: "0 0 0 4px #35685952", // Add shadow or border boxShadow: "0 0 0 4px #35685952", // Add shadow or border
display: "flex", display: "flex",
@ -57,30 +84,30 @@ const ExperienceCard = ({ experience }) => {
}} }}
> >
<div> <div>
<h3 className="text-white text-[24px] font-bold">{experience.title}</h3> <h3
<p className={`text-white text-[24px] font-bold rtl ${
className="text-secondary text-[16px] font-semibold" isRTL ? "rtl" : "ltr"
style={{ margin: 0 }} }`}
> >
{experience.company_name} {experience.title}
</p> </h3>
</div> </div>
<ul className="mt-5 list-disc ml-5 space-y-2"> <ul className={`mt-5 list-disc ml-5 space-y-2 ${isRTL ? "rtl" : "ltr"}`}>
{experience.points.map((point, index) => ( <li className="text-white-100 text-[14px] pl-1 tracking-wider">
<li {experience.points}
key={`experience-point-${index}`} </li>
className="text-white-100 text-[14px] pl-1 tracking-wider"
>
{point}
</li>
))}
</ul> </ul>
</VerticalTimelineElement> </VerticalTimelineElement>
); );
}; };
const Experience = () => { const Experience = () => {
const t = useTranslations("experiences");
const locale = useLocale();
const isRTL = locale === "fa";
const [number, setNumber] = useState(4521); const [number, setNumber] = useState(4521);
const [prevNumber, setPrevNumber] = useState(4521); const [prevNumber, setPrevNumber] = useState(4521);
@ -104,21 +131,24 @@ const Experience = () => {
return ( return (
<> <>
<motion.div variants={textVariant()}> <motion.div variants={textVariant()}>
<h2 className="text-white font-black text-[30px] xs:text-[40px] sm:text-[50px] md:text-[60px] xs:leading-[50px] text-center "> {isRTL ? (
<span className="text-primary-300 text-[30px] xs:text-[100px] sm:text-[150px] relative top-[5px] sm:top-[10px] font-bold"> <h2 className="text-white font-black text-[30px] xs:text-[40px] sm:text-[50px] md:text-[60px] xs:leading-[50px] text-center ">
B {t("title")}
</span> </h2>
ase logics{" "} ) : (
</h2> <h2 className="text-white font-black text-[30px] xs:text-[40px] sm:text-[50px] md:text-[60px] xs:leading-[50px] text-center ">
<span className="text-primary-300 text-[30px] xs:text-[100px] sm:text-[150px] relative top-[5px] sm:top-[10px] font-bold">
B
</span>
ase logics{" "}
</h2>
)}
</motion.div> </motion.div>
<div className="mt-20 flex flex-col"> <div className="mt-20 flex flex-col ">
<VerticalTimeline> <VerticalTimeline>
{experiences.map((experience, index) => ( {experiences().map((e, index) => (
<ExperienceCard <ExperienceCard key={`experience-${index}`} experience={e} />
key={`experience-${index}`}
experience={experience}
/>
))} ))}
</VerticalTimeline> </VerticalTimeline>
</div> </div>
@ -127,11 +157,14 @@ const Experience = () => {
<h2 <h2
className={`text-white font-bold md:text-[30px] sm:text-[20px] xs:text-[18px] text-[30px] text-center`} className={`text-white font-bold md:text-[30px] sm:text-[20px] xs:text-[18px] text-[30px] text-center`}
> >
Number of tasks completed in Briz {t("taskText")}{" "}
</h2> </h2>
<div className="xs:block lg:flex justify-center mt-10"> <div className="xs:block lg:flex justify-center mt-10">
<div className="lg:w-[400px]"> <div className="lg:w-[400px]">
<ActivityCardFake data={activityFake} /> <ActivityCardFake
data={isRTL ? activityFakeFa : activityFake}
type={isRTL ? "fa" : "en"}
/>
</div> </div>
<div className="ml-4 mt-7"> <div className="ml-4 mt-7">
<div className="flex xs:justify-center xs:mt-10 lg:mt-0"> <div className="flex xs:justify-center xs:mt-10 lg:mt-0">
@ -169,7 +202,7 @@ const Experience = () => {
))} ))}
</div> </div>
<p className="mb-0 text-white font-light text-center"> <p className="mb-0 text-white font-light text-center">
Activities performed with Briz {t("LiveNumberTask")}{" "}
</p> </p>
</div> </div>
</div> </div>

View File

@ -5,7 +5,7 @@ import { motion } from "framer-motion";
import { SectionWrapper } from "src/hoc"; import { SectionWrapper } from "src/hoc";
import { fadeIn, textVariant } from "src/utils/motion"; import { fadeIn, textVariant } from "src/utils/motion";
import { styles } from "src/style"; import { styles } from "src/style";
import { testimonials } from "src/constans"; import { testimonials } from "src/constans/";
import Image from "next/image"; import Image from "next/image";
import phi from "@img/adjustw.png"; import phi from "@img/adjustw.png";
import phi1 from "../../src/assets/phi1.png"; import phi1 from "../../src/assets/phi1.png";

View File

@ -2,23 +2,40 @@ import React, { version } from "react";
import logo2 from "../../../src/assets/logo2.png"; import logo2 from "../../../src/assets/logo2.png";
import Image from "next/image"; import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import { useLocale } from "next-intl";
const Footer = () => { const Footer = () => {
const locale = useLocale();
const isRTL = locale === "fa";
return ( return (
<div className="bg-hero-pattern-footer "> <div className="bg-hero-pattern-footer ">
<div className="lg:w-7/12 xs:w-full mx-auto py-20"> <div className="lg:w-7/12 xs:w-full mx-auto py-20">
<div className="flex justify-center"> <div className="flex justify-center">
<div className="flex"></div> <div className={`text-center w-full ${isRTL ? "rtl" : "ltr"}`}>
{isRTL ? (
<div className="text-center w-full"> <>
<p className="mb-0 text-white text-center xs:mt-0 lg:mt-10 font-bold lg:text-[70px] xs:text-[25px] lg:leading-[60px] lg:w-fit xs:w-full"> <p className="mb-0 text-white text-center xs:mt-0 lg:mt-10 font-bold lg:text-[70px] xs:text-[25px] lg:leading-[60px] lg:w-fit xs:w-full">
<small className="text-primary-300">"</small> <small className="text-primary-300">"</small>
Briz, Harmonious routine بریز، مدیریت هارمونیک{" "}
</p> </p>
<p className="mb-0 text-white text-center font-bold lg:text-[70px] xs:text-[25px] lg:leading-[60px] lg:w-fit xs:w-full"> <p className="mb-0 text-white text-center font-bold lg:text-[70px] xs:text-[25px] lg:leading-[60px] lg:w-fit xs:w-full">
management روتین ها
<small className=" text-primary-300">"</small> <small className=" text-primary-300">"</small>
</p> </p>
</>
) : (
<>
{" "}
<p className="mb-0 text-white text-center xs:mt-0 lg:mt-10 font-bold lg:text-[70px] xs:text-[25px] lg:leading-[60px] lg:w-fit xs:w-full">
<small className="text-primary-300">"</small>
Briz, Harmonious routine
</p>
<p className="mb-0 text-white text-center font-bold lg:text-[70px] xs:text-[25px] lg:leading-[60px] lg:w-fit xs:w-full">
management
<small className=" text-primary-300">"</small>
</p>
</>
)}
</div> </div>
</div> </div>
</div> </div>

View File

@ -2,8 +2,13 @@ import Link from "next/link";
import MovingLogos from "./MovingLogos/page"; import MovingLogos from "./MovingLogos/page";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { fadeIn, textVariant } from "src/utils/motion"; import { fadeIn, textVariant } from "src/utils/motion";
import { useTranslations } from "next-intl";
const Hero = () => { const Hero = () => {
const t = useTranslations("page");
console.log("ssssst", t);
return ( return (
<section className="relative w-full h-screen mx-auto"> <section className="relative w-full h-screen mx-auto">
<div className="flex justify-center pt-[200px] lg:pt-[300px] lg:ml-0"> <div className="flex justify-center pt-[200px] lg:pt-[300px] lg:ml-0">
@ -17,7 +22,7 @@ const Hero = () => {
className="font-black text-white text-[40px] xs:text-[30px] sm:text-[140px] lg:text-[60px] leading-tight mb-0 space-x-6 text-center" className="font-black text-white text-[40px] xs:text-[30px] sm:text-[140px] lg:text-[60px] leading-tight mb-0 space-x-6 text-center"
style={{ wordSpacing: "10px" }} style={{ wordSpacing: "10px" }}
> >
SIMPLE AND SMOOTH OPERATION {t("title")}
</h1> </h1>
</motion.div> </motion.div>
<small className="text-[20px] md:text-[60px] lg:text-[80px] mx-2 text-primary-300 xs:hidden lg:block"> <small className="text-[20px] md:text-[60px] lg:text-[80px] mx-2 text-primary-300 xs:hidden lg:block">
@ -27,16 +32,14 @@ const Hero = () => {
<motion.div variants={fadeIn("", "", 0.1, 1)}> <motion.div variants={fadeIn("", "", 0.1, 1)}>
<p className="text-gray-300 font-medium text-[14px] xs:text-[16px] sm:text-[22px] lg:text-[24px] leading-[20px] xs:leading-[24px] text-white-100 text-center lg:w-10/12 xs:w-full xs:px-4 mx-auto mt-5"> <p className="text-gray-300 font-medium text-[14px] xs:text-[16px] sm:text-[22px] lg:text-[24px] leading-[20px] xs:leading-[24px] text-white-100 text-center lg:w-10/12 xs:w-full xs:px-4 mx-auto mt-5">
A task and shift management solution for coffee shops that {t("desc")}
provides clear, trackable task management and monitoring of store
operations.
</p> </p>
</motion.div> </motion.div>
<Link href="/app/login"> <Link href="/app/login">
<div className="flex justify-center mt-10"> <div className="flex justify-center mt-10">
<button className="btn btn-primary rounded-full px-8 sm:px-16 lg:px-20 py-3 sm:py-5 text-black text-sm sm:text-lg font-bold"> <button className="btn btn-primary rounded-full px-8 sm:px-16 lg:px-20 py-3 sm:py-5 text-black text-sm sm:text-lg font-bold">
Get started {t("button")}{" "}
</button> </button>
</div> </div>
</Link> </Link>
@ -45,7 +48,7 @@ const Hero = () => {
<div className="mt-[50px] lg:mt-[200px]"> <div className="mt-[50px] lg:mt-[200px]">
<p className="opacity-60 text-white font-light text-[14px] xs:text-[16px] sm:text-[20px] lg:text-[22px] leading-[20px] lg:leading-[24px] text-center w-10/12 sm:w-8/12 mx-auto"> <p className="opacity-60 text-white font-light text-[14px] xs:text-[16px] sm:text-[20px] lg:text-[22px] leading-[20px] lg:leading-[24px] text-center w-10/12 sm:w-8/12 mx-auto">
Brands that trust us and use BRIZ for their managing. {t("brand")}{" "}
</p> </p>
<div className="p-5 relative overflow-hidden w-10/12 mx-auto opacity-40 fade-mask"> <div className="p-5 relative overflow-hidden w-10/12 mx-auto opacity-40 fade-mask">
<MovingLogos /> <MovingLogos />

View File

@ -3,15 +3,56 @@ import React, { useEffect, useState } from "react";
import { menu, close } from "src/assets"; import { menu, close } from "src/assets";
import { styles } from "src/style"; import { styles } from "src/style";
import { navLinks } from "src/constans";
import Link from "next/link"; import Link from "next/link";
import logo2 from "../../src/assets/logo2.png"; import logo2 from "../../src/assets/logo2.png";
import Image from "next/image"; import Image from "next/image";
import { useLocale, useTranslations } from "next-intl";
import PersianNumberMemo from "plugins/PersianNumber";
import { routing } from "../../src/i18n/routing";
import { useRouter } from "next/navigation";
// Fix the `useTranslations` key (removed space at the end)
const navLinks = () => {
const t = useTranslations("navLinks");
return [
{
id: "our-solution",
title: t("ourSolution"),
go: false,
},
{
id: "product",
title: t("product"),
go: false,
},
{
id: "pricing",
title: t("pricing"),
go: true,
},
{
id: "about-us",
title: t("aboutUs"),
go: true,
},
];
};
const Navbar = () => { const Navbar = () => {
const [active, setActive] = useState(""); const [active, setActive] = useState("");
const [toggle, setToggle] = useState(false); const [toggle, setToggle] = useState(false);
const [scrolled, setScrolled] = useState(false); const [scrolled, setScrolled] = useState(false);
const [isOpenLang, setIsOpenLang] = useState(false); // To toggle the dropdown
const t = useTranslations("navLinks");
const locale = useLocale();
const router = useRouter();
const isRTL = locale === "fa";
// Call `navLinks` once at the beginning
const navItems = navLinks();
useEffect(() => { useEffect(() => {
const handleScroll = () => { const handleScroll = () => {
@ -28,13 +69,30 @@ const Navbar = () => {
return () => window.removeEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll);
}, []); }, []);
const availableLocales = [
{ code: "en", name: "en" },
{ code: "fa", name: "فا" }, // Persian (RTL)
{ code: "zh", name: "中文" },
];
// Function to change the locale
const changeLocale = (newLocale) => {
// Navigate to the same route but with a different locale
router.push(newLocale);
setIsOpenLang(false); // Close the dropdown
};
return ( return (
<nav <nav
className={`sm:px-16 px-6 w-full flex items-center py-5 fixed top-0 z-20 tr03 ${ className={`sm:px-16 px-6 w-full flex items-center py-5 fixed top-0 z-20 tr03 ${
scrolled ? "bg-black" : "bg-transparent" scrolled ? "bg-black" : "bg-transparent"
}`} }`}
> >
<div className="w-full flex justify-between items-center max-w-7xl mx-auto"> <div
className={`w-full flex justify-between items-center max-w-7xl mx-auto ${
isRTL ? "rtl" : "ltr"
}`}
>
<div className="flex"> <div className="flex">
<Link <Link
href="/" href="/"
@ -51,7 +109,7 @@ const Navbar = () => {
/>{" "} />{" "}
</Link> </Link>
<ul className="list-none hidden sm:flex flex-row gap-10 p-3 mx-10"> <ul className="list-none hidden sm:flex flex-row gap-10 p-3 mx-10">
{navLinks.map((nav) => ( {navItems.map((nav) => (
<li <li
key={nav.id} key={nav.id}
className={`${ className={`${
@ -73,10 +131,40 @@ const Navbar = () => {
<div className="flex"> <div className="flex">
<Link href="/app/login"> <Link href="/app/login">
<button className=" btn btn-primary px-10 rounded-full py-2 xs:hidden lg:block"> <button className="btn btn-primary px-10 rounded-full text-sm py-2 xs:hidden lg:block">
Get started {t("button")}{" "}
</button> </button>
</Link> </Link>
<div className="relative">
{/* Language button */}
<div
className="w-9 h-9 bg-primary-300 rounded-full mx-2 cursor-pointer flex items-center justify-center"
onClick={() => setIsOpenLang(!isOpenLang)}
>
<p className="mb-0 text-sm">
{isRTL ? "فا" : locale == "zh" ? "中文" : locale}
</p>
</div>
{/* Dropdown box for language selection */}
{isOpenLang && (
<div className="absolute bg-white shadow-lg rounded-full w-9 mx-2 mt-2 ">
{availableLocales.map((lang) => (
<button
key={lang.code}
onClick={() => changeLocale(lang.code)}
className={`block py-2 text-sm text-center w-full relative ${
locale === lang.code ? "font-bold" : ""
}`}
>
{lang.name}
</button>
))}
</div>
)}
</div>
</div> </div>
<div className="sm:hidden flex flex-1 justify-end items-center"> <div className="sm:hidden flex flex-1 justify-end items-center">
@ -93,7 +181,7 @@ const Navbar = () => {
} p-6 bg-white absolute top-20 right-5 my-2 min-w-[140px] z-10 rounded-xl`} } p-6 bg-white absolute top-20 right-5 my-2 min-w-[140px] z-10 rounded-xl`}
> >
<ul className="list-none flex justify-end items-start flex-1 flex-col gap-4"> <ul className="list-none flex justify-end items-start flex-1 flex-col gap-4">
{navLinks.map((nav) => ( {navItems.map((nav) => (
<li <li
key={nav.id} key={nav.id}
className={`font-poppins font-medium cursor-pointer text-[16px] ${ className={`font-poppins font-medium cursor-pointer text-[16px] ${
@ -106,9 +194,9 @@ const Navbar = () => {
> >
<> <>
{nav.go ? ( {nav.go ? (
<Link href={`/${nav.id}`}>{nav.title}</Link> <Link href={`*/${nav.id}`}>{nav.title}</Link>
) : ( ) : (
<a href={`/#${nav.id}`}>{nav.title}</a> <a href={`*/#${nav.id}`}>{nav.title}</a>
)} )}
</> </>
</li> </li>

View File

@ -5,55 +5,77 @@ import { motion } from "framer-motion";
import { SectionWrapper } from "src/hoc"; import { SectionWrapper } from "src/hoc";
import { fadeIn, textVariant } from "src/utils/motion"; import { fadeIn, textVariant } from "src/utils/motion";
import { styles } from "src/style"; import { styles } from "src/style";
import { testimonials } from "src/constans";
import Image from "next/image"; import Image from "next/image";
import phi from "@img/adjustw.png"; import phi from "@img/adjustw.png";
import phi1 from "../../src/assets/phi1.png"; import phi1 from "../../src/assets/phi1.png";
import phi2 from "../../src/assets/phi2.png"; import phi2 from "../../src/assets/phi2.png";
import phi3 from "../../src/assets/phi3.png"; import phi3 from "../../src/assets/phi3.png";
import { useLocale, useTranslations } from "next-intl";
const phiData = () => {
const t = useTranslations("phiData");
return [
{
title: t("bcg.title"),
desc: t("bcg.desc"),
},
{
title: t("oeg.title"),
desc: t("oeg.desc"),
},
{
title: t("et.title"),
desc: t("et.desc"),
},
];
};
const Phi = () => { const Phi = () => {
const [activeIndex, setActiveIndex] = useState(0); const [activeIndex, setActiveIndex] = useState(0);
useEffect(() => { console.log("object phiData().length", phiData().length);
const interval = setInterval(() => {
setActiveIndex((prevIndex) =>
prevIndex === testimonials.length - 1 ? 0 : prevIndex + 1
);
}, 6000); // 5 seconds interval
return () => clearInterval(interval); // Cleanup interval on component unmount const t = useTranslations("phiData");
}, []);
const locale = useLocale();
const isRTL = locale === "fa";
console.log(activeIndex); console.log(activeIndex);
return ( return (
<div className={` rounded-[20px]`}> <div className={` rounded-[20px] ${isRTL ? "rtl" : "ltr"} `}>
<div className={`bg-tertiary rounded-2xl ]`}> <div className={`bg-tertiary rounded-2xl `}>
<motion.div variants={textVariant()}> <motion.div variants={textVariant()}>
<div className="flex"> <div className="flex ">
<div className="xs:w-[100px] lg:w-[120px] mt-[90px]"> {isRTL ? (
<Image src={phi} /> <>
</div> <span className="text-primary-300 text-[30px] xs:text-[100px] sm:text-[150px] relative top-[5px] sm:top-[10px] font-bold xs:mt-[89px] lg:mt-[52px]">
{" "}
<span className="text-primary-300 text-[30px] xs:text-[100px] sm:text-[150px] relative top-[5px] sm:top-[10px] font-bold xs:mt-[89px] lg:mt-[52px]"> HI
{" "} </span>
HI <div className="xs:w-[100px] lg:w-[120px] mt-[90px]">
</span> <Image src={phi} />
</div>
</>
) : (
<>
{" "}
<div className="xs:w-[100px] lg:w-[120px] mt-[90px]">
<Image src={phi} />
</div>
<span className="text-primary-300 text-[30px] xs:text-[100px] sm:text-[150px] relative top-[5px] sm:top-[10px] font-bold xs:mt-[89px] lg:mt-[52px]">
{" "}
HI
</span>
</>
)}
</div> </div>
<p className="mb-0 text-white xs:mt-0 lg:mt-5"> <p className="mb-0 text-white xs:mt-0 lg:mt-5"> {t("desc")}</p>
{" "}
Coffee taste always matters the most. With PHI, it will always be
perfect. Phi means the golden ratio. If you brew your coffee with
the golden ratio, it will always taste good. In the Phi section,
there are three boxes that the barista on shift should fill. These
are the main elements for adjusting the daily coffee recipe:
</p>
</motion.div> </motion.div>
</div> </div>
<div className={` pb-14 sm:py-16 grid lg:grid-cols-2 xs:grid-cols-1 `}> <div className={` pb-14 sm:py-16 grid lg:grid-cols-2 xs:grid-cols-1 `}>
<div> <div>
{testimonials.map((e, index) => ( {phiData().map((e, index) => (
<motion.div <motion.div
key={index} key={index}
variants={fadeIn("", "spring", index * 0.5, 0.75)} variants={fadeIn("", "spring", index * 0.5, 0.75)}
@ -73,7 +95,7 @@ const Phi = () => {
{activeIndex == index && ( {activeIndex == index && (
<div className="mt-3"> <div className="mt-3">
<p className="text-white tracking-wider text-[16px] font-light"> <p className="text-white tracking-wider text-[16px] font-light">
{e.testimonial} {e.desc}
</p> </p>
</div> </div>
)} )}
@ -105,12 +127,7 @@ const Phi = () => {
</div> */} </div> */}
</div> </div>
<p className="mb-0 text-white"> <p className="mb-0 text-white">{t("endDesc")}</p>
{" "}
Your barista enters the daily recipe, which will be recorded in your
database. You can view your adjustment chart see whats happening in
your bar, and check the quality of your coffee serving in your store.
</p>
</div> </div>
); );
}; };

View File

@ -5,30 +5,77 @@ import { motion } from "framer-motion";
import { SectionWrapper } from "src/hoc"; import { SectionWrapper } from "src/hoc";
import { fadeIn, textVariant } from "src/utils/motion"; import { fadeIn, textVariant } from "src/utils/motion";
import { styles } from "src/style"; import { styles } from "src/style";
import { stepProducts } from "src/constans";
import Image from "next/image"; import Image from "next/image";
import phi from "@img/adjustw.png"; import phi from "@img/adjustw.png";
import app from "../../src/assets/app.png"; import app from "../../src/assets/app.png";
import Avatar from "boring-avatars"; import Avatar from "boring-avatars";
import { useLocale, useTranslations } from "next-intl";
const stepProducts = () => {
const t = useTranslations("stepProducts");
return [
{
title: t("setupRoutine.title"),
desc: t("setupRoutine.desc"),
},
{
title: t("setupSections.title"),
desc: t("setupSections.desc"),
},
{
title: t("setupPositions.title"),
desc: t("setupPositions.desc"),
},
{
title: t("setupStaffInfo.title"),
desc: t("setupStaffInfo.desc"),
},
{
title: t("setupShiftsLogic.title"),
desc: t("setupShiftsLogic.desc"),
},
{
title: t("insertTasks.title"),
desc: t("insertTasks.desc"),
},
];
};
const StepProduct = ({}) => { const StepProduct = ({}) => {
const [activeIndex, setActiveIndex] = useState(1); const [activeIndex, setActiveIndex] = useState(1);
const t = useTranslations("stepProducts");
const locale = useLocale();
const isRTL = locale === "fa";
return ( return (
<div className={` rounded-[20px]`}> <div className={` rounded-[20px] ${isRTL ? "rtl" : "ltr"}`}>
<div className={`bg-tertiary rounded-2xl ]`}> <div className={`bg-tertiary rounded-2xl ]`}>
<motion.div variants={textVariant()}> <motion.div variants={textVariant()}>
<div {isRTL ? (
className={`text-white font-black text-[30px] xs:text-[30px] sm:text-[50px] md:text-[60px] xs:leading-[60px] lg:leading-normal flex `} <div
> className={`text-white font-black text-[30px] xs:text-[30px] sm:text-[50px] md:text-[60px] xs:leading-[60px] lg:leading-normal flex `}
<span className="text-primary-300 text-[30px] xs:text-[100px] sm:text-[150px] relative top-[10px] !h-fit font-bold xs:mt-[49px] lg:mt-0"> >
E <div className={` mt-10 ${isRTL ? "text-right" : "text-left"}`}>
</span> <p className="mb-0">آسان برای پیاده سازی </p>
<div className="text-left mt-10"> <p className="mb-0 mt-[-30px]">آسان برای استفاده </p>
<p className="mb-0">asy to Implement </p> </div>
<p className="mb-0 mt-[-30px]">asy to Use. </p>
</div> </div>
</div> ) : (
<div
className={`text-white font-black text-[30px] xs:text-[30px] sm:text-[50px] md:text-[60px] xs:leading-[60px] lg:leading-normal flex `}
>
<span className="text-primary-300 text-[30px] xs:text-[100px] sm:text-[150px] relative top-[10px] !h-fit font-bold xs:mt-[49px] lg:mt-0">
E
</span>
<div className="text-left mt-10">
<p className="mb-0">asy to Implement </p>
<p className="mb-0 mt-[-30px]">asy to Use. </p>
</div>
</div>
)}
{/* <p className="mb-0 text-white text-lfet"> {/* <p className="mb-0 text-white text-lfet">
{" "} {" "}
make your operation simple and smooth make your operation simple and smooth
@ -36,7 +83,7 @@ const StepProduct = ({}) => {
</motion.div> </motion.div>
<div className={` pb-14 grid lg:grid-cols-2 xs:grid-cols-1 gap-7 `}> <div className={` pb-14 grid lg:grid-cols-2 xs:grid-cols-1 gap-7 `}>
<div> <div>
{stepProducts.map((e, index) => ( {stepProducts().map((e, index) => (
<motion.div <motion.div
key={index} key={index}
variants={fadeIn("", "spring", index * 0.5, 0.75)} variants={fadeIn("", "spring", index * 0.5, 0.75)}
@ -56,18 +103,14 @@ const StepProduct = ({}) => {
{activeIndex == index && ( {activeIndex == index && (
<div className="mt-3"> <div className="mt-3">
<p className="text-white tracking-wider text-[16px] font-light"> <p className="text-white tracking-wider text-[16px] font-light">
{e.des} {e.desc}
</p> </p>
</div> </div>
)} )}
</motion.div> </motion.div>
))} ))}
<p className="mb-0 text-white mt-8"> <p className="mb-0 text-white mt-8"> {t("endDesc")}</p>
{" "}
Now just set up your shifts for the upcoming week. Assign staff to
each position within each shift and designate a supervisor.
</p>
</div> </div>
<div className=" xs:p-3 lg:p-8 h-fit"> <div className=" xs:p-3 lg:p-8 h-fit">
@ -88,8 +131,8 @@ const StepProduct = ({}) => {
activeIndex == 0 ? "pb-3" : "" activeIndex == 0 ? "pb-3" : ""
}`} }`}
> >
<div className="flex" onClick={() => setActiveIndex(0)}> <div className="flex " onClick={() => setActiveIndex(0)}>
<div className="flex w-10/12 p-2 py-3"> <div className="flex w-10/12 p-2 py-3">
<div className=" rounded mx-1"> <div className=" rounded mx-1">
<p className="mb-0 text-center pt-[2px] text-white text-[12px] "> <p className="mb-0 text-center pt-[2px] text-white text-[12px] ">
1 - 1 -
@ -97,7 +140,9 @@ const StepProduct = ({}) => {
</div> </div>
<div className="pt-[2px] pr-2 "> <div className="pt-[2px] pr-2 ">
<h4 className="text-[12px] font-bold"> <h4 className="text-[12px] font-bold">
Management routines{" "} {isRTL
? "مدیریت روتین ها"
: " Management routines"}
</h4> </h4>
</div> </div>
</div> </div>
@ -152,7 +197,7 @@ const StepProduct = ({}) => {
<div className="bg-primary-800 shadow-sm rounded-full p-1 w-fit flex m-1"> <div className="bg-primary-800 shadow-sm rounded-full p-1 w-fit flex m-1">
<div className="mx-3"> <div className="mx-3">
<p className="mb-0 mt-1 text-[12px] font-medium"> <p className="mb-0 mt-1 text-[12px] font-medium">
normal {isRTL ? "عادی" : "normal"}
</p> </p>
</div> </div>
<> <>
@ -202,7 +247,7 @@ const StepProduct = ({}) => {
<div className="bg-primary-800 shadow-sm rounded-full p-1 w-fit flex m-1"> <div className="bg-primary-800 shadow-sm rounded-full p-1 w-fit flex m-1">
<div className="mx-3"> <div className="mx-3">
<p className="mb-0 mt-1 text-[12px] font-medium"> <p className="mb-0 mt-1 text-[12px] font-medium">
friday {isRTL ? "جمعه ها" : "friday"}
</p> </p>
</div> </div>
<> <>
@ -265,7 +310,7 @@ const StepProduct = ({}) => {
</div> </div>
<div className="pt-[2px] pr-2 "> <div className="pt-[2px] pr-2 ">
<h4 className="text-[12px] font-bold"> <h4 className="text-[12px] font-bold">
Management sections{" "} {isRTL ? "مدیریت سکشن ها" : "Management sections"}{" "}
</h4> </h4>
</div> </div>
</div> </div>
@ -320,7 +365,7 @@ const StepProduct = ({}) => {
<div className="bg-primary-800 shadow-sm rounded-full p-1 w-fit flex m-1"> <div className="bg-primary-800 shadow-sm rounded-full p-1 w-fit flex m-1">
<div className="mx-3"> <div className="mx-3">
<p className="mb-0 mt-1 text-[12px] font-medium"> <p className="mb-0 mt-1 text-[12px] font-medium">
bar {isRTL ? "بار" : "bar"}
</p> </p>
</div> </div>
<> <>
@ -370,7 +415,9 @@ const StepProduct = ({}) => {
<div className="bg-primary-800 shadow-sm rounded-full p-1 w-fit flex m-1"> <div className="bg-primary-800 shadow-sm rounded-full p-1 w-fit flex m-1">
<div className="mx-3"> <div className="mx-3">
<p className="mb-0 mt-1 text-[12px] font-medium"> <p className="mb-0 mt-1 text-[12px] font-medium">
Italian kitchen {isRTL
? "آشپز خانه فرنگی"
: " Italian kitchenbar"}
</p> </p>
</div> </div>
<> <>
@ -433,7 +480,9 @@ const StepProduct = ({}) => {
</div> </div>
<div className="pt-[2px] pr-2 "> <div className="pt-[2px] pr-2 ">
<h4 className="text-[12px] font-bold"> <h4 className="text-[12px] font-bold">
Management positions{" "} {isRTL
? "مدیریت پوزیشن ها"
: "Management positions"}
</h4> </h4>
</div> </div>
</div> </div>
@ -488,7 +537,7 @@ const StepProduct = ({}) => {
<div className="bg-primary-800 shadow-sm rounded-full p-1 w-fit flex m-1"> <div className="bg-primary-800 shadow-sm rounded-full p-1 w-fit flex m-1">
<div className="mx-3"> <div className="mx-3">
<p className="mb-0 mt-1 text-[12px] font-medium"> <p className="mb-0 mt-1 text-[12px] font-medium">
cashier {isRTL ? "صندوق دار" : "cashier"}
</p> </p>
</div> </div>
<> <>
@ -538,7 +587,7 @@ const StepProduct = ({}) => {
<div className="bg-primary-800 shadow-sm rounded-full p-1 w-fit flex m-1"> <div className="bg-primary-800 shadow-sm rounded-full p-1 w-fit flex m-1">
<div className="mx-3"> <div className="mx-3">
<p className="mb-0 mt-1 text-[12px] font-medium"> <p className="mb-0 mt-1 text-[12px] font-medium">
barista {isRTL ? "باریستا" : "barista"}
</p> </p>
</div> </div>
<> <>
@ -601,7 +650,7 @@ const StepProduct = ({}) => {
</div> </div>
<div className="pt-[2px] pr-2 "> <div className="pt-[2px] pr-2 ">
<h4 className="text-[12px] font-bold"> <h4 className="text-[12px] font-bold">
Management staff{" "} {isRTL ? "مدیریت کارکنان" : " Management staff"}
</h4> </h4>
</div> </div>
</div> </div>
@ -663,7 +712,9 @@ const StepProduct = ({}) => {
</div> </div>
<div className="mx-3"> <div className="mx-3">
<p className="mb-0 mt-1 text-[12px] font-medium"> <p className="mb-0 mt-1 text-[12px] font-medium">
ali maleki - barista {isRTL
? "علی مالکی - باریستا"
: " ali maleki - barista"}
</p> </p>
</div> </div>
</div> </div>
@ -679,7 +730,9 @@ const StepProduct = ({}) => {
</div> </div>
<div className="mx-3"> <div className="mx-3">
<p className="mb-0 mt-1 text-[12px] font-medium"> <p className="mb-0 mt-1 text-[12px] font-medium">
sadaf hedayati - cashier {isRTL
? "صدف هدایتی - صندوق دار"
: " sadaf hedayati - cashier"}
</p> </p>
</div> </div>
</div> </div>
@ -700,7 +753,9 @@ const StepProduct = ({}) => {
</div> </div>
<div className="pt-[2px] pr-2 "> <div className="pt-[2px] pr-2 ">
<h4 className="text-[12px] font-bold"> <h4 className="text-[12px] font-bold">
Management set shifts{" "} {isRTL
? "مدیریت شیفت ها"
: " Management set shifts"}
</h4> </h4>
</div> </div>
</div> </div>
@ -753,14 +808,18 @@ const StepProduct = ({}) => {
<div className="bg-primary-800 shadow-sm rounded-full p-1 w-[95%] flex m-1"> <div className="bg-primary-800 shadow-sm rounded-full p-1 w-[95%] flex m-1">
<div className="mx-3"> <div className="mx-3">
<p className="mb-0 mt-1 text-[12px] font-medium"> <p className="mb-0 mt-1 text-[12px] font-medium">
morning shift | 07:00-11:59 {isRTL
? " شیفت صبح | 07:00-11:59"
: " morning shift | 07:00-11:59"}
</p> </p>
</div> </div>
</div> </div>
<div className="bg-primary-800 shadow-sm rounded-full p-1 w-[95%] flex m-1"> <div className="bg-primary-800 shadow-sm rounded-full p-1 w-[95%] flex m-1">
<div className="mx-3"> <div className="mx-3">
<p className="mb-0 mt-1 text-[12px] font-medium"> <p className="mb-0 mt-1 text-[12px] font-medium">
Afternoon shift | 02:00-17:59 {isRTL
? " شیقت عصر| 02:00-17:59"
: " Afternoon shift | 02:00-17:59"}
</p> </p>
</div> </div>
</div> </div>
@ -781,7 +840,9 @@ const StepProduct = ({}) => {
</div> </div>
<div className="pt-[2px] pr-2 "> <div className="pt-[2px] pr-2 ">
<h4 className="text-[12px] font-bold"> <h4 className="text-[12px] font-bold">
Add collection task{" "} {isRTL
? "مدیریت فعالیت ها"
: " Add collection task"}
</h4> </h4>
</div> </div>
</div> </div>
@ -834,10 +895,14 @@ const StepProduct = ({}) => {
<div className="bg-primary-800 shadow-sm rounded-md p-1 w-[95%] flex m-1"> <div className="bg-primary-800 shadow-sm rounded-md p-1 w-[95%] flex m-1">
<div className="mx-3"> <div className="mx-3">
<p className="mb-0 mt-1 text-[10px] font-medium"> <p className="mb-0 mt-1 text-[10px] font-medium">
morning shift | barista | daily {isRTL
? "شیفت صبح | باریستا | روزانه"
: "morning shift | barista | daily"}
</p> </p>
<p className="mb-0 text-sm"> <p className="mb-0 text-sm">
Backwashing the espresso machine {isRTL
? "تمیزی نهایی اسپرسو ماشین"
: " Backwashing the espresso machine"}
</p> </p>
</div> </div>
</div> </div>
@ -845,10 +910,14 @@ const StepProduct = ({}) => {
<div className="bg-primary-800 shadow-sm rounded-md p-1 w-[95%] flex m-1"> <div className="bg-primary-800 shadow-sm rounded-md p-1 w-[95%] flex m-1">
<div className="mx-3"> <div className="mx-3">
<p className="mb-0 mt-1 text-[10px] font-medium"> <p className="mb-0 mt-1 text-[10px] font-medium">
morning shift | cashier | daily {isRTL
? "شیفت عصر | ویتر | روزانه"
: "morning shift | barista | daily"}
</p> </p>
<p className="mb-0 text-sm"> <p className="mb-0 text-sm">
Close the morning shift box{" "} {isRTL
? "تمیز کردن پنجره های ورودی"
: " Close the morning shift box"}
</p> </p>
</div> </div>
</div> </div>

View File

@ -3,13 +3,14 @@ import { Tilt } from "react-tilt";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { fadeIn, textVariant } from "src/utils/motion"; import { fadeIn, textVariant } from "src/utils/motion";
import { services } from "src/constans";
import { styles } from "src/style"; import { styles } from "src/style";
import { SectionWrapper } from "src/hoc"; import { SectionWrapper } from "src/hoc";
import Image from "next/image"; import Image from "next/image";
import vector1 from "@img/Vector1.png"; import vector1 from "@img/Vector1.png";
import validateIranPhone from "plugins/IranPhoneRegex"; import validateIranPhone from "plugins/IranPhoneRegex";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import { useLocale, useTranslations } from "next-intl";
import { useRouter } from "next/navigation";
const ServiceCard = ({ index, title, icon }) => ( const ServiceCard = ({ index, title, icon }) => (
<Tilt className=" w-full mt-5"> <Tilt className=" w-full mt-5">
@ -49,6 +50,16 @@ const ServiceCard = ({ index, title, icon }) => (
</Tilt> </Tilt>
); );
const services = () => {
const t = useTranslations("services");
return [
{ title: t("streamlinedOperations") },
{ title: t("empoweredDecision") },
{ title: t("unwaveringSupport") },
{ title: t("seamlessIntegration") },
];
};
const StressTest = () => { const StressTest = () => {
const [subscribe, setSubscribe] = useState(false); const [subscribe, setSubscribe] = useState(false);
const [subscribeNumber, setSubscribeNumber] = useState(""); const [subscribeNumber, setSubscribeNumber] = useState("");
@ -68,31 +79,46 @@ const StressTest = () => {
} }
}; };
const t = useTranslations("services");
const locale = useLocale();
const router = useRouter();
const isRTL = locale === "fa";
return ( return (
<div className="xs:mt-20 "> <div className={`xs:mt-20 ${isRTL ? "rtl" : "ltr"} `}>
<motion.div variants={textVariant()}> <motion.div variants={textVariant()}>
<h2 className="text-white font-black text-[30px] xs:text-[40px] sm:text-[50px] md:text-[60px] xs:leading-[50px] "> {isRTL ? (
<span className="text-primary-300 text-[30px] xs:text-[100px] sm:text-[150px] relative top-[5px] sm:top-[10px] font-bold"> <h2 className="text-white font-black text-[30px] xs:text-[40px] sm:text-[50px] md:text-[60px] xs:leading-[50px] ">
B {t("title")}
</span> </h2>
e Part of Our Stress Test{" "} ) : (
</h2> <h2 className="text-white font-black text-[30px] xs:text-[40px] sm:text-[50px] md:text-[60px] xs:leading-[50px] ">
<span className="text-primary-300 text-[30px] xs:text-[100px] sm:text-[150px] relative top-[5px] sm:top-[10px] font-bold">
B
</span>
e Part of Our Stress Test{" "}
</h2>
)}
</motion.div> </motion.div>
<motion.p <motion.p
variants={fadeIn("", "", 0.1, 1)} variants={fadeIn("", "", 0.1, 1)}
className="text-secondary text-[14px] xs:text-[16px] sm:text-[17px] max-w-3xl leading-[20px] sm:leading-[24px] text-white mt-3" className="text-secondary text-[14px] xs:text-[16px] sm:text-[17px] max-w-3xl leading-[20px] sm:leading-[24px] text-white mt-3"
> >
Be Part of Our Stress Test and try us as an early adapter {t("desc")}
</motion.p> </motion.p>
<motion.div variants={fadeIn("", "", 0.1, 1)}> <motion.div variants={fadeIn("", "", 0.1, 1)}>
{subscribe ? ( {subscribe ? (
<div> <div>
<h2 <h2
className={`text-white md:text-[20px] sm:text-[20px] xs:text-[18px] text-[30px] text-left mt-10`} className={`text-white md:text-[20px] sm:text-[20px] xs:text-[18px] text-[30px] mt-10 ${
isRTL ? "text-right" : "text-left"
} `}
> >
Thank you for your trust, we will contact you {t("successInput")}
</h2> </h2>
</div> </div>
) : ( ) : (
@ -100,22 +126,22 @@ const StressTest = () => {
<input <input
type="number" type="number"
className="form-control !w-full sm:!w-6/12 mb-4 sm:mb-0" className="form-control !w-full sm:!w-6/12 mb-4 sm:mb-0"
placeholder="Enter your number" placeholder={t("inputValue")}
onChange={(e) => setSubscribeNumber(e.target.value)} onChange={(e) => setSubscribeNumber(e.target.value)}
value={subscribeNumber} value={subscribeNumber}
/> />
<button <button
className="btn btn-primary rounded-2xl sm:ml-3 w-full p-4 sm:w-auto" className="btn btn-primary rounded-2xl sm:mx-3 w-full p-4 sm:w-auto"
onClick={() => handleSubscribeNumber(true)} onClick={() => handleSubscribeNumber(true)}
> >
Subscribe {t("button")}
</button> </button>
</div> </div>
)} )}
</motion.div> </motion.div>
<div className="mt-10 xs:block lg:flex xs:justify-center lg:justify-start gap-5 sm:gap-10"> <div className="mt-10 xs:block lg:flex xs:justify-center lg:justify-start gap-5 sm:gap-10">
{services.map((service, index) => ( {services().map((service, index) => (
<ServiceCard key={service.title} index={index} {...service} /> <ServiceCard key={service.title} index={index} {...service} />
))} ))}
</div> </div>

View File

@ -424,3 +424,27 @@ export const activityFake = {
userId: "27b63e2b-8b36-41a0-b0e1-270a51184f15", userId: "27b63e2b-8b36-41a0-b0e1-270a51184f15",
userLastName: "masoomi pour", userLastName: "masoomi pour",
}; };
export const activityFakeFa = {
amount: "0",
amountType: " 0",
description: "شستن همه ی پنجره ها ",
doneAt: "0001-01-01T00:00:00",
hasDisposed: false,
id: "8c3b04cb-a4dc-471b-baa3-a0ce773301fa",
isDisposable: false,
isDone: false,
performanceDescription: "",
scheduleType: 0,
setFor: "2024-09-04T06:00:00",
shiftPlanId: "dfb74c6e-5c27-4c4b-866f-ae66f7320331",
shiftTitle: "شیفت صبح",
status: 0,
title: "تمیز کردن همه ی دیوار های اتاق کنفرانس ",
type: 0,
unDoneReason: "",
userFirstName: "حسین",
userFullName: "حسین معصومی پور",
userId: "27b63e2b-8b36-41a0-b0e1-270a51184f15",
userLastName: "معصومی پور",
};

100
messages/en.json 100644
View File

@ -0,0 +1,100 @@
{
"page": {
"title": "SIMPLE AND SMOOTH OPERATION",
"desc": "A task and shift management solution for coffee shops that provides clear, trackable task management and monitoring of store operations. ",
"button": "Get started",
"brand": "Brands that trust us and use BRIZ for their managing."
},
"home": {
"title": "Hello, Next.js i18n",
"desc": "This is a demo of Next.js i18n"
},
"navLinks": {
"ourSolution": "Our Solution",
"product": "Product",
"pricing": "Pricing",
"aboutUs": "About Us",
"button": "Get started"
},
"services": {
"title": "Be Part of Our Stress Test",
"desc": "Be Part of Our Stress Test and try us as an early adapter",
"inputValue": "Enter your number",
"button": "subscribe",
"successInput": "Thank you for your trust, we will contact you",
"streamlinedOperations": "Streamlined Operations",
"empoweredDecision": "Empowered Decision",
"unwaveringSupport": "Unwavering Support",
"seamlessIntegration": "Seamless Integration"
},
"experiences": {
"title": "Base logics",
"taskText": " Number of tasks completed in Briz",
"LiveNumberTask": "Activities performed with Briz",
"insertTasks": {
"title": "Insert tasks and assign",
"points": "Insert tasks and assign them to positions in the store"
},
"createShiftPlan": {
"title": "Create a clear shift plan",
"points": "Create a clear shift plan for each week and assign a supervisor to each shift."
},
"specificPerson": {
"title": "Activity assigned to a specific person",
"points": "After shift planning, each task becomes an activity assigned to a specific person."
},
"realTime": {
"title": "Real time",
"points": "Track the operation routine in the system in real time."
},
"confirmsCompletion": {
"title": "Confirms completion",
"points": "After closing the shift, your supervisor checks all the tasks, confirms completion, and rates the staff."
}
},
"phiData": {
"title": "phi",
"desc": "Coffee taste always matters the most. With PHI, it will always be perfect. Phi means the golden ratio. If you brew your coffee with the golden ratio, it will always taste good. In the Phi section, there are three boxes that the barista on shift should fill. These are the main elements for adjusting the daily coffee recipe:",
"endDesc": "Your barista enters the daily recipe, which will be recorded in your database. You can view your adjustment chart see whats happening in your bar, and check the quality of your coffee serving in your store.",
"bcg": {
"desc": "This refers to the precise amount of ground coffee used for each brew...",
"title": "Basic Coffee Gram (BCG)"
},
"oeg": {
"desc": "This measures the final weight of the extracted coffee after brewing...",
"title": "Output Extract Grammage (OEG)"
},
"et": {
"desc": "This is the total time taken to brew the coffee from start to finish...",
"title": "Extraction Time (ET)"
}
},
"stepProducts": {
"endDesc": "Now just set up your shifts for the upcoming week. Assign staff to each position within each shift and designate a supervisor.",
"setupRoutine": {
"desc": "You can fully customize and define your operation system...",
"title": "Setup your routine"
},
"setupSections": {
"desc": "Define your sections to gain better insights into your operations...",
"title": "Setup your sections"
},
"setupPositions": {
"desc": "Positions play a crucial role in our platform...",
"title": "Setup your positions"
},
"setupStaffInfo": {
"desc": "You need to set up your staff information...",
"title": "Setup staff information"
},
"setupShiftsLogic": {
"desc": "You need to establish your shift logic...",
"title": "Setup your shifts logic"
},
"insertTasks": {
"desc": "Set up all your tasks at this stage...",
"title": "Insert all of your tasks"
}
}
}

102
messages/fa.json 100644
View File

@ -0,0 +1,102 @@
{
"page": {
"title": "عملیات ساده و روان",
"desc": "ک راه حل مدیریت کار و شیفت برای کافی شاپ ها که مدیریت وظایف واضح و قابل ردیابی و نظارت بر عملیات فروشگاه را ارائه می دهد. ",
"button": "شروع کنید",
"brand": "برندهایی که به ما اعتماد دارند و از BRIZ برای مدیریت خود استفاده می کنند."
},
"home": {
"title": "Hello, Next.js i18n",
"desc": "This is a demo of Next.js i18n"
},
"navLinks": {
"ourSolution": "راه حل ما",
"product": "محصول",
"pricing": "قیمت",
"aboutUs": "درباره ما",
"button": "شروع کنید"
},
"services": {
"title": "بخشی از تست استرس ما باشید",
"desc": "خشی از تست استرس ما باشید و ما را به عنوان یک آداپتور اولیه امتحان کنید",
"inputValue": "شماره خود را وارد کنید",
"button": "عضو شوید",
"successInput": "با تشکر از اعتماد شما، ما با شما تماس خواهیم گرفت",
"streamlinedOperations": "عملیات ساده",
"empoweredDecision": "تصمیم قدرتمند",
"unwaveringSupport": "پشتیبانی بی دریغ",
"seamlessIntegration": "یکپارچه سازی "
},
"experiences": {
"title": "منطق پایه",
"taskText": "تعداد کارهای انجام شده در بریز",
"LiveNumberTask": "فعالیت های انجام شده با بریز",
"insertTasks": {
"title": "وظایف را وارد کنید و تعیین کنید",
"points": "وظایف را وارد کنید و آنها را به موقعیت هایی در فروشگاه اختصاص دهید"
},
"createShiftPlan": {
"title": "یک برنامه شفاف ایجاد کنید",
"points": "برای هر هفته یک برنامه شیفت روشن ایجاد کنید و برای هر شیفت یک سرپرست تعیین کنید."
},
"specificPerson": {
"title": "فعالیتی که به شخص خاصی اختصاص داده شده است",
"points": "پس از برنامه ریزی نوبت، هر وظیفه به فعالیتی تبدیل می شود که به یک فرد خاص واگذار می شود."
},
"realTime": {
"title": "به لحظه",
"points": "ردیابی روال عملیات در سیستم در زمان واقعی.."
},
"confirmsCompletion": {
"title": "تکمیل را تایید می کند",
"points": "پس از بستن شیفت، سرپرست شما تمام وظایف را بررسی می کند، تکمیل را تایید می کند و به کارکنان امتیاز می دهد."
}
},
"phiData": {
"title": "phi",
"desc": "طعم قهوه همیشه بیشترین اهمیت را دارد. با PHI، همیشه عالی خواهد بود. فی به معنای نسبت طلایی است. اگر قهوه خود را با نسبت طلایی دم کنید، همیشه طعم خوبی خواهد داشت. در قسمت Phi، سه کادر وجود دارد که باریستای شیفت باید آنها را پر کند. اینها عناصر اصلی برای تنظیم دستور پخت قهوه روزانه هستند:",
"endDesc": "باریستای شما دستور پخت روزانه را وارد می کند که در پایگاه داده شما ثبت می شود. می توانید نمودار تنظیم خود را مشاهده کنید و ببینید در نوار شما چه اتفاقی می افتد و کیفیت سرو قهوه خود را در فروشگاه خود بررسی کنید.",
"bcg": {
"desc": "منظور مقدار دقیق قهوه آسیاب شده برای هر دم کردن است...",
"title": "گرم قهوه پایه (BCG)"
},
"oeg": {
"desc": " وزن نهایی قهوه استخراج شده را پس از دم کردن اندازه گیری می کند.",
"title": "خروجی استخراج گراماژ(OEG)"
},
"et": {
"desc": " کل زمان دم کردن قهوه از ابتدا تا انتها است...",
"title": "زمان استخراج (ET)"
}
},
"stepProducts": {
"endDesc": "اکنون فقط شیفت های خود را برای هفته آینده تنظیم کنید. در هر شیفت، کارکنان را به هر موقعیتی اختصاص دهید و یک سرپرست تعیین کنید.",
"setupRoutine": {
"desc": "شما می توانید به طور کامل سیستم عامل خود را سفارشی و تعریف کنید...",
"title": "روال خود را تنظیم کنید"
},
"setupSections": {
"desc": "بخش های خود را برای به دست آوردن بینش بهتر در مورد عملیات خود تعریف کنید...",
"title": "بخش های خود را تنظیم کنید"
},
"setupPositions": {
"desc": "موقعیت ها نقش مهمی در پلتفرم ما دارند...",
"title": "موقعیت های خود را تنظیم کنید"
},
"setupStaffInfo": {
"desc": "شما باید اطلاعات کارکنان خود را تنظیم کنید ...",
"title": "تنظیم اطلاعات کارکنان"
},
"setupShiftsLogic": {
"desc": "شما باید منطق شیفت خود را ایجاد کنید...",
"title": "منطق شیفت خود را تنظیم کنید"
},
"insertTasks": {
"desc": "تمام وظایف خود را در این مرحله تنظیم کنید...",
"title": "همه وظایف خود را وارد کنید"
}
}
}

100
messages/zh.json 100644
View File

@ -0,0 +1,100 @@
{
"page": {
"title": "简单流畅的操作",
"desc": "一款咖啡店的任务和班次管理解决方案,提供清晰、可追踪的任务管理和店铺运营监控。",
"button": "开始使用",
"brand": "信任我们并使用 BRIZ 进行管理的品牌。"
},
"home": {
"title": "你好Next.js i18n",
"desc": "这是 Next.js i18n 的演示"
},
"navLinks": {
"ourSolution": "我们的解决方案",
"product": "产品",
"pricing": "定价",
"aboutUs": "关于我们",
"button": "开始使用"
},
"services": {
"title": "参与我们的压力测试",
"desc": "成为我们的压力测试的一部分,作为早期适配者尝试我们",
"inputValue": "输入您的号码",
"button": "订阅",
"successInput": "感谢您的信任,我们将与您联系",
"streamlinedOperations": "精简的操作",
"empoweredDecision": "赋权决策",
"unwaveringSupport": "坚定支持",
"seamlessIntegration": "无缝集成"
},
"experiences": {
"title": "基本逻辑",
"taskText": "在 Briz 完成的任务数量",
"LiveNumberTask": "使用 Briz 执行的活动",
"insertTasks": {
"title": "插入任务并分配",
"points": "插入任务并将其分配到店铺中的职位"
},
"createShiftPlan": {
"title": "创建明确的班次计划",
"points": "为每周创建明确的班次计划,并为每个班次分配监督员。"
},
"specificPerson": {
"title": "任务分配给特定人员",
"points": "班次计划后,每项任务将成为分配给特定人员的活动。"
},
"realTime": {
"title": "实时",
"points": "实时在系统中跟踪运营常规。"
},
"confirmsCompletion": {
"title": "确认完成",
"points": "班次结束后,您的监督员检查所有任务,确认完成并评估员工表现。"
}
},
"phiData": {
"title": "PHI",
"desc": "咖啡的味道永远是最重要的。有了 PHI它将永远完美。Phi 代表黄金比例。如果按照黄金比例冲泡咖啡,它将永远味道醇美。在 PHI 部分,有三个框需要当班咖啡师填写。这些是调整每日咖啡配方的主要元素:",
"endDesc": "您的咖啡师输入每日配方,这将被记录在您的数据库中。您可以查看您的调整图表,了解您的咖啡店情况,并检查店内的咖啡质量。",
"bcg": {
"desc": "这指的是每次冲泡所使用的精确咖啡粉量...",
"title": "基础咖啡克数 (BCG)"
},
"oeg": {
"desc": "这是冲泡后提取的咖啡的最终重量...",
"title": "输出提取克重 (OEG)"
},
"et": {
"desc": "这是从开始到结束冲泡咖啡所花费的总时间...",
"title": "萃取时间 (ET)"
}
},
"stepProducts": {
"endDesc": "现在为接下来的一周设置您的班次。为每个班次中的每个职位分配员工并指定监督员。",
"setupRoutine": {
"desc": "您可以完全自定义并定义您的运营系统...",
"title": "设置您的常规操作"
},
"setupSections": {
"desc": "定义您的区域以更好地了解您的运营...",
"title": "设置您的区域"
},
"setupPositions": {
"desc": "职位在我们的平台中扮演着重要角色...",
"title": "设置您的职位"
},
"setupStaffInfo": {
"desc": "您需要设置您的员工信息...",
"title": "设置员工信息"
},
"setupShiftsLogic": {
"desc": "您需要确定您的班次逻辑...",
"title": "设置您的班次逻辑"
},
"insertTasks": {
"desc": "在此阶段设置您所有的任务...",
"title": "插入所有任务"
}
}
}

View File

@ -7,18 +7,20 @@ const withPWA = require("@ducanh2912/next-pwa").default({
swcMinify: true, swcMinify: true,
dest: "public", dest: "public",
fallbacks: { fallbacks: {
//image: "/static/images/fallback.png", document: "/offline", // fallback to custom page
document: "/offline", // if you want to fallback to a custom page rather than /_offline
// font: '/static/font/fallback.woff2',
// audio: ...,
// video: ...,
}, },
workboxOptions: { workboxOptions: {
disableDevLogs: true, disableDevLogs: true,
}, },
// ... other options you like
}); });
const createNextIntlPlugin = require("next-intl/plugin");
// Initialize the next-intl plugin
const withNextIntl = createNextIntlPlugin();
// Merge the configurations
const nextConfig = {}; const nextConfig = {};
module.exports = withPWA(nextConfig); // Export the combined configuration
module.exports = withNextIntl(withPWA(nextConfig));

96
package-lock.json generated
View File

@ -24,6 +24,7 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"maath": "^0.10.4", "maath": "^0.10.4",
"next": "13.4.19", "next": "13.4.19",
"next-intl": "^3.20.0",
"postcss": "8.4.28", "postcss": "8.4.28",
"rc-slider": "^10.5.0", "rc-slider": "^10.5.0",
"react": "18.2.0", "react": "18.2.0",
@ -1797,6 +1798,50 @@
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
"optional": true "optional": true
}, },
"node_modules/@formatjs/ecma402-abstract": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.0.0.tgz",
"integrity": "sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g==",
"dependencies": {
"@formatjs/intl-localematcher": "0.5.4",
"tslib": "^2.4.0"
}
},
"node_modules/@formatjs/fast-memoize": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz",
"integrity": "sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==",
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@formatjs/icu-messageformat-parser": {
"version": "2.7.8",
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.8.tgz",
"integrity": "sha512-nBZJYmhpcSX0WeJ5SDYUkZ42AgR3xiyhNCsQweFx3cz/ULJjym8bHAzWKvG5e2+1XO98dBYC0fWeeAECAVSwLA==",
"dependencies": {
"@formatjs/ecma402-abstract": "2.0.0",
"@formatjs/icu-skeleton-parser": "1.8.2",
"tslib": "^2.4.0"
}
},
"node_modules/@formatjs/icu-skeleton-parser": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.2.tgz",
"integrity": "sha512-k4ERKgw7aKGWJZgTarIcNEmvyTVD9FYh0mTrrBMHZ1b8hUu6iOJ4SzsZlo3UNAvHYa+PnvntIwRPt1/vy4nA9Q==",
"dependencies": {
"@formatjs/ecma402-abstract": "2.0.0",
"tslib": "^2.4.0"
}
},
"node_modules/@formatjs/intl-localematcher": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz",
"integrity": "sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==",
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@hassanmojab/react-modern-calendar-datepicker": { "node_modules/@hassanmojab/react-modern-calendar-datepicker": {
"version": "3.1.7", "version": "3.1.7",
"resolved": "https://registry.npmjs.org/@hassanmojab/react-modern-calendar-datepicker/-/react-modern-calendar-datepicker-3.1.7.tgz", "resolved": "https://registry.npmjs.org/@hassanmojab/react-modern-calendar-datepicker/-/react-modern-calendar-datepicker-3.1.7.tgz",
@ -4512,6 +4557,17 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"node_modules/intl-messageformat": {
"version": "10.5.14",
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.14.tgz",
"integrity": "sha512-IjC6sI0X7YRjjyVH9aUgdftcmZK7WXdHeil4KwbjDnRWjnVitKpAx3rr6t6di1joFp5188VqKcobOPA6mCLG/w==",
"dependencies": {
"@formatjs/ecma402-abstract": "2.0.0",
"@formatjs/fast-memoize": "2.2.0",
"@formatjs/icu-messageformat-parser": "2.7.8",
"tslib": "^2.4.0"
}
},
"node_modules/is-array-buffer": { "node_modules/is-array-buffer": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
@ -5249,6 +5305,14 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
} }
}, },
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/neo-async": { "node_modules/neo-async": {
"version": "2.6.2", "version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
@ -5300,6 +5364,26 @@
} }
} }
}, },
"node_modules/next-intl": {
"version": "3.20.0",
"resolved": "https://registry.npmjs.org/next-intl/-/next-intl-3.20.0.tgz",
"integrity": "sha512-0bCZcc38HfAZk/T+PNNcnJZknC+caS5rBK+WYRd1HsOL5O6puEu2H3kya8oT9s8piHjrTf7P0UHeahOFleOnrw==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/amannn"
}
],
"dependencies": {
"@formatjs/intl-localematcher": "^0.5.4",
"negotiator": "^0.6.3",
"use-intl": "^3.20.0"
},
"peerDependencies": {
"next": "^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/next/node_modules/postcss": { "node_modules/next/node_modules/postcss": {
"version": "8.4.14", "version": "8.4.14",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
@ -7367,6 +7451,18 @@
"punycode": "^2.1.0" "punycode": "^2.1.0"
} }
}, },
"node_modules/use-intl": {
"version": "3.20.0",
"resolved": "https://registry.npmjs.org/use-intl/-/use-intl-3.20.0.tgz",
"integrity": "sha512-5WQs6yZVWI9K7vw3134P0bhKNp4mi8NbmqKOCuhD9nQUMTKdmpBXwjk62+axwvEbj4XrZxj4X93mQMLXU5ZsCg==",
"dependencies": {
"@formatjs/fast-memoize": "^2.2.0",
"intl-messageformat": "^10.5.14"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/use-isomorphic-layout-effect": { "node_modules/use-isomorphic-layout-effect": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz",

View File

@ -25,6 +25,7 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"maath": "^0.10.4", "maath": "^0.10.4",
"next": "13.4.19", "next": "13.4.19",
"next-intl": "^3.20.0",
"postcss": "8.4.28", "postcss": "8.4.28",
"rc-slider": "^10.5.0", "rc-slider": "^10.5.0",
"react": "18.2.0", "react": "18.2.0",

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -0,0 +1,25 @@
import { Inter } from "next/font/google";
import { NextIntlClientProvider } from "next-intl";
import RootData from "@comp/RootData/page";
import { getMessages } from "next-intl/server";
const inter = Inter({ subsets: ["latin"] });
// export const metadata = {
// title: "Create Next App",
// description: "Generated by create next app",
// };
export default async function RootLayout({ children, locale }) {
const messages = await getMessages();
return (
<NextIntlClientProvider messages={messages}>
<html lang={locale}>
<body className={inter.className}>
<RootData> {children}</RootData>
</body>
</html>
</NextIntlClientProvider>
);
}

View File

@ -11,9 +11,10 @@ import Footer from "@comp/landingComponents/Footer/page";
import Phi from "@comp/landingComponents/Phi"; import Phi from "@comp/landingComponents/Phi";
import StepProduct from "@comp/landingComponents/StepProduct"; import StepProduct from "@comp/landingComponents/StepProduct";
import StressTest from "@comp/landingComponents/StressTest"; import StressTest from "@comp/landingComponents/StressTest";
import { useTranslations } from "next-intl";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
export default function Home() { export default function Home(locale) {
const [state, setstate] = useState(false); const [state, setstate] = useState(false);
useEffect(() => { useEffect(() => {
@ -32,7 +33,7 @@ export default function Home() {
{/* <Feedbacks /> */} {/* <Feedbacks /> */}
<Phi /> <Phi />
<StepProduct/> <StepProduct />
<Footer /> <Footer />
</div> </div>

View File

@ -0,0 +1,12 @@
import { notFound } from "next/navigation";
import { getRequestConfig } from "next-intl/server";
import { routing } from "./routing";
export default getRequestConfig(async ({ locale }) => {
// Validate that the incoming `locale` parameter is valid
if (!routing.locales.includes(locale as any)) notFound();
return {
messages: (await import(`../../messages/${locale}.json`)).default,
};
});

View File

@ -0,0 +1,15 @@
import { defineRouting } from "next-intl/routing";
import { createSharedPathnamesNavigation } from "next-intl/navigation";
export const routing = defineRouting({
// A list of all locales that are supported
locales: ["en", "fa", "zh"],
// Used when no locale matches
defaultLocale: "en",
});
// Lightweight wrappers around Next.js' navigation APIs
// that will consider the routing configuration
export const { Link, redirect, usePathname, useRouter } =
createSharedPathnamesNavigation(routing);

View File

@ -0,0 +1,9 @@
import createMiddleware from "next-intl/middleware";
import { routing } from "./i18n/routing";
export default createMiddleware(routing);
export const config = {
// Match only internationalized pathnames
matcher: ["/", "/(fa|en|zh)/:path*"],
};