Files
slash-e/frontend/web/src/layouts/Root.tsx
T
c38b58618c refactor: shadcn UI (#496)
* feat: add shadcn/ui base dependencies

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: configure shadcn/ui setup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add cn utility for class merging

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: configure tailwind with shadcn theme and CSS variables

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add shadcn button component

* feat: add shadcn input component

* feat: add shadcn label component

* feat: add shadcn card component

* feat: add shadcn badge component

* feat: add shadcn separator component

* chore: update dependencies for separator component

* feat: add shadcn dialog component

* feat: add shadcn sheet component (drawer replacement)

* feat: add shadcn dropdown-menu component

* feat: add shadcn tooltip component

* feat: add shadcn checkbox component

* feat: add shadcn textarea component

* feat: add shadcn avatar component

* feat: add shadcn sonner component (toast replacement)

* refactor: migrate Dropdown to shadcn dropdown-menu

* refactor: migrate Alert to shadcn alert-dialog

* refactor: migrate ShortcutCard to shadcn components

* refactor: migrate CreateShortcutDrawer to shadcn sheet

* fix: correct import path in alert-dialog

* feat: add framer-motion for animations

* feat: add animated card with framer motion

* feat: improve typography with consistent styles

* chore: migrate MUI Joy components to shadcn/ui (partial)

- Migrated core app components (main.tsx, App.tsx, Root.tsx)
- Replaced CssVarsProvider with next-themes ThemeProvider
- Replaced useColorScheme with useTheme from next-themes
- Migrated all page components using Button, Input, Divider, Tooltip, Separator
- Migrated component files using simple components
- Migrated setting sections with Select, Switch, Textarea
- Added shadcn/ui components: alert, switch, select, radio-group
- Build tested and passing

Remaining: Dialog/Modal, Drawer/Sheet, RadioGroup components in 10 files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* refactor: complete Task 26 - migrate remaining components from MUI Joy to shadcn/ui

Migrated 11 remaining files using MUI Joy components to shadcn/ui:

Dialog migrations (6 files):
- AboutDialog.tsx: Modal/ModalDialog → Dialog
- ChangePasswordDialog.tsx: Modal/ModalDialog → Dialog
- CreateAccessTokenDialog.tsx: Modal/ModalDialog → Dialog with RadioGroup
- CreateUserDialog.tsx: Modal/ModalDialog → Dialog with RadioGroup
- EditUserinfoDialog.tsx: Modal/ModalDialog → Dialog
- GenerateQRCodeDialog.tsx: Modal/ModalDialog → Dialog

Drawer migrations (2 files):
- CreateCollectionDrawer.tsx: Drawer → Sheet
- CreateIdentityProviderDrawer.tsx: Drawer → Sheet

Page migrations (2 files):
- SubscriptionSetting.tsx: Alert, Button, Divider, Link, Textarea → shadcn equivalents
- WorkspaceSetting.tsx: Alert, Button, Divider → shadcn equivalents

Component migrations (1 file):
- SubscriptionFAQ.tsx: Accordion/AccordionGroup → shadcn Accordion

All components now use shadcn/ui. No MUI Joy imports remain.
Build verified successfully.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore: remove MUI Joy and react-hot-toast dependencies

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* docs: add UI components guide

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: complete migration from MUI Joy to shadcn/ui

- Migrated all UI components to shadcn/ui
- Implemented clean & minimal design aesthetic
- Added Framer Motion for subtle animations
- Improved typography and spacing consistency
- Enhanced dark mode with proper color palette
- Replaced react-hot-toast with sonner
- Removed MUI Joy dependencies
- Updated all forms, modals, and interactive components
- Added component documentation

This migration improves maintainability, reduces bundle size, and provides a more modern, polished UI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* chore: update

* chore: update

* chore: update

* refactor: complete shadcn/ui theme migration with semantic tokens

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: Johnny <yourselfhosted@gmail.com>
2025-12-18 18:06:00 +08:00

59 lines
1.5 KiB
TypeScript

import { useTheme } from "next-themes";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { Outlet } from "react-router-dom";
import Header from "@/components/Header";
import Navigator from "@/components/Navigator";
import useNavigateTo from "@/hooks/useNavigateTo";
import { useUserStore } from "@/stores";
const Root: React.FC = () => {
const navigateTo = useNavigateTo();
const { setTheme } = useTheme();
const { i18n } = useTranslation();
const userStore = useUserStore();
const currentUser = userStore.getCurrentUser();
const currentUserSetting = userStore.getCurrentUserSetting();
const isInitialized = Boolean(currentUser) && Boolean(currentUserSetting);
useEffect(() => {
if (!currentUser) {
navigateTo("/auth", {
replace: true,
});
return;
}
// Prepare user setting.
userStore.fetchUserSetting(currentUser.id);
}, []);
useEffect(() => {
if (!currentUserSetting) {
return;
}
i18n.changeLanguage(currentUserSetting.general?.locale || "en");
if (currentUserSetting.general?.colorTheme === "LIGHT") {
setTheme("light");
} else if (currentUserSetting.general?.colorTheme === "DARK") {
setTheme("dark");
} else {
setTheme("system");
}
}, [currentUserSetting]);
return (
isInitialized && (
<div className="w-full h-auto flex flex-col justify-start items-start bg-background">
<Header />
<Navigator />
<Outlet />
</div>
)
);
};
export default Root;