refactor: improve code quality and consistency (#197)

* refactor: convert components to named exports

- Convert arrow function components to function declarations
- Replace React.forwardRef with modern TypeScript patterns
- Remove unnecessary displayName assignments
- Ensure consistent component declaration style across codebase

* refactor: convert all components to named exports for consistency

- Convert default exports to named exports across features directory
- Update all import statements to use named imports
- Move sidebarNavItems outside Settings component for better organization
- Improve component parameter formatting for readability
- Ensure consistent export patterns throughout codebase

* refactor: enforce and update import type for typescript types
This commit is contained in:
Sat Naing
2025-08-04 08:02:29 +07:00
parent bb0bc7d9bc
commit cb131826e2
125 changed files with 239 additions and 256 deletions

View File

@@ -42,6 +42,15 @@ export default tseslint.config(
ignoreRestSiblings: true,
},
],
// Enforce type-only imports for TypeScript types
'@typescript-eslint/consistent-type-imports': [
'error',
{
prefer: 'type-imports',
fixStyle: 'inline-type-imports',
disallowTypeAnnotations: false,
},
],
},
}
)

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconDiscord({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconDocker({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconFacebook({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconFigma({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconGithub({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconGitlab({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconGmail({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconMedium({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconNotion({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconSkype({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconSlack({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconStripe({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconTelegram({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconTrello({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconWhatsapp({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconZoom({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
export function ClerkFullLogo(props: SVGProps<SVGSVGElement>) {
return (

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function ClerkLogo({ className, ...props }: SVGProps<SVGSVGElement>) {

View File

@@ -1,6 +1,6 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
import { Direction } from '@/context/direction-context'
import { type Direction } from '@/context/direction-context'
interface Props extends SVGProps<SVGSVGElement> {
dir: Direction

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
export function IconLayoutCompact(props: SVGProps<SVGSVGElement>) {
return (

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
export function IconLayoutDefault(props: SVGProps<SVGSVGElement>) {
return (

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
export function IconLayoutFull(props: SVGProps<SVGSVGElement>) {
return (

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
export function IconSidebarFloating(props: SVGProps<SVGSVGElement>) {
return (

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
export function IconSidebarInset(props: SVGProps<SVGSVGElement>) {
return (

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
export function IconSidebarSidebar(props: SVGProps<SVGSVGElement>) {
return (

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
export function IconThemeDark(props: SVGProps<SVGSVGElement>) {
return (

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
export function IconThemeLight(props: SVGProps<SVGSVGElement>) {
return (

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { cn } from '@/lib/utils'
export function IconThemeSystem({

View File

@@ -1,5 +1,5 @@
import { useState, useEffect, useRef } from 'react'
import { Table } from '@tanstack/react-table'
import { type Table } from '@tanstack/react-table'
import { X } from 'lucide-react'
import { cn } from '@/lib/utils'
import { Badge } from '@/components/ui/badge'

View File

@@ -1,6 +1,6 @@
import { Telescope } from 'lucide-react'
export default function ComingSoon() {
export function ComingSoon() {
return (
<div className='h-svh'>
<div className='m-auto flex h-full w-full flex-col items-center justify-center gap-2'>

View File

@@ -1,4 +1,4 @@
import { SVGProps } from 'react'
import { type SVGProps } from 'react'
import { Root as Radio, Item } from '@radix-ui/react-radio-group'
import { CircleCheck, RotateCcw, Settings } from 'lucide-react'
import { IconDir } from '@/assets/custom/icon-dir'
@@ -13,7 +13,7 @@ import { IconThemeLight } from '@/assets/custom/icon-theme-light'
import { IconThemeSystem } from '@/assets/custom/icon-theme-system'
import { cn } from '@/lib/utils'
import { useDirection } from '@/context/direction-context'
import { Collapsible, useLayout } from '@/context/layout-context'
import { type Collapsible, useLayout } from '@/context/layout-context'
import { useTheme } from '@/context/theme-context'
import { Button } from '@/components/ui/button'
import {

View File

@@ -12,7 +12,7 @@ import {
SidebarRail,
} from '@/components/ui/sidebar'
import { AppSidebar } from '@/components/layout/app-sidebar'
import SkipToMain from '@/components/skip-to-main'
import { SkipToMain } from '@/components/skip-to-main'
import { sidebarData } from './data/sidebar-data'
import { NavGroup } from './nav-group'
import { NavUser } from './nav-user'

View File

@@ -8,12 +8,7 @@ interface HeaderProps extends React.HTMLAttributes<HTMLElement> {
ref?: React.Ref<HTMLElement>
}
export const Header = ({
className,
fixed,
children,
...props
}: HeaderProps) => {
export function Header({ className, fixed, children, ...props }: HeaderProps) {
const [offset, setOffset] = React.useState(0)
React.useEffect(() => {
@@ -53,5 +48,3 @@ export const Header = ({
</header>
)
}
Header.displayName = 'Header'

View File

@@ -7,7 +7,7 @@ interface MainProps extends React.HTMLAttributes<HTMLElement> {
ref?: React.Ref<HTMLElement>
}
export const Main = ({ fixed, className, fluid, ...props }: MainProps) => {
export function Main({ fixed, className, fluid, ...props }: MainProps) {
return (
<main
data-layout={fixed ? 'fixed' : 'auto'}
@@ -26,5 +26,3 @@ export const Main = ({ fixed, className, fluid, ...props }: MainProps) => {
/>
)
}
Main.displayName = 'Main'

View File

@@ -1,4 +1,4 @@
import { ReactNode } from 'react'
import { type ReactNode } from 'react'
import { Link, useLocation } from '@tanstack/react-router'
import { ChevronRight } from 'lucide-react'
import {
@@ -26,7 +26,7 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '../ui/dropdown-menu'
import { NavCollapsible, NavItem, NavLink, type NavGroup } from './types'
import { type NavCollapsible, type NavItem, type NavLink, type NavGroup } from './types'
export function NavGroup({ title, items }: NavGroup) {
const { state, isMobile } = useSidebar()
@@ -53,11 +53,11 @@ export function NavGroup({ title, items }: NavGroup) {
)
}
const NavBadge = ({ children }: { children: ReactNode }) => (
<Badge className='rounded-full px-1 py-0 text-xs'>{children}</Badge>
)
function NavBadge({ children }: { children: ReactNode }) {
return <Badge className='rounded-full px-1 py-0 text-xs'>{children}</Badge>
}
const SidebarMenuLink = ({ item, href }: { item: NavLink; href: string }) => {
function SidebarMenuLink({ item, href }: { item: NavLink; href: string }) {
const { setOpenMobile } = useSidebar()
return (
<SidebarMenuItem>
@@ -76,13 +76,13 @@ const SidebarMenuLink = ({ item, href }: { item: NavLink; href: string }) => {
)
}
const SidebarMenuCollapsible = ({
function SidebarMenuCollapsible({
item,
href,
}: {
item: NavCollapsible
href: string
}) => {
}) {
const { setOpenMobile } = useSidebar()
return (
<Collapsible
@@ -122,13 +122,13 @@ const SidebarMenuCollapsible = ({
)
}
const SidebarMenuCollapsedDropdown = ({
function SidebarMenuCollapsedDropdown({
item,
href,
}: {
item: NavCollapsible
href: string
}) => {
}) {
return (
<SidebarMenuItem>
<DropdownMenu>

View File

@@ -1,4 +1,4 @@
import { LinkProps } from '@tanstack/react-router'
import { type LinkProps } from '@tanstack/react-router'
interface User {
name: string

View File

@@ -1,4 +1,4 @@
import { Root, Content, Trigger } from '@radix-ui/react-popover'
import { type Root, type Content, type Trigger } from '@radix-ui/react-popover'
import { CircleQuestionMark } from 'lucide-react'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'

View File

@@ -18,7 +18,7 @@ interface Props {
contentClassName?: string
}
export default function LongText({
export function LongText({
children,
className = '',
contentClassName = '',

View File

@@ -1,6 +1,6 @@
import { useEffect, useRef } from 'react'
import { useRouterState } from '@tanstack/react-router'
import LoadingBar, { LoadingBarRef } from 'react-top-loading-bar'
import LoadingBar, { type LoadingBarRef } from 'react-top-loading-bar'
export function NavigationProgress() {
const ref = useRef<LoadingBarRef>(null)

View File

@@ -6,34 +6,37 @@ import { Button } from './ui/button'
type PasswordInputProps = Omit<
React.InputHTMLAttributes<HTMLInputElement>,
'type'
>
> & {
ref?: React.Ref<HTMLInputElement>
}
const PasswordInput = React.forwardRef<HTMLInputElement, PasswordInputProps>(
({ className, disabled, ...props }, ref) => {
const [showPassword, setShowPassword] = React.useState(false)
return (
<div className={cn('relative rounded-md', className)}>
<input
type={showPassword ? 'text' : 'password'}
className='border-input placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-sm shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-1 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50'
ref={ref}
disabled={disabled}
{...props}
/>
<Button
type='button'
size='icon'
variant='ghost'
disabled={disabled}
className='text-muted-foreground absolute end-1 top-1/2 h-6 w-6 -translate-y-1/2 rounded-md'
onClick={() => setShowPassword((prev) => !prev)}
>
{showPassword ? <Eye size={18} /> : <EyeOff size={18} />}
</Button>
</div>
)
}
)
PasswordInput.displayName = 'PasswordInput'
export function PasswordInput({
className,
disabled,
ref,
...props
}: PasswordInputProps) {
const [showPassword, setShowPassword] = React.useState(false)
export { PasswordInput }
return (
<div className={cn('relative rounded-md', className)}>
<input
type={showPassword ? 'text' : 'password'}
className='border-input placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-sm shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-1 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50'
ref={ref}
disabled={disabled}
{...props}
/>
<Button
type='button'
size='icon'
variant='ghost'
disabled={disabled}
className='text-muted-foreground absolute end-1 top-1/2 h-6 w-6 -translate-y-1/2 rounded-md'
onClick={() => setShowPassword((prev) => !prev)}
>
{showPassword ? <Eye size={18} /> : <EyeOff size={18} />}
</Button>
</div>
)
}

View File

@@ -1,4 +1,4 @@
const SkipToMain = () => {
export function SkipToMain() {
return (
<a
className={`bg-primary text-primary-foreground hover:bg-primary/90 focus-visible:ring-ring fixed start-44 z-999 -translate-y-52 px-4 py-2 text-sm font-medium whitespace-nowrap opacity-95 shadow-sm transition focus:translate-y-3 focus:transform focus-visible:ring-1`}
@@ -8,5 +8,3 @@ const SkipToMain = () => {
</a>
)
}
export default SkipToMain

View File

@@ -1,7 +1,7 @@
import { Toaster as Sonner, ToasterProps } from 'sonner'
import { useTheme } from '@/context/theme-context'
const Toaster = ({ ...props }: ToasterProps) => {
export function Toaster({ ...props }: ToasterProps) {
const { theme = 'system' } = useTheme()
return (
@@ -19,5 +19,3 @@ const Toaster = ({ ...props }: ToasterProps) => {
/>
)
}
export { Toaster }

View File

@@ -23,7 +23,7 @@ const appText = new Map<string, string>([
['notConnected', 'Not Connected'],
])
export default function Apps() {
export function Apps() {
const [sort, setSort] = useState('ascending')
const [appType, setAppType] = useState('all')
const [searchTerm, setSearchTerm] = useState('')

View File

@@ -2,7 +2,7 @@ interface Props {
children: React.ReactNode
}
export default function AuthLayout({ children }: Props) {
export function AuthLayout({ children }: Props) {
return (
<div className='container grid h-svh max-w-none items-center justify-center'>
<div className='mx-auto flex w-full flex-col justify-center space-y-2 py-8 sm:w-[480px] sm:p-8'>

View File

@@ -1,4 +1,4 @@
import { HTMLAttributes, useState } from 'react'
import { type HTMLAttributes, useState } from 'react'
import { z } from 'zod'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'

View File

@@ -7,10 +7,10 @@ import {
CardHeader,
CardTitle,
} from '@/components/ui/card'
import AuthLayout from '../auth-layout'
import { AuthLayout } from '../auth-layout'
import { ForgotPasswordForm } from './components/forgot-password-form'
export default function ForgotPassword() {
export function ForgotPassword() {
return (
<AuthLayout>
<Card className='gap-4'>

View File

@@ -1,4 +1,4 @@
import { HTMLAttributes, useState } from 'react'
import { type HTMLAttributes, useState } from 'react'
import { z } from 'zod'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'

View File

@@ -7,10 +7,10 @@ import {
CardHeader,
CardTitle,
} from '@/components/ui/card'
import AuthLayout from '../auth-layout'
import { AuthLayout } from '../auth-layout'
import { OtpForm } from './components/otp-form'
export default function Otp() {
export function Otp() {
return (
<AuthLayout>
<Card className='gap-4'>

View File

@@ -1,4 +1,4 @@
import { HTMLAttributes, useState } from 'react'
import { type HTMLAttributes, useState } from 'react'
import { z } from 'zod'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'

View File

@@ -6,10 +6,10 @@ import {
CardHeader,
CardTitle,
} from '@/components/ui/card'
import AuthLayout from '../auth-layout'
import { AuthLayout } from '../auth-layout'
import { UserAuthForm } from './components/user-auth-form'
export default function SignIn() {
export function SignIn() {
return (
<AuthLayout>
<Card className='gap-4'>

View File

@@ -1,7 +1,7 @@
import ViteLogo from '@/assets/vite.svg'
import { UserAuthForm } from './components/user-auth-form'
export default function SignIn2() {
export function SignIn2() {
return (
<div className='relative container grid h-svh flex-col items-center justify-center lg:max-w-none lg:grid-cols-2 lg:px-0'>
<div className='bg-muted relative hidden h-full flex-col p-10 text-white lg:flex dark:border-e'>

View File

@@ -1,4 +1,4 @@
import { HTMLAttributes, useState } from 'react'
import { type HTMLAttributes, useState } from 'react'
import { z } from 'zod'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'

View File

@@ -7,10 +7,10 @@ import {
CardHeader,
CardTitle,
} from '@/components/ui/card'
import AuthLayout from '../auth-layout'
import { AuthLayout } from '../auth-layout'
import { SignUpForm } from './components/sign-up-form'
export default function SignUp() {
export function SignUp() {
return (
<AuthLayout>
<Card className='gap-4'>

View File

@@ -17,7 +17,7 @@ import {
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog'
import { ChatUser } from '../data/chat-types'
import { type ChatUser } from '../data/chat-types'
type User = Omit<ChatUser, 'messages'>

View File

@@ -1,4 +1,4 @@
import { conversations } from './convo.json'
import { type conversations } from './convo.json'
export type ChatUser = (typeof conversations)[number]
export type Convo = ChatUser['messages'][number]

View File

@@ -29,7 +29,7 @@ import { type ChatUser, type Convo } from './data/chat-types'
// Fake Data
import { conversations } from './data/convo.json'
export default function Chats() {
export function Chats() {
const [search, setSearch] = useState('')
const [selectedUser, setSelectedUser] = useState<ChatUser | null>(null)
const [mobileSelectedUser, setMobileSelectedUser] = useState<ChatUser | null>(

View File

@@ -16,7 +16,7 @@ import { ThemeSwitch } from '@/components/theme-switch'
import { Overview } from './components/overview'
import { RecentSales } from './components/recent-sales'
export default function Dashboard() {
export function Dashboard() {
return (
<>
{/* ===== Top Heading ===== */}

View File

@@ -1,7 +1,7 @@
import { useNavigate, useRouter } from '@tanstack/react-router'
import { Button } from '@/components/ui/button'
export default function ForbiddenError() {
export function ForbiddenError() {
const navigate = useNavigate()
const { history } = useRouter()
return (

View File

@@ -6,7 +6,7 @@ interface GeneralErrorProps extends React.HTMLAttributes<HTMLDivElement> {
minimal?: boolean
}
export default function GeneralError({
export function GeneralError({
className,
minimal = false,
}: GeneralErrorProps) {

View File

@@ -1,6 +1,6 @@
import { Button } from '@/components/ui/button'
export default function MaintenanceError() {
export function MaintenanceError() {
return (
<div className='h-svh'>
<div className='m-auto flex h-full w-full flex-col items-center justify-center gap-2'>

View File

@@ -1,7 +1,7 @@
import { useNavigate, useRouter } from '@tanstack/react-router'
import { Button } from '@/components/ui/button'
export default function NotFoundError() {
export function NotFoundError() {
const navigate = useNavigate()
const { history } = useRouter()
return (

View File

@@ -1,7 +1,7 @@
import { useNavigate, useRouter } from '@tanstack/react-router'
import { Button } from '@/components/ui/button'
export default function UnauthorisedError() {
export function UnauthorisedError() {
const navigate = useNavigate()
const { history } = useRouter()
return (

View File

@@ -1,7 +1,7 @@
import ContentSection from '../components/content-section'
import { ContentSection } from '../components/content-section'
import { AccountForm } from './account-form'
export default function SettingsAccount() {
export function SettingsAccount() {
return (
<ContentSection
title='Account'

View File

@@ -1,7 +1,7 @@
import ContentSection from '../components/content-section'
import { ContentSection } from '../components/content-section'
import { AppearanceForm } from './appearance-form'
export default function SettingsAppearance() {
export function SettingsAppearance() {
return (
<ContentSection
title='Appearance'

View File

@@ -6,11 +6,7 @@ interface ContentSectionProps {
children: React.JSX.Element
}
export default function ContentSection({
title,
desc,
children,
}: ContentSectionProps) {
export function ContentSection({ title, desc, children }: ContentSectionProps) {
return (
<div className='flex flex-1 flex-col'>
<div className='flex-none'>

View File

@@ -20,11 +20,7 @@ interface SidebarNavProps extends React.HTMLAttributes<HTMLElement> {
}[]
}
export default function SidebarNav({
className,
items,
...props
}: SidebarNavProps) {
export function SidebarNav({ className, items, ...props }: SidebarNavProps) {
const { pathname } = useLocation()
const navigate = useNavigate()
const [val, setVal] = useState(pathname ?? '/settings')

View File

@@ -1,7 +1,7 @@
import ContentSection from '../components/content-section'
import { ContentSection } from '../components/content-section'
import { DisplayForm } from './display-form'
export default function SettingsDisplay() {
export function SettingsDisplay() {
return (
<ContentSection
title='Display'

View File

@@ -6,9 +6,37 @@ import { Main } from '@/components/layout/main'
import { ProfileDropdown } from '@/components/profile-dropdown'
import { Search } from '@/components/search'
import { ThemeSwitch } from '@/components/theme-switch'
import SidebarNav from './components/sidebar-nav'
import { SidebarNav } from './components/sidebar-nav'
export default function Settings() {
const sidebarNavItems = [
{
title: 'Profile',
href: '/settings',
icon: <UserCog size={18} />,
},
{
title: 'Account',
href: '/settings/account',
icon: <Wrench size={18} />,
},
{
title: 'Appearance',
href: '/settings/appearance',
icon: <Palette size={18} />,
},
{
title: 'Notifications',
href: '/settings/notifications',
icon: <Bell size={18} />,
},
{
title: 'Display',
href: '/settings/display',
icon: <Monitor size={18} />,
},
]
export function Settings() {
return (
<>
{/* ===== Top Heading ===== */}
@@ -42,31 +70,3 @@ export default function Settings() {
</>
)
}
const sidebarNavItems = [
{
title: 'Profile',
href: '/settings',
icon: <UserCog size={18} />,
},
{
title: 'Account',
href: '/settings/account',
icon: <Wrench size={18} />,
},
{
title: 'Appearance',
href: '/settings/appearance',
icon: <Palette size={18} />,
},
{
title: 'Notifications',
href: '/settings/notifications',
icon: <Bell size={18} />,
},
{
title: 'Display',
href: '/settings/display',
icon: <Monitor size={18} />,
},
]

View File

@@ -1,7 +1,7 @@
import ContentSection from '../components/content-section'
import { ContentSection } from '../components/content-section'
import { NotificationsForm } from './notifications-form'
export default function SettingsNotifications() {
export function SettingsNotifications() {
return (
<ContentSection
title='Notifications'

View File

@@ -1,7 +1,7 @@
import ContentSection from '../components/content-section'
import ProfileForm from './profile-form'
import { ContentSection } from '../components/content-section'
import { ProfileForm } from './profile-form'
export default function SettingsProfile() {
export function SettingsProfile() {
return (
<ContentSection
title='Profile'

View File

@@ -56,7 +56,7 @@ const defaultValues: Partial<ProfileFormValues> = {
],
}
export default function ProfileForm() {
export function ProfileForm() {
const form = useForm<ProfileFormValues>({
resolver: zodResolver(profileFormSchema),
defaultValues,

View File

@@ -1,8 +1,8 @@
import { ColumnDef } from '@tanstack/react-table'
import { type ColumnDef } from '@tanstack/react-table'
import { Badge } from '@/components/ui/badge'
import { Checkbox } from '@/components/ui/checkbox'
import { labels, priorities, statuses } from '../data/data'
import { Task } from '../data/schema'
import { type Task } from '../data/schema'
import { DataTableColumnHeader } from './data-table-column-header'
import { DataTableRowActions } from './data-table-row-actions'

View File

@@ -1,5 +1,5 @@
import { useState } from 'react'
import { Table } from '@tanstack/react-table'
import { type Table } from '@tanstack/react-table'
import { Trash2, CircleArrowUp, ArrowUpDown, Download } from 'lucide-react'
import { toast } from 'sonner'
import { sleep } from '@/utils/sleep'
@@ -17,7 +17,7 @@ import {
} from '@/components/ui/tooltip'
import { BulkActionsToolbar } from '@/components/bulk-actions-toolbar'
import { priorities, statuses } from '../data/data'
import { Task } from '../data/schema'
import { type Task } from '../data/schema'
import { TasksMultiDeleteDialog } from './tasks-multi-delete-dialog'
interface DataTableBulkActionsProps<TData> {

View File

@@ -4,7 +4,7 @@ import {
CaretSortIcon,
EyeNoneIcon,
} from '@radix-ui/react-icons'
import { Column } from '@tanstack/react-table'
import { type Column } from '@tanstack/react-table'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import {

View File

@@ -1,6 +1,6 @@
import * as React from 'react'
import { CheckIcon, PlusCircledIcon } from '@radix-ui/react-icons'
import { Column } from '@tanstack/react-table'
import { type Column } from '@tanstack/react-table'
import { cn } from '@/lib/utils'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'

View File

@@ -4,7 +4,7 @@ import {
DoubleArrowLeftIcon,
DoubleArrowRightIcon,
} from '@radix-ui/react-icons'
import { Table } from '@tanstack/react-table'
import { type Table } from '@tanstack/react-table'
import { Button } from '@/components/ui/button'
import {
Select,

View File

@@ -1,5 +1,5 @@
import { DotsHorizontalIcon } from '@radix-ui/react-icons'
import { Row } from '@tanstack/react-table'
import { type Row } from '@tanstack/react-table'
import { Trash2 } from 'lucide-react'
import { Button } from '@/components/ui/button'
import {

View File

@@ -1,5 +1,5 @@
import { Cross2Icon } from '@radix-ui/react-icons'
import { Table } from '@tanstack/react-table'
import { type Table } from '@tanstack/react-table'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { DataTableViewOptions } from '../components/data-table-view-options'

View File

@@ -1,6 +1,6 @@
import { DropdownMenuTrigger } from '@radix-ui/react-dropdown-menu'
import { MixerHorizontalIcon } from '@radix-ui/react-icons'
import { Table } from '@tanstack/react-table'
import { type Table } from '@tanstack/react-table'
import { Button } from '@/components/ui/button'
import {
DropdownMenu,

View File

@@ -1,9 +1,9 @@
import * as React from 'react'
import {
ColumnDef,
ColumnFiltersState,
SortingState,
VisibilityState,
type ColumnDef,
type ColumnFiltersState,
type SortingState,
type VisibilityState,
flexRender,
getCoreRowModel,
getFacetedRowModel,

View File

@@ -1,7 +1,7 @@
'use client'
import { useState } from 'react'
import { Table } from '@tanstack/react-table'
import { type Table } from '@tanstack/react-table'
import { AlertTriangle } from 'lucide-react'
import { toast } from 'sonner'
import { sleep } from '@/utils/sleep'

View File

@@ -23,7 +23,7 @@ import {
SheetTitle,
} from '@/components/ui/sheet'
import { SelectDropdown } from '@/components/select-dropdown'
import { Task } from '../data/schema'
import { type Task } from '../data/schema'
interface Props {
open: boolean

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react'
import useDialogState from '@/hooks/use-dialog-state'
import { Task } from '../data/schema'
import { type Task } from '../data/schema'
type TasksDialogType = 'create' | 'update' | 'delete' | 'import'
@@ -13,11 +13,7 @@ interface TasksContextType {
const TasksContext = React.createContext<TasksContextType | null>(null)
interface Props {
children: React.ReactNode
}
export default function TasksProvider({ children }: Props) {
export function TasksProvider({ children }: { children: React.ReactNode }) {
const [open, setOpen] = useDialogState<TasksDialogType>(null)
const [currentRow, setCurrentRow] = useState<Task | null>(null)
return (

View File

@@ -8,10 +8,10 @@ import { columns } from './components/columns'
import { DataTable } from './components/data-table'
import { TasksDialogs } from './components/tasks-dialogs'
import { TasksPrimaryButtons } from './components/tasks-primary-buttons'
import TasksProvider from './context/tasks-context'
import { TasksProvider } from './context/tasks-context'
import { tasks } from './data/tasks'
export default function Tasks() {
export function Tasks() {
return (
<TasksProvider>
<Header fixed>

View File

@@ -1,5 +1,5 @@
import { useState } from 'react'
import { Table } from '@tanstack/react-table'
import { type Table } from '@tanstack/react-table'
import { Trash2, UserX, UserCheck, Mail } from 'lucide-react'
import { toast } from 'sonner'
import { sleep } from '@/utils/sleep'
@@ -10,7 +10,7 @@ import {
TooltipTrigger,
} from '@/components/ui/tooltip'
import { BulkActionsToolbar } from '@/components/bulk-actions-toolbar'
import { User } from '../data/schema'
import { type User } from '../data/schema'
import { UsersMultiDeleteDialog } from './users-multi-delete-dialog'
interface DataTableBulkActionsProps<TData> {

View File

@@ -4,7 +4,7 @@ import {
CaretSortIcon,
EyeNoneIcon,
} from '@radix-ui/react-icons'
import { Column } from '@tanstack/react-table'
import { type Column } from '@tanstack/react-table'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import {

View File

@@ -1,6 +1,6 @@
import * as React from 'react'
import { CheckIcon, PlusCircledIcon } from '@radix-ui/react-icons'
import { Column } from '@tanstack/react-table'
import { type Column } from '@tanstack/react-table'
import { cn } from '@/lib/utils'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'

View File

@@ -4,7 +4,7 @@ import {
DoubleArrowLeftIcon,
DoubleArrowRightIcon,
} from '@radix-ui/react-icons'
import { Table } from '@tanstack/react-table'
import { type Table } from '@tanstack/react-table'
import { Button } from '@/components/ui/button'
import {
Select,

View File

@@ -1,5 +1,5 @@
import { DotsHorizontalIcon } from '@radix-ui/react-icons'
import { Row } from '@tanstack/react-table'
import { type Row } from '@tanstack/react-table'
import { Trash2, UserPen } from 'lucide-react'
import { Button } from '@/components/ui/button'
import {
@@ -11,7 +11,7 @@ import {
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { useUsers } from '../context/users-context'
import { User } from '../data/schema'
import { type User } from '../data/schema'
interface DataTableRowActionsProps {
row: Row<User>

View File

@@ -1,5 +1,5 @@
import { Cross2Icon } from '@radix-ui/react-icons'
import { Table } from '@tanstack/react-table'
import { type Table } from '@tanstack/react-table'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { roles } from '../data/data'

View File

@@ -1,6 +1,6 @@
import { DropdownMenuTrigger } from '@radix-ui/react-dropdown-menu'
import { MixerHorizontalIcon } from '@radix-ui/react-icons'
import { Table } from '@tanstack/react-table'
import { type Table } from '@tanstack/react-table'
import { Button } from '@/components/ui/button'
import {
DropdownMenu,

View File

@@ -25,7 +25,7 @@ import { Input } from '@/components/ui/input'
import { PasswordInput } from '@/components/password-input'
import { SelectDropdown } from '@/components/select-dropdown'
import { roles } from '../data/data'
import { User } from '../data/schema'
import { type User } from '../data/schema'
const formSchema = z
.object({

View File

@@ -1,10 +1,10 @@
import { ColumnDef } from '@tanstack/react-table'
import { type ColumnDef } from '@tanstack/react-table'
import { cn } from '@/lib/utils'
import { Badge } from '@/components/ui/badge'
import { Checkbox } from '@/components/ui/checkbox'
import LongText from '@/components/long-text'
import { LongText } from '@/components/long-text'
import { callTypes, roles } from '../data/data'
import { User } from '../data/schema'
import { type User } from '../data/schema'
import { DataTableColumnHeader } from './data-table-column-header'
import { DataTableRowActions } from './data-table-row-actions'

View File

@@ -7,7 +7,7 @@ import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { ConfirmDialog } from '@/components/confirm-dialog'
import { User } from '../data/schema'
import { type User } from '../data/schema'
interface Props {
open: boolean

View File

@@ -1,7 +1,7 @@
'use client'
import { useState } from 'react'
import { Table } from '@tanstack/react-table'
import { type Table } from '@tanstack/react-table'
import { AlertTriangle } from 'lucide-react'
import { toast } from 'sonner'
import { sleep } from '@/utils/sleep'

View File

@@ -1,10 +1,10 @@
import { useState } from 'react'
import {
ColumnDef,
ColumnFiltersState,
RowData,
SortingState,
VisibilityState,
type ColumnDef,
type ColumnFiltersState,
type RowData,
type SortingState,
type VisibilityState,
flexRender,
getCoreRowModel,
getFacetedRowModel,
@@ -23,7 +23,7 @@ import {
TableHeader,
TableRow,
} from '@/components/ui/table'
import { User } from '../data/schema'
import { type User } from '../data/schema'
import { DataTableBulkActions } from './data-table-bulk-actions'
import { DataTablePagination } from './data-table-pagination'
import { DataTableToolbar } from './data-table-toolbar'

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react'
import useDialogState from '@/hooks/use-dialog-state'
import { User } from '../data/schema'
import { type User } from '../data/schema'
type UsersDialogType = 'invite' | 'add' | 'edit' | 'delete'
@@ -13,11 +13,7 @@ interface UsersContextType {
const UsersContext = React.createContext<UsersContextType | null>(null)
interface Props {
children: React.ReactNode
}
export default function UsersProvider({ children }: Props) {
export function UsersProvider({ children }: { children: React.ReactNode }) {
const [open, setOpen] = useDialogState<UsersDialogType>(null)
const [currentRow, setCurrentRow] = useState<User | null>(null)

View File

@@ -1,5 +1,5 @@
import { Shield, UserCheck, Users, CreditCard } from 'lucide-react'
import { UserStatus } from './schema'
import { type UserStatus } from './schema'
export const callTypes = new Map<UserStatus, string>([
['active', 'bg-teal-100/30 text-teal-900 dark:text-teal-200 border-teal-200'],

View File

@@ -7,11 +7,11 @@ import { columns } from './components/users-columns'
import { UsersDialogs } from './components/users-dialogs'
import { UsersPrimaryButtons } from './components/users-primary-buttons'
import { UsersTable } from './components/users-table'
import UsersProvider from './context/users-context'
import { UsersProvider } from './context/users-context'
import { userListSchema } from './data/schema'
import { users } from './data/users'
export default function Users() {
export function Users() {
// Parse user list
const userList = userListSchema.parse(users)

Some files were not shown because too many files have changed in this diff Show More