Skip to content

Conversation

@tran-christian
Copy link
Contributor

@tran-christian tran-christian commented Jan 8, 2026

Migrate from Pages to App Router, migrate from Material UI to Mantine, Upgrade NextJS, and Storybook, other chores.

@tran-christian tran-christian requested a review from awpala January 8, 2026 10:59
@vercel
Copy link

vercel bot commented Jan 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
website Ready Ready Preview, Comment Jan 10, 2026 5:07am

@@ -0,0 +1,9 @@
export default function AboutPage() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine consolidating this page and trimming some of the old content, but I think it should still include the Discord link from before.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request implements a major migration from Next.js Pages Router to App Router, along with significant version upgrades to Next.js (to 16.1.0), Material UI (to v7), Storybook (to v10), React (to v19), and switches the package manager from Yarn to pnpm.

Key changes:

  • Migration from Pages Router architecture to App Router with new app/ directory structure
  • Upgraded Next.js, React, Material UI, and Storybook to latest/future versions
  • Replaced router hooks (useRouter from next/router → next/navigation)
  • Updated Material UI Grid components to use new size prop API
  • Added hydration mismatch fixes with mounted state checks

Reviewed changes

Copilot reviewed 56 out of 62 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
tsconfig.json Updated compiler options for App Router (moduleResolution: bundler, jsx config, Next.js plugin)
package.json Major version upgrades for Next.js (16.1.0), React (19.1.0), MUI (7.x), Storybook (10.x), switched to pnpm
eslint.config.mjs New ESLint flat config replacing .eslintrc.json
next.config.js Removed Emotion styledComponents compiler option, updated transpilePackages
app/layout.tsx New App Router root layout with theme providers and metadata
app/providers.tsx Client component wrapping contexts and theme registry
app/theme/ThemeRegistry.tsx New theme setup for App Router using MUI v7 CSS variables
app/page.tsx Server component for home page data fetching
app/course/[courseid]/page.tsx Server component for course page with async data fetching
app/about/page.tsx Client component for about page (migrated from pages/about.tsx)
src/components/NavBar.tsx Added 'use client', hydration fix for theme toggle with mounted state
src/components/ReviewCard.tsx UTC date formatting for hydration, improved clipboard error handling
src/components/ReviewForm.tsx Replaced router.reload() with window.location.reload()
src/components/ClassCard.tsx Updated router import from next/router to next/navigation
src/Link.tsx Updated to use usePathname from next/navigation
src/stories/*.stories.ts Updated Storybook imports and added fn() mocks
.github/workflows/*.yml Updated to use pnpm instead of yarn, updated action versions
.storybook/main.ts Migrated to nextjs-vite framework for Storybook v10
Comments suppressed due to low confidence (2)

app/course/[courseid]/CourseContent.tsx:263

  • There's a spacing issue in the sx prop. The value should be '5px 30px' (with space) not '5 30' (which is invalid CSS).
    app/course/[courseid]/CourseContent.tsx:308
  • Missing space after colon in the 'height' property across multiple Card components. Should be 'height: "100%"' with proper spacing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -1,4 +1,5 @@
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from 'storybook/test';
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import path 'storybook/test' is incorrect. It should be '@storybook/test' (with the @ prefix). This will cause a module resolution error.

Copilot uses AI. Check for mistakes.
>
{isLegacy && (
<Grid item>
<Grid size="auto">
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Grid component is using size="auto" which may not be correct for Material UI v7. In Material UI v7, the Grid v2 component uses size prop with numeric values or responsive objects. For auto-sizing, you should use size="grow" or omit the size prop entirely.

Copilot uses AI. Check for mistakes.
@@ -1,5 +1,5 @@
import type { Meta, StoryObj } from '@storybook/react';
import { within, userEvent } from '@storybook/test';
import { within, userEvent } from 'storybook/test';
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import path 'storybook/test' is incorrect. It should be '@storybook/test' (with the @ prefix). This will cause a module resolution error.

Copilot uses AI. Check for mistakes.
return field.onChange(double);
}
return;
return field.onChange(null);
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning an empty value from onChange is problematic. When the field value should be cleared (when double is falsy), you should explicitly set it to an empty string ('') or null to properly clear the field, otherwise the field might retain stale values.

Copilot uses AI. Check for mistakes.
Comment on lines +51 to +52
"react": "^19.1.0",
"react-dom": "^19.1.0",
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React has been upgraded to ^19.1.0. As of January 2025, React 19 is in RC (release candidate) status and may not be stable for production use. Please verify this is intentional and that all dependencies are compatible with React 19.

Copilot uses AI. Check for mistakes.
@@ -1,4 +1,4 @@
import { Meta } from '@storybook/blocks';
import { Meta } from '@storybook/addon-docs/blocks';
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The import path '@storybook/addon-docs/blocks' may be incorrect for Storybook v10. In Storybook v10, the import should typically be from '@storybook/blocks'. Please verify this import path is correct for the version being used.

Copilot uses AI. Check for mistakes.
)
) : (
<Brightness4Icon />
<Brightness4Icon/>
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The closing tag has an extra space before the slash. It should be <Brightness4Icon /> not <Brightness4Icon/> (though both work, the spacing is inconsistent with the rest of the codebase).

Copilot uses AI. Check for mistakes.
Comment on lines +35 to +38
"@mui/icons-material": "^7.1.0",
"@mui/material": "^7.1.0",
"@mui/system": "^7.1.0",
"@mui/x-data-grid": "^8.5.0",
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Material UI icons and material packages have inconsistent versions. @mui/icons-material is at ^7.1.0 while @mui/material and @mui/system are also at ^7.1.0, but @mui/x-data-grid is at ^8.5.0. The data grid version should be compatible with the Material UI version being used. Please verify version compatibility between these packages.

Copilot uses AI. Check for mistakes.
Terms of Use & Privacy
</Typography>
<Typography variant="body1" paragraph marginTop={1} align="center">
We are currently in the process of esablishing a non-profit organization
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a typo in "esablishing" which should be "establishing".

Suggested change
We are currently in the process of esablishing a non-profit organization
We are currently in the process of establishing a non-profit organization

Copilot uses AI. Check for mistakes.
Comment on lines 42 to 53
{reviewsRecent && (
<Grid container rowSpacing={5} sx={{ mt: 1 }}>
{reviewsRecent
.sort((a, b) => b.created - a.created)
.slice(0, REVIEWS_RECENT_LEN)
.map((value: Review) => (
<Grid sx={{ width: '100%' }} key={value.reviewId} size={12}>
<ReviewCard {...value}></ReviewCard>
</Grid>
))}
</Grid>
)}
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This use of variable 'reviewsRecent' always evaluates to true.

Suggested change
{reviewsRecent && (
<Grid container rowSpacing={5} sx={{ mt: 1 }}>
{reviewsRecent
.sort((a, b) => b.created - a.created)
.slice(0, REVIEWS_RECENT_LEN)
.map((value: Review) => (
<Grid sx={{ width: '100%' }} key={value.reviewId} size={12}>
<ReviewCard {...value}></ReviewCard>
</Grid>
))}
</Grid>
)}
<Grid container rowSpacing={5} sx={{ mt: 1 }}>
{reviewsRecent
.sort((a, b) => b.created - a.created)
.slice(0, REVIEWS_RECENT_LEN)
.map((value: Review) => (
<Grid sx={{ width: '100%' }} key={value.reviewId} size={12}>
<ReviewCard {...value}></ReviewCard>
</Grid>
))}
</Grid>

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 55 out of 61 changed files in this pull request and generated 15 comments.

Comments suppressed due to low confidence (3)

app/user/reviews/page.tsx:83

  • The Grid component at line 83 uses size="grow" which is not a valid value for the size prop in Material-UI Grid v2. Valid values are numbers 1-12, 'auto', or responsive objects. Consider using size={12} or Grid2 with flexGrow styling instead.
    app/course/[courseid]/CourseContent.tsx:308
  • The Card components have inconsistent padding values. Line 263 uses padding: '5px 30px' while lines 280 and 308 use the same. However, these string values should be consistent. The CSS shorthand is correct but ensure this is the intended design.
    app/HomeContent.tsx:143
  • The DataGrid toolbar slot is set to undefined when not on desktop, but this may cause issues if the DataGrid expects either a component or null. Consider using null instead of undefined for better type safety and predictability.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

<>
<Grid container spacing={2}>
<Grid item xs={4}>
<Grid size={4}>
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Grid component is using size={4} which is the Grid2 API, but it's imported from '@mui/material' as the legacy Grid component. With Material-UI v7, you should either import Grid2 from '@mui/material/Grid2' or use the legacy Grid API with item and xs={4} props. The current usage will not render correctly.

Copilot uses AI. Check for mistakes.
Comment on lines 46 to 48
run: npx eslint .
--config .eslintrc.json
--ext .js,.jsx,.ts,.tsx
--format @microsoft/eslint-formatter-sarif
--output-file eslint-results.sarif
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ESLint workflow is missing line breaks in the run command. Lines 46-48 should have proper line continuation characters or be formatted as a multi-line command. The current format will cause the command to fail.

Copilot uses AI. Check for mistakes.
Comment on lines +107 to +115
"pnpm": {
"overrides": {
"react": "^19.1.0",
"react-dom": "^19.1.0",
"@types/react": "^19.1.0",
"@types/react-dom": "^19.1.0",
"dompurify": "^3.2.4",
"tmp": "^0.2.4"
}
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React 19 is specified in pnpm overrides, but React 19 is a major version with breaking changes. Ensure all dependencies (especially @mui/material, @storybook/react, @testing-library/react) are fully compatible with React 19 to avoid runtime errors. Consider testing thoroughly or using React 18 until ecosystem compatibility is verified.

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +40
const isDesktopQuery = useMediaQuery('(min-width:1025px)', { noSsr: true });
const isDesktop = mounted ? isDesktopQuery : true;
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The useMediaQuery hook with noSsr: true and the mounted state pattern is good for preventing hydration mismatches. However, defaulting to isDesktop = true before mounting means the drawer width will always start as desktop on the server. Consider if this matches your actual layout to prevent layout shifts.

Copilot uses AI. Check for mistakes.
Comment on lines +68 to +70
// Use UTC date formatting to avoid hydration mismatch between server and client timezones
const createdDate = new Date(created);
const timestamp = `${createdDate.getUTCMonth() + 1}/${createdDate.getUTCDate()}/${createdDate.getUTCFullYear()}`;
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The UTC date formatting is implemented to avoid hydration mismatches, which is good. However, this means all dates will display in UTC regardless of the user's timezone. Consider adding a note in the UI or using a client-side effect to show local time after hydration if user timezone is important for the UX.

Copilot uses AI. Check for mistakes.
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
</head>
<body suppressHydrationWarning>
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'suppressHydrationWarning' prop on the body element is too broad. This will suppress all hydration warnings for the entire body, potentially hiding real hydration issues. Consider using it more selectively or fixing the actual hydration mismatches instead.

Suggested change
<body suppressHydrationWarning>
<body>

Copilot uses AI. Check for mistakes.

module.exports = {
'*.{ts,tsx}': [buildEslintCommand],
'*.{ts,tsx}': 'eslint --fix --no-warn-ignored',
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The eslint command uses --no-warn-ignored flag which may not be compatible with all ESLint versions. Verify this flag is supported by your ESLint version (9.18.0) to avoid build failures during pre-commit hooks.

Suggested change
'*.{ts,tsx}': 'eslint --fix --no-warn-ignored',
'*.{ts,tsx}': 'eslint --fix',

Copilot uses AI. Check for mistakes.
run: pnpm install
- name: Publish to Chromatic
uses: chromaui/action@v13
uses: chromaui/action@07791f8243f4cb2698bf4d00426baf4b2d1cb7e0 # v13.3.5
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The chromatic action is pinned to a specific commit SHA (07791f8243f4cb2698bf4d00426baf4b2d1cb7e0) which is good for security, but the comment claims it's v13.3.5. Verify this SHA actually corresponds to v13.3.5 to ensure the intended version is being used.

Suggested change
uses: chromaui/action@07791f8243f4cb2698bf4d00426baf4b2d1cb7e0 # v13.3.5
uses: chromaui/action@07791f8243f4cb2698bf4d00426baf4b2d1cb7e0 # pinned Chromatic action commit

Copilot uses AI. Check for mistakes.
Comment on lines +54 to +55
// Disable Pages Router rule - this is an App Router project
'@next/next/no-page-custom-font': 'off',
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ESLint configuration disables '@next/next/no-page-custom-font' rule with a comment stating "this is an App Router project". However, this rule is still relevant for App Router projects as it warns about custom fonts in layout files. Only disable it if you're intentionally using custom fonts in a way that violates the rule.

Copilot uses AI. Check for mistakes.
Comment on lines 5 to 10
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-a11y',
'@chromatic-com/storybook',
'@storybook/addon-docs'
],
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Storybook configuration is migrating to Vite (@storybook/nextjs-vite), but the removal of '@storybook/addon-essentials' and '@storybook/addon-interactions' may break existing stories that depend on these addons. Verify that '@storybook/addon-docs' provides all necessary functionality or add back required addons.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 63 out of 69 changed files in this pull request and generated 17 comments.

Comments suppressed due to low confidence (2)

app/user/reviews/page.tsx:83

  • The 'size="grow"' value is not a valid Grid2 size prop. The size prop should be a number (1-12), an object with breakpoint keys, or boolean. If you want the Grid item to grow and fill available space, consider using 'size={12}' or removing the size prop and using flex properties in sx prop.
    app/course/[courseid]/CourseContent.tsx:263
  • The padding value has been changed from '5 30' to '5px 30px'. The original value '5 30' was invalid CSS and would have been ignored. Ensure this padding change produces the desired visual result, as it now applies 5px top/bottom and 30px left/right padding where previously it may have had no padding due to the invalid syntax.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


handleReviewModalClose();
router.reload();
window.location.reload();
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using 'window.location.reload()' instead of 'router.reload()' will cause a full page reload, losing any client-side state and potentially impacting user experience. Consider using the App Router's 'router.refresh()' method instead, which performs a soft navigation and preserves client-side state while refreshing server data.

Copilot uses AI. Check for mistakes.
Comment on lines 57 to 59
open={loginOpen}
onClose={handleLoginClose}
anchor={'right'}
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The deprecated 'ModalProps' prop has been removed, which is correct for the newer version of MUI. However, ensure that the backdrop click behavior is still working as expected with the default settings or add the 'onClose' handler to handle backdrop clicks if needed.

Copilot uses AI. Check for mistakes.
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
</head>
<body suppressHydrationWarning>
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'suppressHydrationWarning' prop is added to both html and body tags. While this is sometimes necessary for theme-related hydration mismatches, it suppresses ALL hydration warnings. Ensure you're not masking legitimate hydration issues. Consider using more targeted solutions for specific hydration problems, such as the mounted state pattern used in NavBar and other components.

Suggested change
<body suppressHydrationWarning>
<body>

Copilot uses AI. Check for mistakes.
Terms of Use & Privacy
</Typography>
<Typography variant="body1" paragraph marginTop={1} align="center">
We are currently in the process of establishing a non-profit organization
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spelling error: change "esablishing" to "establishing".

Copilot uses AI. Check for mistakes.
title: 'Knowledge Based AI',
acronym: 'KBAI',
classId: 'CS 7637',
classId: 'CS-7637',
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The classId format has changed from 'CS 7637' to 'CS-7637' (space to hyphen). Ensure this format change is consistent throughout the application and that any existing data or links using the old format are properly migrated or handled. This could be a breaking change for URLs, database queries, or external integrations.

Copilot uses AI. Check for mistakes.
>
{isLegacy && (
<Grid item>
<Grid size="auto">
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Grid component's 'item' and 'xs' props have been replaced with 'size', but line 207 uses 'size="auto"' as a string instead of an object or number. According to Material-UI v7 Grid2 API, the size prop should be a number (1-12), an object like {xs: 12}, or boolean true/false for auto sizing. Change this to 'size={{xs: "auto"}}' or simply remove the size prop if you want auto-sizing behavior.

Copilot uses AI. Check for mistakes.
></Chip>
</Grid>
<Grid item>
<Grid size="auto">
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar issue: 'size="auto"' should be changed to a valid Grid2 size prop format. Use 'size={{xs: "auto"}}' or remove the size prop for auto-sizing.

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +44
const isDesktopQuery = useMediaQuery('(min-width:1025px)', { noSsr: true });
const isDesktop = mounted ? isDesktopQuery : true;

useEffect(() => {
setMounted(true);
}, []);
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change from 'useMediaQuery' without options to 'useMediaQuery(..., { noSsr: true })' is important for preventing hydration mismatches. However, you've also added a mounted state pattern. Using both together is redundant. The noSsr option tells MUI to skip server-side rendering of the media query, while the mounted pattern achieves the same thing. Consider using only one approach for consistency across the codebase.

Copilot uses AI. Check for mistakes.
Comment on lines +35 to +38
"@mui/icons-material": "^7.1.0",
"@mui/material": "^7.1.0",
"@mui/system": "^7.1.0",
"@mui/x-data-grid": "^8.5.0",
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The package.json shows Material-UI has been upgraded from v5 to v7, and MUI X DataGrid from v7 to v8. These are major version upgrades with breaking changes. Ensure all Grid components have been updated to use the new Grid2 API (which you've done), but verify that all DataGrid features used in the application are still compatible with v8. Additionally, the removal of '@emotion/server' dependency could affect SSR styling if not properly replaced by the new EmotionCache implementation.

Copilot uses AI. Check for mistakes.
Comment on lines +64 to +101
"@chromatic-com/storybook": "^4.1.3",
"@commitlint/cli": "^19.4.1",
"@commitlint/config-conventional": "^19.6.0",
"@next/bundle-analyzer": "^15.3.1",
"@storybook/addon-actions": "^8.2.9",
"@storybook/addon-essentials": "^8.2.9",
"@storybook/addon-interactions": "^8.2.9",
"@storybook/addon-links": "^8.2.9",
"@storybook/blocks": "^8.2.9",
"@storybook/nextjs": "^8.2.9",
"@storybook/react": "^8.2.9",
"@storybook/test": "^8.2.9",
"@eslint/eslintrc": "^3.2.0",
"@next/bundle-analyzer": "^16.1.0",
"@next/eslint-plugin-next": "^16.1.0",
"@storybook/addon-a11y": "^10.1.11",
"@storybook/addon-docs": "10.1.11",
"@storybook/addon-links": "10.1.11",
"@storybook/addon-vitest": "^10.1.11",
"@storybook/nextjs-vite": "10.1.11",
"@storybook/react": "^10.1.11",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^15.0.7",
"@testing-library/react": "^16.3.0",
"@types/node": "^22.15.2",
"@types/react": "^18.3.4",
"babel-loader": "^10.0.0",
"babel-plugin-import": "^1.13.8",
"@types/prismjs": "^1.26.5",
"@types/react": "^19.1.0",
"@types/react-dom": "^19.1.0",
"@vitest/browser": "^4.0.16",
"commitizen": "^4.3.0",
"cross-env": "^7.0.3",
"cz-conventional-changelog": "3.3.0",
"eslint": "8.57.0",
"eslint-config-next": "^14.2.7",
"eslint": "^9.18.0",
"eslint-config-prettier": "^10.1.2",
"eslint-plugin-storybook": "^0.8.0",
"husky": "^9.1.5",
"eslint-plugin-react": "^7.37.0",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-storybook": "10.1.11",
"globals": "^16.2.0",
"husky": "^9.1.7",
"jest": "^29.4.3",
"jest-environment-jsdom": "^29.3.1",
"jest-fetch-mock": "^3.0.3",
"lint-staged": "^15.2.9",
"next-sitemap": "^4.1.8",
"playwright": "^1.57.0",
"prettier": "^3.0.3",
"storybook": "^8.2.9",
"typescript": "^5.7.2"
"storybook": "10.1.11",
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Storybook has been upgraded from v8.2.9 to v10.1.11, skipping v9 entirely. This is a major upgrade with significant breaking changes. The migration from '@storybook/nextjs' to '@storybook/nextjs-vite' changes the underlying build system from Webpack to Vite. Ensure all stories load correctly and that any custom Storybook configurations are compatible with the new version.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 63 out of 69 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 66 to 67
const authContext: TNullable<any> = useAuth();
const user: TNullable<FirebaseAuthUser> = authContext.user;
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The authContext can be null when the component is used outside of the AuthContextProvider. Accessing authContext.user directly without null-checking will cause a runtime error. Use optional chaining: authContext?.user instead.

Copilot uses AI. Check for mistakes.
Comment on lines 33 to +35
const authContext: TNullable<any> = useAuth();
const user: TNullable<FirebaseAuthUser> = authContext.user;
const loading: TNullable<Boolean> = authContext.loading;
const loading: TNullable<boolean> = authContext.loading;
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The authContext can be null when the component is used outside of the AuthContextProvider. Accessing authContext.user and authContext.loading directly without null-checking will cause a runtime error. Use optional chaining: authContext?.user and authContext?.loading instead.

Copilot uses AI. Check for mistakes.
nextjs: {
appDirectory: true,
navigation: {
pathname: '/class',
Copy link

Copilot AI Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The navigation pathname is set to '/class' but the actual route is '/course/[courseid]'. Update this to '/course' to match the actual route structure.

Copilot uses AI. Check for mistakes.
@tran-christian tran-christian changed the title Migrate from Pages to App Router, Upgrade NextJS, Material UI, and Storybook, other chores. Website overhaul Jan 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants