Skip to content

Commit

Permalink
Merge pull request #46 from wordigo/fix/dashboard
Browse files Browse the repository at this point in the history
feat: new dashboard
  • Loading branch information
aliosmandev authored Oct 29, 2023
2 parents d62e531 + 15ec511 commit 0359eaf
Show file tree
Hide file tree
Showing 12 changed files with 14,814 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function DataTableRowActions<TData extends object>({
}, [status]);

return (
<div className="w-full relative z-50">
<div className="w-full relative z-10">
{row.original.title !== "initial" && (
<DropdownMenu>
<DropdownMenuTrigger asChild>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useTranslation } from "next-i18next";

export interface IFeedbackType {
title: string;
imageSrc: string;
level: number;
}

const useFeedbacks = (): IFeedbackType[] => {
const { t } = useTranslation();

return [
{
title: t("general.too_bad"),
imageSrc: "/images/faces/very_bad.svg",
level: 1,
},
{
title: t("general.bad"),
imageSrc: "/images/faces/very_bad.svg",
level: 2,
},
{
title: t("general.not_bad"),
imageSrc: "/images/faces/not_bad.svg",
level: 3,
},
{
title: t("general.good"),
imageSrc: "/images/faces/good.svg",
level: 4,
},
{
title: t("general.very_good"),
imageSrc: "/images/faces/very_good.svg",
level: 5,
},
];
};

export default useFeedbacks;
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import useFeedbacksConstants, {
type IFeedbackType,
} from "./Feedback.constants";
import CButton from "@/components/UI/Button";
import { usePostFeedBackMutation } from "@/store/feedback/api";
import {
Button,
Popover,
PopoverContent,
PopoverTrigger,
Textarea,
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
toast,
} from "@wordigo/ui";
import { cn } from "@wordigo/ui/lib/utils";
import { useTranslation } from "next-i18next";
import Image from "next/image";
import { useState } from "react";

const Feedback = () => {
const { t } = useTranslation();
const [active, setActive] = useState();
const feedbacks = useFeedbacksConstants();
const [inputValue, setInputValue] = useState<string>("");
const [isFeedbackShow, setFeedbackShow] = useState(false);
const [FeedBack, { isLoading }] = usePostFeedBackMutation();

const handleSubmitFeedback = () => {
void FeedBack({
description: inputValue,
rate: active,
})
.then(() => {
toast({
title: t("notifications.success"),
description: t("feedback.success"),
});
setFeedbackShow(false);
})
.catch(() => {
toast({
title: t("notifications.error"),
description: t("feedback.error"),
});
});
};

return (
<Popover open={isFeedbackShow} onOpenChange={setFeedbackShow}>
<PopoverTrigger asChild>
<Button variant="outline">{t("feedback.title")}</Button>
</PopoverTrigger>
<PopoverContent className="w-80">
<div className="grid gap-4">
<div className="grid gap-2">
<div className="flex flex-col items-center gap-4">
<Textarea
id="width"
placeholder={t("feedback.placeholder")}
className="col-span-2 h-8"
onChange={(e) => setInputValue(e.target.value)}
/>
</div>
</div>
<div className="flex gap-x-2 items-center justify-center">
{feedbacks?.map((feedback, index) => (
<Feedback.Item
key={index}
active={active}
setActive={setActive}
{...feedback}
/>
))}
</div>
<CButton loading={isLoading} onClick={handleSubmitFeedback}>
{t("feedback.submit")}
</CButton>
</div>
</PopoverContent>
</Popover>
);
};

type IFeedbackItem = IFeedbackType & { active: any; setActive: any };

Feedback.Item = ({
title,
imageSrc,
active,
setActive,
level,
}: IFeedbackItem) => {
const handleclick = () => {
setActive(level);
};

const isActive = active === level;

return (
<TooltipProvider delayDuration={100}>
<Tooltip>
<TooltipTrigger asChild>
<Button
onClick={handleclick}
className={cn(
"rounded-full transition-all duration-25",
isActive ? " !bg-blue-100" : ""
)}
size="icon"
variant="outline"
>
<Image src={imageSrc} width={32} height={32} alt={title} />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>{title}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
};

export default Feedback;
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import homeSidebarNavigations from "./navigation.constant";
import { cn } from "@wordigo/ui/lib/utils";
import Link from "next/link";

const Navigation = ({ variant }: { variant?: "borgerMenu" }) => {
const classes = cn(
"w-full",
variant === "borgerMenu" ? "flex-col flex" : "flex items-center gap-3"
);

return (
<ul className="flex items-center font-sm mt-1 w-full">
<li className={cn(classes)}>
<Navigation.Item variant={variant} />
</li>
</ul>
);
};

Navigation.Item = ({ variant }: { variant: string }) => {
const navigations = homeSidebarNavigations();

const checkActive = (href: string) => {
if (typeof window !== "undefined") {
if (href.includes("#")) {
href = href.split("#")[0];
}

return window.location.pathname === href;
}
return false;
};

const classes_hover = cn(
variant === "borgerMenu" ??
"hover:text-foreground text-muted-foreground flex item-center"
);

return (
<>
{navigations.map((item, index) => [
<Link
href={item.href}
passHref
key={index}
className={cn(
"flex items-center w-full transition-colors text-muted-foreground text-sm hover:text-accent-foreground font-medium group relative",
variant === "borgerMenu" &&
"p-3 rounded-[6px] hover:bg-[#F8FAFC] dark:hover:bg-[#101929] mb-1",
classes_hover,
checkActive(item.href) &&
"text-accent-foreground bg-[#F8FAFC] dark:bg-[#101929] md:bg-transparent md:dark:bg-transparent md:text-muted-foreground md:dark:text-muted-foreground md:group-hover:bg-transparent md:group-hover:dark:bg-transparent md:group-hover:text-accent-foreground md:group-hover:dark:text-accent-foreground"
)}
>
{item.icon}
{item.title}
</Link>,
])}
</>
);
};

export default Navigation;
156 changes: 156 additions & 0 deletions apps/next/src/components/Layout/Dashboard/DashboardHeader/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import NavProfile from "../../NavProfile";
import ThemeMode from "../../ThemeMode";
import Feedback from "./Feedback";
import Navigation from "./Navigation";
import DashboardHeader from "@/components/Layout/Dashboard/DashboardHeader";
import DashboardNavigation from "@/components/Layout/Dashboard/Sidebar/Navigation";
import ChangeLanguage from "@/components/Layout/MainLayout/ChangeLanguage";
import DynamicLogo from "@/components/Logo/DynamicLogo";
import StaticLogo from "@/components/Logo/StaticLogo";
import { Button, Separator, buttonVariants } from "@wordigo/ui";
import { cn } from "@wordigo/ui/lib/utils";
import { AnimatePresence, motion } from "framer-motion";
import { Menu, X } from "lucide-react";
import { useSession } from "next-auth/react";
import { useTranslation } from "next-i18next";
import Link from "next/link";
import { Fragment, useState } from "react";

export default function HomeHeader({ className }: { className?: string }) {
const { t } = useTranslation();
const { status } = useSession();

const [isMenuOpen, setMenuOpen] = useState(false);

const toggleMenu = () => {
setMenuOpen(!isMenuOpen);
};

return (
<>
<div
className={cn(
"w-full fixed max-w-[90rem] bg-LightBackground dark:bg-DarkBackground z-50",
className
)}
>
<nav className="flex items-center justify-between w-full m-auto py-[1.125rem] px-20 max-md:px-4 max-8xl:px-5">
<div className="flex items-center">
<Link
href="/"
className={cn(
"flex items-center mr-6 justify-center",
!toggleMenu && "hidden"
)}
>
<StaticLogo />
<div className="font-semibold ml-[10px]">Wordigo</div>
</Link>
<span className="max-lg:hidden">
<Navigation />
</span>
</div>
<div className="flex gap-x-4 items-center max-lg:hidden">
{status === "loading" ? (
<NavProfile.Loader />
) : status === "authenticated" ? (
<Fragment>
<Feedback />
<div className="hidden md:block w-[0.5px] h-7 bg-gray-300 dark:bg-gray-700"></div>
<NavProfile />
</Fragment>
) : (
<div className="flex gap-y-6 gap-x-3 items-center">
<ThemeMode showLabel={false} className="!h-9 !px-3 !py-2" />
<ChangeLanguage className="!h-9 !px-3 !py-2" />
<div className="w-[1px] !h-9 bg-gray-200 dark:bg-gray-800"></div>
<Link
href="/auth/signup"
className={cn(
buttonVariants({ variant: "default", className: "!h-9" })
)}
>
{t("navbar.get_started")}
</Link>
</div>
)}
</div>
<Button
onClick={toggleMenu}
className="lg:hidden text-black bg-transparent bg-white"
variant="outline"
size="icon"
>
<Menu size={17} />
</Button>
</nav>
</div>
<AnimatePresence>
{isMenuOpen && (
<motion.div
initial={{ x: "100%" }}
animate={{ x: 0 }}
exit={{ x: "100%" }}
transition={{ duration: 0.3, ease: "easeInOut" }}
className="col-span-1 flex flex-col fixed justify-between top-0 right-0 z-50 py-4 text-light_text dark:text-white bg-LightBackground dark:bg-DarkBackground g-red-500 px-5 min-w-[280px] max-w-[280px] border-l shadow-md shadow-[rgba(16, 24, 40, 1)] h-screen lg:hidden z-50"
>
<span className="flex items-center flex-col w-full mb-8">
<div className="font-bold text-[18px] flex items-center select-none pt-3 justify-between w-full">
<Link
href="/"
className={cn(
"flex items-center mr-6 max-w-[128px] min-w-[128px]",
!toggleMenu && "hidden"
)}
>
<DynamicLogo size={128} />
</Link>
<Button
onClick={toggleMenu}
className="text-black dark:text-white !h-9 !w-9"
variant="outline"
size="icon"
>
<X size={19} />
</Button>
</div>

<div className="flex w-full md:flex-col py-4">
<DashboardNavigation />
</div>
</span>

<div className="lg:hidden">
<Separator className="mb-2" />
<div className="flex gap-x-4 items-center">
{status === "loading" ? (
<NavProfile.Loader />
) : status === "authenticated" ? (
<NavProfile variant="borgerMenu" />
) : (
<span className="w-full flex flex-col gap-y-3">
<div className="flex gap-x-2 items-center justify-between">
<ThemeMode className="!h-8 !px-2 w-full" />
<ChangeLanguage className="!h-8 !px-2 w-full" />
</div>
<Link
href="/auth/signup"
className={cn(
buttonVariants({
variant: "default",
className: "w-full",
})
)}
>
{t("navbar.get_started")}
</Link>
</span>
)}
</div>
</div>
</motion.div>
)}
</AnimatePresence>
</>
);
}
Loading

0 comments on commit 0359eaf

Please sign in to comment.