Skip to content

Commit

Permalink
feat: create dashboard header component
Browse files Browse the repository at this point in the history
  • Loading branch information
ixartz committed May 15, 2024
1 parent 27e908a commit f3dc1da
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 81 deletions.
66 changes: 4 additions & 62 deletions src/app/[locale]/(auth)/dashboard/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import { OrganizationSwitcher, UserButton } from '@clerk/nextjs';
import Link from 'next/link';
import { useTranslations } from 'next-intl';
import { getTranslations } from 'next-intl/server';

import { ActiveLink } from '@/components/ActiveLink';
import LocaleSwitcher from '@/components/LocaleSwitcher';
import { Logo } from '@/templates/Logo';
import { getI18nPath } from '@/utils/Helpers';
import { DashboardHeader } from '@/features/dashboard/DashboardHeader';

export async function generateMetadata(props: { params: { locale: string } }) {
const t = await getTranslations({
Expand All @@ -20,64 +14,12 @@ export async function generateMetadata(props: { params: { locale: string } }) {
};
}

export default function DashboardLayout(props: {
children: React.ReactNode;
params: { locale: string };
}) {
const t = useTranslations('DashboardLayout');

export default function DashboardLayout(props: { children: React.ReactNode }) {
return (
<>
<div className="shadow-md">
<div className="mx-auto flex max-w-screen-xl items-center justify-between px-3 py-5">
<div className="flex items-center">
<Link href="/dashboard">
<Logo />
</Link>

<div className="ml-3">
<OrganizationSwitcher
organizationProfileMode="navigation"
organizationProfileUrl={getI18nPath(
'/dashboard/organization-profile',
props.params.locale,
)}
afterCreateOrganizationUrl="/dashboard"
hidePersonal
skipInvitationScreen
/>
</div>

<nav className="ml-3">
<ul className="flex flex-row items-center gap-x-3 text-lg font-medium [&_a:hover]:opacity-100 [&_a]:opacity-75">
<li>
<ActiveLink href="/dashboard">{t('home')}</ActiveLink>
</li>

<li>
<ActiveLink href="/dashboard/organization-profile/organization-members">
{t('members')}
</ActiveLink>
</li>

<li>
<ActiveLink href="/dashboard/organization-profile">
{t('settings')}
</ActiveLink>
</li>
</ul>
</nav>
</div>

<div className="flex items-center gap-x-4">
<LocaleSwitcher />

<UserButton
userProfileMode="navigation"
userProfileUrl="/dashboard/user-profile"
afterSignOutUrl="/"
/>
</div>
<div className="mx-auto flex max-w-screen-xl items-center justify-between px-3 py-4">
<DashboardHeader />
</div>
</div>

Expand Down
26 changes: 14 additions & 12 deletions src/components/LocaleSwitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,20 @@ export default function LocaleSwitcher() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<svg
xmlns="http://www.w3.org/2000/svg"
className="size-6 stroke-current stroke-2"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
viewBox="0 0 24 24"
>
<path stroke="none" d="M0 0h24v24H0z" />
<path d="M3 12a9 9 0 1 0 18 0 9 9 0 0 0-18 0M3.6 9h16.8M3.6 15h16.8" />
<path d="M11.5 3a17 17 0 0 0 0 18M12.5 3a17 17 0 0 1 0 18" />
</svg>
<div className="cursor-pointer px-1 py-2">
<svg
xmlns="http://www.w3.org/2000/svg"
className="size-6 stroke-current stroke-2"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
viewBox="0 0 24 24"
>
<path stroke="none" d="M0 0h24v24H0z" />
<path d="M3 12a9 9 0 1 0 18 0 9 9 0 0 0-18 0M3.6 9h16.8M3.6 15h16.8" />
<path d="M11.5 3a17 17 0 0 0 0 18M12.5 3a17 17 0 0 1 0 18" />
</svg>
</div>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuRadioGroup value={locale} onValueChange={handleChange}>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ToggleMenuButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type IToggleMenuButtonProps = {
*/
const ToggleMenuButton = (props: IToggleMenuButtonProps) => (
<button
className="rounded-md p-2 text-gray-900 hover:bg-white"
className="rounded-md px-1 py-2 hover:bg-white"
onClick={props.onClick}
type="button"
>
Expand Down
103 changes: 103 additions & 0 deletions src/features/dashboard/DashboardHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
'use client';

import { OrganizationSwitcher, UserButton } from '@clerk/nextjs';
import Link from 'next/link';
import { useLocale, useTranslations } from 'next-intl';

import { ActiveLink } from '@/components/ActiveLink';
import LocaleSwitcher from '@/components/LocaleSwitcher';
import { ToggleMenuButton } from '@/components/ToggleMenuButton';
import { Logo } from '@/templates/Logo';
import { getI18nPath } from '@/utils/Helpers';

const DashboardHeader = () => {
const t = useTranslations('DashboardLayout');
const locale = useLocale();

return (
<>
<div className="flex items-center">
<Link href="/dashboard" className="max-sm:hidden">
<Logo />
</Link>

<svg
className="ml-1 size-8 stroke-muted-foreground max-sm:hidden"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" />
<path d="M17 5 7 19" />
</svg>

<OrganizationSwitcher
organizationProfileMode="navigation"
organizationProfileUrl={getI18nPath(
'/dashboard/organization-profile',
locale,
)}
afterCreateOrganizationUrl="/dashboard"
hidePersonal
skipInvitationScreen
appearance={{
elements: {
organizationSwitcherTrigger: 'max-w-52',
},
}}
/>

<nav className="ml-3 max-lg:hidden">
<ul className="flex flex-row items-center gap-x-3 text-lg font-medium [&_a:hover]:opacity-100 [&_a]:opacity-75">
<li>
<ActiveLink href="/dashboard">{t('home')}</ActiveLink>
</li>

<li>
<ActiveLink href="/dashboard/organization-profile/organization-members">
{t('members')}
</ActiveLink>
</li>

<li>
<ActiveLink href="/dashboard/organization-profile">
{t('settings')}
</ActiveLink>
</li>
</ul>
</nav>
</div>

<div className="">
<ul className="flex items-center gap-x-1 [&_li:not(:last-child):hover]:opacity-100 [&_li:not(:last-child)]:opacity-60">
<li>
<div className="lg:hidden">
<ToggleMenuButton onClick={() => {}} />
</div>
</li>

<li>
<LocaleSwitcher />
</li>

<li>
<UserButton
userProfileMode="navigation"
userProfileUrl="/dashboard/user-profile"
afterSignOutUrl="/"
appearance={{
elements: {
rootBox: 'px-2 py-1.5',
},
}}
/>
</li>
</ul>
</div>
</>
);
};

export { DashboardHeader };
4 changes: 2 additions & 2 deletions src/features/landing/CenteredMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const CenteredMenu = (props: {
<div className="flex flex-wrap items-center justify-between">
<Link href="/">{props.logo}</Link>

<div className="lg:hidden">
<div className="lg:hidden [&_button:hover]:opacity-100 [&_button]:opacity-60">
<ToggleMenuButton onClick={handleToggleMenu} />
</div>

Expand All @@ -37,7 +37,7 @@ const CenteredMenu = (props: {
navClass,
)}
>
<ul className="flex flex-row items-center gap-x-4 text-lg font-medium [&_li:not(:last-child):hover]:opacity-100 [&_li:not(:last-child)]:opacity-60">
<ul className="flex flex-row items-center gap-x-3 text-lg font-medium [&_li:not(:last-child):hover]:opacity-100 [&_li:not(:last-child)]:opacity-60">
{props.rightMenu}
</ul>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
"title_bar": "Dashboard",
"title_bar_description": "Welcome to your dashboard",
"message_state_title": "Let's get started",
"message_state_description": "You can customize this page by editing the file at <code>src/app/[locale]/(auth)/dashboard/page.tsx</code>",
"message_state_description": "You can customize this page by editing the file at <code>dashboard/page.tsx</code>",
"message_state_button": "Read the documentation"
},
"UserProfile": {
Expand Down
4 changes: 1 addition & 3 deletions src/templates/Logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ import { AppConfig } from '@/utils/AppConfig';
const Logo = () => (
<div className="flex items-center text-xl font-semibold">
<svg
className="mr-1 stroke-current stroke-2"
className="mr-1 size-8 stroke-current stroke-2"
xmlns="http://www.w3.org/2000/svg"
width={32}
height={32}
viewBox="0 0 24 24"
fill="none"
strokeLinecap="round"
Expand Down

0 comments on commit f3dc1da

Please sign in to comment.