diff --git a/.gitignore b/.gitignore index 4d29575..4ab93aa 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,6 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + +# Yarn +.yarn/install-state.gz diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz deleted file mode 100644 index 4ce5cd0..0000000 Binary files a/.yarn/install-state.gz and /dev/null differ diff --git a/CLAUDE.md b/CLAUDE.md index f143f72..d5ee053 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -5,6 +5,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Development Commands ### Common Scripts + - `yarn start` or `npm start` - Start the development server using Craco - `yarn build` or `npm run build` - Build the production version - `yarn test` or `npm test` - Run all tests with Jest @@ -20,11 +21,13 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co - `yarn run-pushed-files-tests` or `npm run run-pushed-files-tests` - Run tests for pushed files ### Makefile Commands + - `make coverage` - Run coverage tests and open the report in Chrome - `make branch-clean` - Delete local branches that have been removed from remote - `make commit` - Interactive commit helper that guides you through conventional commits ### Recommended Commit Workflow + 1. Create a feature branch: `git checkout -b amitraikwar/{about-changes}` 2. Stage your changes: `git add ` 3. Create initial commit: `make commit` (opens interactive conventional commit prompt) @@ -33,7 +36,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Architecture ### High-Level Structure + This is a React single-page application styled after Apple's macOS interface, using: + - **React 18** with TypeScript for the UI framework - **Zustand** for state management (centralized store in `/src/store/`) - **React Router DOM v6** for client-side routing @@ -42,6 +47,7 @@ This is a React single-page application styled after Apple's macOS interface, us - **Craco** (Create React App Configuration Override) for extending CRA without ejecting ### Key Directories + - `/src/assets/` - Static assets including icons and macOS-themed elements - `/src/components/` - Reusable UI components (buttons, menus, modals, windows, wallpaper) - `/src/hooks/` - Custom React hooks (e.g., useWindowDimension) @@ -53,12 +59,14 @@ This is a React single-page application styled after Apple's macOS interface, us - `/src/localization/` - Internationalization configuration (i18next) ### State Management + - Uses **Zustand** with Immer middleware for immutable state updates - Centralized store at `/src/store/uiStore/uiStore.ts` - Features are sliced (Modal slice for UI state, DateTime slice for time-related state) - Access store hooks via `uiStore(selector)` pattern throughout components ### Routing Strategy + - Implements **code-splitting** with React.lazy and Suspense for performance - **LazyProvider** wraps route components for fallback handling - Separate routers for: @@ -67,6 +75,7 @@ This is a React single-page application styled after Apple's macOS interface, us - Route components are dynamically imported to reduce initial bundle size ### Component Architecture + - **Atomic design approach** with small, focused components - **MacOS simulation** elements: - Window controls (minimize, maximize, close) @@ -77,19 +86,22 @@ This is a React single-page application styled after Apple's macOS interface, us - **Icon system** in `/src/assets/icons/` with individual TSX files for each icon ### Styling Approach + - **Chakra UI** as the primary styling system - Custom CSS in `/src/index.css` for global styles - Component-specific styling using Chakra's props-based API - Responsive design considerations throughout ### Testing Strategy + - **Jest** with **React Testing Library** for unit and integration tests - **Cypress** for end-to-end testing -- Test files co-located with components (__tests__ directories) +- Test files co-located with components (**tests** directories) - Mocks in `/__mocks__/` for external libraries (zustand mock) - Coverage reporting configured via jest.config.js ### Development Practices + - **ESLint** with React App configuration and Prettier integration - **Husky** pre-commit hooks for linting staged files - **Conventional commits** via make commit command @@ -97,6 +109,7 @@ This is a React single-page application styled after Apple's macOS interface, us - Environment-specific configuration in `.env` files (not committed) ### Internationalization + - Configured with **i18next** and browser language detection - Localization files in `/src/localization/` -- Language switching capability built into the system \ No newline at end of file +- Language switching capability built into the system diff --git a/README.md b/README.md index dce35eb..8b8f54d 100644 --- a/README.md +++ b/README.md @@ -32,22 +32,26 @@ This project is built using modern web development tools and best practices: ## ๐Ÿš€ Getting Started ### Prerequisites + Make sure you have Node.js (v18 or higher) and Yarn installed. ### Installation 1. Clone the repository: + ```bash git clone git@github.com:onemanfighter/ARMacPortfolio.git cd ARMacPortfolio ``` 2. Install dependencies: + ```bash yarn install ``` 3. Start the development server: + ```bash yarn start ``` @@ -57,14 +61,17 @@ Make sure you have Node.js (v18 or higher) and Yarn installed. ## ๐Ÿงช Testing Run unit tests and generate coverage reports: + ```bash yarn test:cov ``` Run Cypress end-to-end tests: + ```bash yarn cy:open ``` ## ๐Ÿ“œ License + This project is licensed under the MIT License. diff --git a/jest.js b/jest.js index fe1101f..ce9bb7e 100644 --- a/jest.js +++ b/jest.js @@ -24,3 +24,6 @@ jest.mock('react-clock', () => { return
; }; }); + +window.HTMLElement.prototype.scrollTo = jest.fn(); +window.Element.prototype.scrollTo = jest.fn(); diff --git a/package.json b/package.json index 962000b..1c6bff2 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,14 @@ { - "name": "ARMacPortfolio", + "name": "MacMock", "version": "0.5.0", - "description": "This is a mac simulator portfolio website for Amit Raikwar", + "description": "Mac OS Simulator", "main": "index.tsx", "dependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@chakra-ui/react": "^2.8.2", "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", - "@types/node": "^16.18.91", - "@types/react": "^18.2.69", - "@types/react-dom": "^18.2.22", + "@types/node": "^18.19.0", "draft-js": "^0.11.7", "framer-motion": "^11.2.6", "fuse.js": "^7.0.0", @@ -30,7 +28,7 @@ "react-resizable": "^3.0.5", "react-router-dom": "^6.23.1", "react-scripts": "5.0.1", - "typescript": "^4.9.5", + "typescript": "^5.4.5", "web-vitals": "^2.1.4", "zustand": "^4.5.2" }, @@ -52,6 +50,10 @@ "run-staged-tests": "./scripts/run-staged-tests.sh", "run-pushed-files-tests": "./scripts/run-staged-tests.sh --pushed" }, + "resolutions": { + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.3" + }, "eslintConfig": { "extends": [ "react-app", @@ -102,9 +104,11 @@ "jest-transform-stub": "^2.0.0", "prettier": "3.2.5", "react-test-renderer": "^18.3.0", - "ts-jest": "^29.1.2" + "ts-jest": "^29.1.2", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.3" }, - "repository": "git@github.com:onemanfighter/ARMacPortfolio.git", + "repository": "git@github.com:AmitRaikwar-in/MacMock.git", "author": "Amit Raikwar", "license": "MIT" } diff --git a/src/App.tsx b/src/App.tsx index 26ea57e..38653fd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,10 +15,10 @@ function App() { try { const promise = handle.enter(); if (promise && promise.catch) { - promise.catch((err: any) => console.warn('Fullscreen error:', err)); + promise.catch(() => {}); } } catch (err) { - console.warn('Fullscreen error:', err); + // ignore } } else if (event.key === 'Escape') { handle.exit(); @@ -33,10 +33,10 @@ function App() { try { const promise = handle.enter(); if (promise && promise.catch) { - promise.catch((err: any) => console.warn('Fullscreen error:', err)); + promise.catch(() => {}); } } catch (err) { - console.warn('Fullscreen error:', err); + // ignore } } }; diff --git a/src/components/MenuList/__tests__/__snapshots__/MenuListComponent.test.tsx.snap b/src/components/MenuList/__tests__/__snapshots__/MenuListComponent.test.tsx.snap index e2d8fc7..3b82fd2 100644 --- a/src/components/MenuList/__tests__/__snapshots__/MenuListComponent.test.tsx.snap +++ b/src/components/MenuList/__tests__/__snapshots__/MenuListComponent.test.tsx.snap @@ -11,7 +11,7 @@ exports[`MenuList component should render for default values 1`] = ` class="chakra-menu__menu-list css-f6jf1x" id="menu-list-:r1:" role="menu" - style="transform-origin: var(--popper-transform-origin); opacity: 0; visibility: hidden; transform: scale(0.8) translateZ(0);" + style="transform-origin: var(--popper-transform-origin); opacity: 0; visibility: hidden; transform: scale(0.8);" tabindex="-1" >
diff --git a/src/components/Modal/Modals/Search/__tests__/__snapshots__/SearchModal.test.tsx.snap b/src/components/Modal/Modals/Search/__tests__/__snapshots__/SearchModal.test.tsx.snap index d015af4..07a154f 100644 --- a/src/components/Modal/Modals/Search/__tests__/__snapshots__/SearchModal.test.tsx.snap +++ b/src/components/Modal/Modals/Search/__tests__/__snapshots__/SearchModal.test.tsx.snap @@ -27,7 +27,7 @@ exports[`SearchModal should not render component if isOpen is false 1`] = `
test @@ -14,7 +14,7 @@ exports[`Draggable provider should render correctly 1`] = ` exports[`Draggable provider should render correctly on dragging 1`] = `
test @@ -25,7 +25,7 @@ exports[`Draggable provider should render correctly on dragging 1`] = ` exports[`Draggable provider should render correctly with custom position 1`] = `
test @@ -36,7 +36,7 @@ exports[`Draggable provider should render correctly with custom position 1`] = ` exports[`Draggable provider should render correctly with custom position for maximized 1`] = `
test diff --git a/src/providers/routerProvider/__tests__/__snapshots__/RouterProvider.test.tsx.snap b/src/providers/routerProvider/__tests__/__snapshots__/RouterProvider.test.tsx.snap index b48e9e7..e12659a 100644 --- a/src/providers/routerProvider/__tests__/__snapshots__/RouterProvider.test.tsx.snap +++ b/src/providers/routerProvider/__tests__/__snapshots__/RouterProvider.test.tsx.snap @@ -98,64 +98,100 @@ exports[`RouterProvider should render for lock when power is on but user logged 11:01

+

Your password is required to enable Touch ID

@@ -173,7 +209,7 @@ exports[`RouterProvider should render for power off 1`] = ` >
+
-
- +
+
+
+ +

Your password is required to enable Touch ID

diff --git a/src/screens/public/Lock/component/TimeDate.tsx b/src/screens/public/Lock/component/TimeDate.tsx index 5127c39..5bd54cf 100644 --- a/src/screens/public/Lock/component/TimeDate.tsx +++ b/src/screens/public/Lock/component/TimeDate.tsx @@ -26,11 +26,12 @@ const TimeDateComponent = () => { const { dateObject } = uiStore(useShallow(dateTimeSelector)); const formattedDate = dateObject?.toDateString().slice(0, 10) ?? ''; - const formattedTime = dateObject?.toLocaleTimeString([], { - hour: '2-digit', - minute: '2-digit', - hour12: false, - }) ?? ''; + const formattedTime = + dateObject?.toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + hour12: false, + }) ?? ''; return ( - Profile + Profile {/* Username โ€” always rendered, fades in on expanded */} @@ -237,21 +232,20 @@ const UserLoginComponent = () => { const [isLoading, toggleIsLoading] = useBoolean(); const { login, isUserLocked } = processStore(useShallow(loginSelector)); - const { name, password: userPasswordData, profilePicture } = - settingsStore(useShallow(usersSelector)).userData; + const { + name, + password: userPasswordData, + profilePicture, + } = settingsStore(useShallow(usersSelector)).userData; const handleLogin = useCallback(() => { if (isLoading) return; toggleIsLoading.on(); - console.log('[UserLogin] Login attempt started'); setTimeout(() => { if (password === userPasswordData) { - console.log('[UserLogin] Password matched โ€” logging in'); login(); - } else { - console.warn('[UserLogin] Incorrect password'); } toggleIsLoading.off(); }, LOGIN_DELAY_MS); @@ -294,9 +288,9 @@ const UserLoginComponent = () => { onClick={togglePasswordVisibility.toggle} /> - diff --git a/src/screens/public/Lock/component/__Tests__/__snapshots__/UserLogin.test.tsx.snap b/src/screens/public/Lock/component/__Tests__/__snapshots__/UserLogin.test.tsx.snap index 8104aa1..cba32ba 100644 --- a/src/screens/public/Lock/component/__Tests__/__snapshots__/UserLogin.test.tsx.snap +++ b/src/screens/public/Lock/component/__Tests__/__snapshots__/UserLogin.test.tsx.snap @@ -2,64 +2,100 @@ exports[`UserLogin should be able to enter password on password field 1`] = `
+

Your password is required to enable Touch ID

@@ -69,64 +105,100 @@ exports[`UserLogin should be able to enter password on password field 1`] = ` exports[`UserLogin should be able to enter password on password field 2`] = `
+

Your password is required to enable Touch ID

@@ -136,64 +208,100 @@ exports[`UserLogin should be able to enter password on password field 2`] = ` exports[`UserLogin should return the default user login component 1`] = `
+

Your password is required to enable Touch ID

@@ -203,55 +311,94 @@ exports[`UserLogin should return the default user login component 1`] = ` exports[`UserLogin should show spinner on click on login button 1`] = `
+

Your password is required to enable Touch ID

@@ -261,64 +408,100 @@ exports[`UserLogin should show spinner on click on login button 1`] = ` exports[`UserLogin should show spinner on click on login button 2`] = `
+

Your password is required to enable Touch ID

diff --git a/src/screens/public/Power/__tests__/__snapshots__/Power.test.tsx.snap b/src/screens/public/Power/__tests__/__snapshots__/Power.test.tsx.snap index cfa9dad..3ae4b90 100644 --- a/src/screens/public/Power/__tests__/__snapshots__/Power.test.tsx.snap +++ b/src/screens/public/Power/__tests__/__snapshots__/Power.test.tsx.snap @@ -4,7 +4,7 @@ exports[`PowerOn should render correctly to match snapshot 1`] = `