Skip to content

Commit

Permalink
feat: implement side menu toggling (#312)
Browse files Browse the repository at this point in the history
* feat: implement side menu toggling

* feat: some minor improvements

---------

Co-authored-by: Ahmed Elsakaan <[email protected]>
  • Loading branch information
gedeondoescode and ixahmedxi authored Sep 5, 2023
1 parent f210530 commit 8ce7402
Show file tree
Hide file tree
Showing 9 changed files with 534 additions and 680 deletions.
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@upstash/ratelimit": "^0.4.3",
"@vercel/analytics": "^1.0.2",
"date-fns": "^2.30.0",
"framer-motion": "^10.16.3",
"lucide-react": "0.263.1",
"next": "13.4.19",
"next-mdx-remote": "^4.4.1",
Expand Down
24 changes: 21 additions & 3 deletions apps/web/src/layouts/dashboard/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Dispatch, FC, SetStateAction } from 'react';
import { UserButton } from '@clerk/nextjs';
import { dark } from '@clerk/themes';
import { useRouter } from 'next/router';
Expand All @@ -6,13 +7,30 @@ import { Button } from '@noodle/ui';

import { Icon } from '@/components/Icon';

export const DashboardNavbar = () => {
type NavbarProps = {
isSideMenuExpanded: boolean;
setSideMenuExpanded: Dispatch<SetStateAction<boolean>>;
};

export const DashboardNavbar: FC<NavbarProps> = ({
isSideMenuExpanded = true,
setSideMenuExpanded,
}) => {
const router = useRouter();
return (
<nav className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Button type="button" variant="muted" size="icon">
<Icon name="panel-left-close" />
<Button
type="button"
variant="muted"
size="icon"
onClick={() => {
setSideMenuExpanded((prev) => !prev);
}}
>
<Icon
name={isSideMenuExpanded ? 'panel-left-close' : 'panel-left-open'}
/>
</Button>

<div className="flex items-center">
Expand Down
20 changes: 17 additions & 3 deletions apps/web/src/layouts/dashboard/SideMenuLink.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { type FC } from 'react';
import type { IconNames } from '@/components/Icon';
import { motion } from 'framer-motion';

import { Button } from '@noodle/ui';

Expand All @@ -10,18 +11,31 @@ type SideMenuLinkProps = {
href: string;
icon: IconNames;
label: string;
isSideMenuExpanded: boolean;
};

export const SideMenuLink: FC<SideMenuLinkProps> = ({ href, icon, label }) => {
export const SideMenuLink: FC<SideMenuLinkProps> = ({
href,
icon,
label,
isSideMenuExpanded = true,
}) => {
return (
<li>
<Button asChild variant="muted" className="w-full">
<ActiveLink
href={href}
activeClassName="text-gray-12 dark:text-graydark-12"
>
<Icon name={icon} />
<span>{label}</span>
<Icon name={icon} className="min-w-max" />
<motion.span
animate={{
opacity: isSideMenuExpanded ? 1 : 0,
}}
transition={{ duration: 0.2 }}
>
{label}
</motion.span>
</ActiveLink>
</Button>
</li>
Expand Down
6 changes: 3 additions & 3 deletions apps/web/src/layouts/dashboard/SideMenuModules.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ import { Icon } from '@/components/Icon';
export const SideMenuModules = () => {
return (
<div className="mt-4">
<div className="flex items-center justify-between px-4">
<div className="flex min-w-[180px] items-center justify-between px-4">
<Typography.P as="h3" className="text-xs">
Modules
</Typography.P>
<Button type="button" variant="muted" size="icon" className="p-2">
<Icon name="plus" size={16} />
</Button>
</div>
<div className="w-full">
<Typography.P className="w-[220px] px-4 pt-1 text-xs leading-4 opacity-50">
<div>
<Typography.P className="line-clamp-2 overflow-hidden px-4 pt-1 text-xs leading-4 opacity-50">
Create modules to organize your study material.
</Typography.P>
</div>
Expand Down
19 changes: 16 additions & 3 deletions apps/web/src/layouts/dashboard/feedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useForm } from 'react-hook-form';
import { useUser } from '@clerk/nextjs';
import { zodResolver } from '@hookform/resolvers/zod';
import { type TRPCErrorResponse } from '@trpc/server/rpc';
import { motion } from 'framer-motion';
import { z } from 'zod';

import {
Expand Down Expand Up @@ -120,15 +121,27 @@ const FeedbackForm: FC<{ email?: string | undefined }> = ({ email }) => {
);
};

export const FeedbackDialog = () => {
type FeedbackDialogProps = {
isSideMenuExpanded?: boolean;
};

export const FeedbackDialog: FC<FeedbackDialogProps> = ({
isSideMenuExpanded = true,
}) => {
const { user } = useUser();

return (
<Dialog>
<DialogTrigger asChild>
<Button variant="muted" className="w-full">
<Icon name="badge-help" />
Provide feedback
<Icon name="badge-help" className="min-w-max" />
<motion.span
className="min-w-max"
animate={{ opacity: isSideMenuExpanded ? 1 : 0 }}
transition={{ duration: 0.2 }}
>
Provide feedback
</motion.span>
</Button>
</DialogTrigger>

Expand Down
35 changes: 27 additions & 8 deletions apps/web/src/layouts/dashboard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { useState } from 'react';
import type { FC, PropsWithChildren } from 'react';
import { motion } from 'framer-motion';

import { Brand } from '@noodle/ui';

Expand All @@ -9,28 +11,45 @@ import { SideMenuModules } from './SideMenuModules';
import { pageLinks } from './static-data';

const DashboardLayout: FC<PropsWithChildren> = ({ children }) => {
const [isSideMenuExpanded, setSideMenuExpanded] = useState(true);

return (
<div className="flex h-screen gap-6 p-6">
{/* Side Menu */}
<aside className="flex min-w-[220px] flex-col justify-between">
<motion.aside
className="flex flex-col justify-between"
animate={{ width: isSideMenuExpanded ? '181px' : '51px' }}
transition={{ duration: 0.3 }}
>
<div>
<Brand className="ml-4" size={35} />

<ul className="mt-8 flex flex-col gap-2">
{pageLinks.map((link) => (
<SideMenuLink key={link.href} {...link} />
<SideMenuLink
key={link.href}
{...link}
isSideMenuExpanded={isSideMenuExpanded}
/>
))}
</ul>

<SideMenuModules />
<motion.div
animate={{ opacity: isSideMenuExpanded ? 1 : 0 }}
transition={{ duration: 0.2 }}
>
<SideMenuModules />
</motion.div>
</div>

<FeedbackDialog />
</aside>
<FeedbackDialog isSideMenuExpanded={isSideMenuExpanded} />
</motion.aside>

<div className="border-gray-3 dark:border-graydark-3 flex flex-1 flex-col overflow-scroll rounded-2xl border px-6 py-4">
<div className="border-gray-3 dark:border-graydark-3 bg-gray-1 dark:bg-graydark-1 z-50 flex flex-1 flex-col overflow-scroll rounded-2xl border px-6 py-4">
{/* Top Navigation Bar */}
<DashboardNavbar />
<DashboardNavbar
setSideMenuExpanded={setSideMenuExpanded}
isSideMenuExpanded={isSideMenuExpanded}
/>

{/* Page Content */}
<div className="flex h-full w-full overflow-scroll">{children}</div>
Expand Down
1 change: 1 addition & 0 deletions packages/config/tailwind/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@noodle/tsconfig": "workspace:^",
"@radix-ui/colors": "^2.1.0",
"@savvywombat/tailwindcss-grid-areas": "^3.1.0",
"@tailwindcss/line-clamp": "^0.4.4",
"autoprefixer": "^10.4.15",
"tailwindcss-animate": "^1.0.7",
"tailwindcss-radix-colors": "^0.5.1"
Expand Down
1 change: 1 addition & 0 deletions packages/config/tailwind/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const config = {
require('tailwindcss-radix-colors'),
require('tailwindcss-animate'),
require('@savvywombat/tailwindcss-grid-areas'),
require('@tailwindcss/line-clamp'),
],
} satisfies Config;

Expand Down
Loading

0 comments on commit 8ce7402

Please sign in to comment.