Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions packages/client/src/app/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,24 @@
const isProduction = process.env.NODE_ENV === 'production';
const isDevServer = import.meta.env.VITE_DEV_SERVER === 'true';

if (isProduction && !isDevServer) {
Clarity.init(import.meta.env.VITE_CLARITY_PROJECT_ID);
function initAnalytics() {
if (isProduction && !isDevServer) {
Clarity.init(import.meta.env.VITE_CLARITY_PROJECT_ID);

// Todo: Sentry tree shaking
Sentry.initialize();
ReactGA.initialize(import.meta.env.VITE_GOOGLE_ANALYTICS_ID);
// Todo: Sentry tree shaking
Sentry.initialize();
ReactGA.initialize(import.meta.env.VITE_GOOGLE_ANALYTICS_ID);
}
}

if ('requestIdleCallback' in window) {

Check warning on line 27 in packages/client/src/app/main.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `globalThis` over `window`.

See more on https://sonarcloud.io/project/issues?id=allcll_allcll-frontend&issues=AZz55A8lOBw0NpRv9VDu&open=AZz55A8lOBw0NpRv9VDu&pullRequest=339
requestIdleCallback(initAnalytics);
} else {
setTimeout(initAnalytics, 200);
}

if (!isProduction || !isDevServer) {
// @ts-ignore
// @ts-expect-error -- window is extended at runtime for dev tooling
window.__TANSTACK_QUERY_CLIENT__ = queryClient;
}

Expand Down
272 changes: 145 additions & 127 deletions packages/client/src/app/routing.tsx
Original file line number Diff line number Diff line change
@@ -1,137 +1,155 @@
import { lazy, Suspense } from 'react';
import { createBrowserRouter } from 'react-router-dom';
import MainLayout from '@/app/layouts/MainLayout.tsx';
import ServiceLayout from '@/app/layouts/ServiceLayout.tsx';
import SimulationLayout from '@/app/layouts/SimulationLayout.tsx';
import Landing from '@/pages/home/Landing.tsx';
import Live from '@/pages/live/Live.tsx';
import ServiceInfo from '@/pages/serviceInfo/ServiceInfo.tsx';
import CustomerService from '@/pages/customerService/CustomerService.tsx';
import FAQ from '@/pages/faq/FAQ';
import WishTable from '@/pages/wishlist/WishTable.tsx';
import WishesDetail from '@/pages/wishlist/WishesDetail.tsx';
const SimulationLayout = lazy(() => import('@/app/layouts/SimulationLayout.tsx'));
import ErrorPage from '@/pages/ErrorPage.tsx';
import ErrorPageWith404 from '@/pages/ErrorPageWith404.tsx';
import Simulation from '@/pages/simulation/Simulation.tsx';
import SimulationDashboard from '@/pages/simulation/Dashboard.tsx';
import SimulationDashboardDetail from '@/pages/simulation/DashboardDetail.tsx';
import Timetable from '@/pages/timetable/Timetable.tsx';
import GraduationSettingSteps from '@/pages/graduation/SettingSteps.tsx';
import GraduationDashboard from '@/pages/graduation/Dashboard.tsx';
import NotFound from '@/pages/notfound/NotFound';
import PrivacyPolicy from '@/pages/user/PrivacyPolicy';
import PageLoader from '@/shared/ui/PageLoader.tsx';

const router = createBrowserRouter([
{
path: '/',
element: <MainLayout />,
errorElement: <ErrorPage />,
children: [
{
path: '/',
element: <Landing />,
},
{
path: 'survey',
element: <CustomerService />,
},
{
path: 'about',
element: <ServiceInfo />,
},
{
path: 'faq',
element: <FAQ />,
},
],
},
{
path: 'wishes',
element: <ServiceLayout serviceId="baskets" />,
errorElement: <ErrorPageWith404 />,
children: [
{
path: '',
element: <WishTable />,
},
{
path: ':id',
element: <WishesDetail />,
},
],
},
{
path: 'live',
element: <ServiceLayout serviceId="live" />,
errorElement: <ErrorPage />,
children: [
{
path: '',
element: <Live />,
},
],
},
const Landing = lazy(() => import('@/pages/home/Landing.tsx'));
const Live = lazy(() => import('@/pages/live/Live.tsx'));
const ServiceInfo = lazy(() => import('@/pages/serviceInfo/ServiceInfo.tsx'));
const CustomerService = lazy(() => import('@/pages/customerService/CustomerService.tsx'));
const FAQ = lazy(() => import('@/pages/faq/FAQ'));
const WishTable = lazy(() => import('@/pages/wishlist/WishTable.tsx'));
const WishesDetail = lazy(() => import('@/pages/wishlist/WishesDetail.tsx'));
const Simulation = lazy(() => import('@/pages/simulation/Simulation.tsx'));
const SimulationDashboard = lazy(() => import('@/pages/simulation/Dashboard.tsx'));
const SimulationDashboardDetail = lazy(() => import('@/pages/simulation/DashboardDetail.tsx'));
const Timetable = lazy(() => import('@/pages/timetable/Timetable.tsx'));
const GraduationSettingSteps = lazy(() => import('@/pages/graduation/SettingSteps.tsx'));
const GraduationDashboard = lazy(() => import('@/pages/graduation/Dashboard.tsx'));
const NotFound = lazy(() => import('@/pages/notfound/NotFound'));
const PrivacyPolicy = lazy(() => import('@/pages/user/PrivacyPolicy'));

{
path: 'simulation',
element: <SimulationLayout />,
errorElement: <ErrorPage />,
children: [
{
path: '',
element: <Simulation />,
},
{
path: 'logs',
element: <SimulationDashboard />,
},
{
path: 'logs/:runId',
element: <SimulationDashboardDetail />,
},
],
},
{
path: 'timetable',
element: <MainLayout />,
errorElement: <ErrorPage />,
children: [
{
index: true,
element: <Timetable />,
},
],
},
{
path: 'graduation',
element: <ServiceLayout serviceId="graduation" />,
errorElement: <ErrorPage />,
children: [
{
path: '',
element: <GraduationSettingSteps />,
},
{
path: 'result',
element: <GraduationDashboard />,
},
],
},
{
path: 'privacy-policy',
element: <MainLayout />,
children: [
{
index: true,
element: <PrivacyPolicy />,
},
],
errorElement: <ErrorPage />,
},
function page(Component: React.ComponentType) {
return (
<Suspense fallback={<PageLoader />}>
<Component />
</Suspense>
);
}

{
path: '*',
element: <NotFound />,
},
], { basename: import.meta.env.BASE_URL });
const router = createBrowserRouter(
[
{
path: '/',
element: <MainLayout />,
errorElement: <ErrorPage />,
children: [
{
path: '/',
element: page(Landing),
},
{
path: 'survey',
element: page(CustomerService),
},
{
path: 'about',
element: page(ServiceInfo),
},
{
path: 'faq',
element: page(FAQ),
},
],
},
{
path: 'wishes',
element: <ServiceLayout serviceId="baskets" />,
errorElement: <ErrorPageWith404 />,
children: [
{
path: '',
element: page(WishTable),
},
{
path: ':id',
element: page(WishesDetail),
},
],
},
{
path: 'live',
element: <ServiceLayout serviceId="live" />,
errorElement: <ErrorPage />,
children: [
{
path: '',
element: page(Live),
},
],
},

{
path: 'simulation',
element: (
<Suspense fallback={<PageLoader />}>
<SimulationLayout />
</Suspense>
),
errorElement: <ErrorPage />,
children: [
{
path: '',
element: page(Simulation),
},
{
path: 'logs',
element: page(SimulationDashboard),
},
{
path: 'logs/:runId',
element: page(SimulationDashboardDetail),
},
],
},
{
path: 'timetable',
element: <MainLayout />,
errorElement: <ErrorPage />,
children: [
{
index: true,
element: page(Timetable),
},
],
},
{
path: 'graduation',
element: <ServiceLayout serviceId="graduation" />,
errorElement: <ErrorPage />,
children: [
{
path: '',
element: page(GraduationSettingSteps),
},
{
path: 'result',
element: page(GraduationDashboard),
},
],
},
{
path: 'privacy-policy',
element: <MainLayout />,
children: [
{
index: true,
element: page(PrivacyPolicy),
},
],
errorElement: <ErrorPage />,
},

{
path: '*',
element: page(NotFound),
},
],
{ basename: import.meta.env.BASE_URL },
);

export default router;
7 changes: 5 additions & 2 deletions packages/client/src/pages/home/Landing.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { lazy, Suspense } from 'react';
import MainBanner from '@/widgets/home/ui/MainBanner.tsx';
import TimetableSection from '@/widgets/home/ui/TimetableSection.tsx';
import SimulationSection from '@/widgets/home/ui/SimulationSection.tsx';
const SimulationSection = lazy(() => import('@/widgets/home/ui/SimulationSection.tsx'));
import WishesSection from '@/widgets/home/ui/WishesSection.tsx';
import LiveSection from '@/widgets/home/ui/LiveSection.tsx';
import PainPointSection from '@/widgets/home/ui/PainPointSection.tsx';
Expand All @@ -16,7 +17,9 @@ function Landing() {
<JouluphajaSection />
<TimetableSection />
<WishesSection />
<SimulationSection />
<Suspense fallback={null}>
<SimulationSection />
</Suspense>
<LiveSection />

<PainPointSection />
Expand Down
26 changes: 26 additions & 0 deletions packages/client/src/shared/ui/PageLoader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const PageLoader = () => {
return (
<div className="flex items-center justify-center w-full min-h-[50vh]">
<div className="flex flex-col items-center gap-3">
<img
src="/ci.svg"
alt="페이지를 불러오는 중"
style={{
width: 64,
height: 64,
animation: 'spin 1.5s linear infinite',
}}
/>
<style>{`
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
`}</style>
<p className="text-gray-500 text-sm">페이지를 불러오는 중...</p>
</div>
</div>
);
};

export default PageLoader;
2 changes: 1 addition & 1 deletion packages/client/src/widgets/home/ui/MainBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ function MainBanner() {
fetchPriority="high"
alt=""
aria-hidden="true"
className="hidden md:block self-end shrink-0 w-[320px] lg:w-[370px]"
className="hidden md:block absolute bottom-0 right-5 w-[320px] lg:w-[370px]"
/>
</Section>
</div>
Expand Down
Loading
Loading