refactor: rename navigation function and update sidebar component

- Renamed `getNavMainLinks` to `getSidebarLinks` for improved clarity in the configuration file.
- Updated the `DashboardSidebar` component to utilize the new `getSidebarLinks` function and integrated `useCurrentUser` for user status handling.
- Enhanced the sidebar to conditionally display the upgrade card and user profile based on membership status.
- Updated comments for better understanding of the code functionality.
This commit is contained in:
javayhu 2025-04-05 08:18:55 +08:00
parent b5699b85f1
commit 9dbe79593e
7 changed files with 36 additions and 21 deletions

View File

@ -11,20 +11,22 @@ import {
SidebarMenuButton,
SidebarMenuItem
} from '@/components/ui/sidebar';
import { getNavMainLinks } from '@/config';
import { getSidebarLinks } from '@/config';
import { useCurrentUser } from '@/hooks/use-current-user';
import { LocaleLink } from '@/i18n/navigation';
import { useTranslations } from 'next-intl';
import * as React from 'react';
import { Logo } from '../logo';
import { SidebarUpgradeCard } from './sidebar-upgrade-card';
import { authClient } from '@/lib/auth-client';
export function DashboardSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
const t = useTranslations();
const mainLinks = getNavMainLinks();
const sidebarLinks = getSidebarLinks();
const currentUser = useCurrentUser();
const { data: session, error } = authClient.useSession();
const user = session?.user;
// user is a member if they have a lifetime membership or an active subscription
const isMember = currentUser?.lifetimeMember ||
(currentUser?.subscriptionId && currentUser?.subscriptionStatus === 'active');
return (
<Sidebar collapsible="icon" {...props}>
@ -47,14 +49,15 @@ export function DashboardSidebar({ ...props }: React.ComponentProps<typeof Sideb
</SidebarHeader>
<SidebarContent>
<NavMain items={mainLinks} />
<NavMain items={sidebarLinks} />
</SidebarContent>
<SidebarFooter className="flex flex-col gap-4">
{/* TODO: show or hide based on user status */}
<SidebarUpgradeCard />
{/* show upgrade card if user is not a member */}
{!isMember && <SidebarUpgradeCard />}
{user && <NavUser user={user} />}
{/* show user profile if user is logged in */}
{currentUser && <NavUser user={currentUser} />}
</SidebarFooter>
</Sidebar>
);

View File

@ -20,7 +20,7 @@ import { useEffect, useTransition } from 'react';
*
* Allows users to switch between available locales using a dropdown menu.
*
* Based on next-intl's useLocaleRouter and usePathname for locale navigation.
* Based on next-intl's useLocaleRouter and useLocalePathname for locale navigation.
* https://next-intl.dev/docs/routing/navigation#userouter
*/
export default function LocaleSwitcher() {

View File

@ -93,12 +93,15 @@ export function PricingCard({
className
)}
>
{/* show popular badge if plan is recommended */}
{plan.recommended && (
<span className="absolute inset-x-0 -top-3 mx-auto flex h-6 w-fit items-center rounded-full px-3 py-1 text-xs font-medium border
bg-purple-100 dark:bg-purple-900 text-purple-800 dark:text-purple-200 border-purple-200 dark:border-purple-800 shadow-sm">
{t('popular')}
</span>
)}
{/* show current plan badge if plan is current plan */}
{isCurrentPlan && (
<span className="absolute inset-x-0 -top-3 mx-auto flex h-6 w-fit items-center rounded-full px-3 py-1 text-xs font-medium border
bg-blue-100 dark:bg-blue-900 text-blue-800 dark:text-blue-100 border-blue-200 dark:border-blue-800 shadow-sm">
@ -109,6 +112,7 @@ export function PricingCard({
<CardHeader>
<CardTitle className="font-medium">{plan.name}</CardTitle>
{/* show price and price label */}
<div className="flex items-baseline gap-2">
<span className="my-4 block text-4xl font-semibold">
{formattedPrice}
@ -118,6 +122,7 @@ export function PricingCard({
<CardDescription className="text-sm">{plan.description}</CardDescription>
{/* show action buttons based on plans */}
{plan.isFree ? (
currentUser ? (
<Button variant="outline" className="mt-4 w-full disabled">
@ -162,6 +167,7 @@ export function PricingCard({
<CardContent className="space-y-4">
<hr className="border-dashed" />
{/* show trial period if it exists */}
{hasTrialPeriod && (
<div className="my-4">
<span className="inline-block px-2.5 py-1.5 text-xs font-medium rounded-md
@ -171,6 +177,7 @@ export function PricingCard({
</div>
)}
{/* show features of this plan */}
<ul className="list-outside space-y-4 text-sm">
{plan.features.map((feature, i) => (
<li key={i} className="flex items-center gap-2">

View File

@ -1,10 +1,9 @@
'use client';
import { Button } from '@/components/ui/button';
import { useLocaleRouter } from '@/i18n/navigation';
import { LocaleLink, useLocaleRouter } from '@/i18n/navigation';
import { cn } from '@/lib/utils';
import { ArrowLeftIcon } from 'lucide-react';
import Link from 'next/link';
interface BackButtonSmallProps {
href?: string;
@ -29,9 +28,9 @@ export default function BackButtonSmall({
asChild
>
{/* if href is provided, use it, otherwise use the router.back() */}
<Link href={href || '#'} onClick={handleBack}>
<LocaleLink href={href || '#'} onClick={handleBack}>
<ArrowLeftIcon className="size-4" />
</Link>
</LocaleLink>
</Button>
);
}

View File

@ -425,14 +425,14 @@ export function getAvatarLinks(): MenuItem[] {
}
/**
* Get sidebar navigation main links with translations
* Get sidebar navigation links with translations
*
* NOTICE: used in client components only
*
* @param t - The translation function
* @returns The menu links with translated titles and descriptions
*/
export function getNavMainLinks(): NestedMenuItem[] {
export function getSidebarLinks(): NestedMenuItem[] {
const t = useTranslations();
return [

View File

@ -14,9 +14,9 @@ export const user = pgTable("user", {
banReason: text('ban_reason'),
banExpires: timestamp('ban_expires'),
customerId: text('customer_id'),
lifetimeMember: boolean('lifetime_member'),
subscriptionId: text('subscription_id'),
subscriptionStatus: text('subscription_status'),
lifetimeMember: boolean('lifetime_member')
});
export const session = pgTable("session", {

View File

@ -116,17 +116,23 @@ export const auth = betterAuth({
defaultValue: "",
input: false, // don't allow user to set customerId
},
lifetimeMember: {
type: "boolean",
required: false,
defaultValue: false,
input: false, // don't allow user to set lifetimeMember
},
subscriptionId: {
type: "string",
required: false,
defaultValue: "",
input: false, // don't allow user to set subscriptionId
},
lifetimeMember: {
type: "boolean",
subscriptionStatus: {
type: "string",
required: false,
defaultValue: false,
input: false, // don't allow user to set lifetimeMember
defaultValue: "",
input: false, // don't allow user to set subscriptionStatus
},
},
// https://www.better-auth.com/docs/concepts/users-accounts#delete-user