diff --git a/.dockerignore b/.dockerignore index 45502ad8..b99e7de9 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,3 @@ -react/node_modules +node_modules .git .gitignore diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index c0c872d4..5934e253 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -40,7 +40,7 @@ jobs: - name: Install dependencies run: | - pnpm install --frozen-lockfile + pnpm install --frozen-lockfile --ignore-scripts - name: Check codebase via Oxlint run: | diff --git a/.oxfmtrc.json b/.oxfmtrc.json index 50355c2d..4e8caa7b 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -31,5 +31,10 @@ ["alias-imports", "internal", "type-internal"], "unknown" ] + }, + "sortTailwindcss": { + "stylesheet": "src/index.css", + "functions": ["clsx", "cn"], + "preserveWhitespace": true } } diff --git a/.oxlintrc.json b/.oxlintrc.json index 77c12b93..3a394c77 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -17,13 +17,16 @@ // Automatically generated code "src/routeTree.gen.ts", - // Shadcn components + // Shadcn/ui components "src/components/ui", - "!src/components/ui/theme-provider.tsx" + "!src/components/ui/theme-provider.tsx", + "!src/components/ui/carousel.tsx" ], "overrides": [ { - "files": ["**/*.{ts,tsx}"], + "files": [ + "**/*.{ts,tsx}" + ], "rules": { "constructor-super": "error", "for-direction": "error", @@ -78,6 +81,7 @@ "no-unused-labels": "error", "no-unused-private-class-members": "error", "no-unused-vars": "error", + "no-useless-assignment": "error", "no-useless-backreference": "error", "no-useless-catch": "error", "no-useless-escape": "error", @@ -175,18 +179,85 @@ "allowRegExp": false } ], - "typescript/return-await": ["error", "error-handling-correctness-only"], + "typescript/return-await": [ + "error", + "error-handling-correctness-only" + ], "typescript/triple-slash-reference": "error", "typescript/unbound-method": "error", "typescript/unified-signatures": "error", "typescript/use-unknown-in-catch-callback-variable": "error", - "import/named": "error", + "react/rules-of-hooks": "error", + "react/exhaustive-deps": "warn", + "react-x/error-boundaries": "error", + "react-x/exhaustive-deps": "warn", + "react-x/no-access-state-in-setstate": "error", + "react-x/no-array-index-key": "warn", + "react-x/no-children-count": "warn", + "react-x/no-children-for-each": "warn", + "react-x/no-children-map": "warn", + "react-x/no-children-only": "warn", + "react-x/no-children-to-array": "warn", + "react-x/no-clone-element": "warn", + "react-x/no-component-will-mount": "error", + "react-x/no-component-will-receive-props": "error", + "react-x/no-component-will-update": "error", + "react-x/no-context-provider": "warn", + "react-x/no-create-ref": "error", + "react-x/no-direct-mutation-state": "error", + "react-x/no-forward-ref": "warn", + "react-x/no-missing-key": "error", + "react-x/no-nested-component-definitions": "error", + "react-x/no-nested-lazy-component-declarations": "error", + "react-x/no-set-state-in-component-did-mount": "warn", + "react-x/no-set-state-in-component-did-update": "warn", + "react-x/no-set-state-in-component-will-update": "warn", + "react-x/no-unnecessary-use-prefix": "warn", + "react-x/no-unsafe-component-will-mount": "warn", + "react-x/no-unsafe-component-will-receive-props": "warn", + "react-x/no-unsafe-component-will-update": "warn", + "react-x/no-unused-class-component-members": "warn", + "react-x/no-unused-state": "warn", + "react-x/no-use-context": "warn", + "react-x/purity": "warn", + "react-x/rules-of-hooks": "error", + "react-x/set-state-in-effect": "warn", + "react-x/set-state-in-render": "error", + "react-x/static-components": "error", + "react-x/unsupported-syntax": "error", + "react-x/use-memo": "error", + "react-x/use-state": "warn", + "react-dom/no-dangerously-set-innerhtml": "warn", + "react-dom/no-dangerously-set-innerhtml-with-children": "error", + "react-dom/no-find-dom-node": "error", + "react-dom/no-flush-sync": "error", + "react-dom/no-hydrate": "error", + "react-dom/no-render": "error", + "react-dom/no-render-return-value": "error", + "react-dom/no-script-url": "warn", + "react-dom/no-unsafe-iframe-sandbox": "warn", + "react-dom/no-use-form-state": "error", + "react-dom/no-void-elements-with-children": "error", + "react-naming-convention/context-name": "warn", + "react-naming-convention/id-name": "warn", + "react-naming-convention/ref-name": "warn", + "react-jsx/no-children-prop": "warn", + "react-jsx/no-children-prop-with-children": "error", + "react-jsx/no-comment-textnodes": "warn", + "react-jsx/no-key-after-spread": "error", + "react-jsx/no-leaked-dollar": "warn", + "react-jsx/no-leaked-semicolon": "warn", + "react-jsx/no-namespace": "error", + "import/named": "off", "import/namespace": "error", "import/default": "error", "import/export": "error", "import/no-named-as-default": "warn", "import/no-named-as-default-member": "warn", "import/no-duplicates": "warn", + "react-perf/jsx-no-new-object-as-prop": "error", + "react-perf/jsx-no-new-array-as-prop": "error", + "react-perf/jsx-no-new-function-as-prop": "error", "jsx-a11y/alt-text": "error", "jsx-a11y/anchor-ambiguous-text": "off", "jsx-a11y/anchor-has-content": "error", @@ -212,7 +283,9 @@ "error", { "tags": [], - "roles": ["tabpanel"], + "roles": [ + "tabpanel" + ], "allowExpressionValues": true } ], @@ -235,66 +308,6 @@ "jsx-a11y/role-supports-aria-props": "error", "jsx-a11y/scope": "error", "jsx-a11y/tabindex-no-positive": "error", - "react-dom/no-dangerously-set-innerhtml": "warn", - "react-dom/no-dangerously-set-innerhtml-with-children": "error", - "react-dom/no-find-dom-node": "error", - "react-dom/no-flush-sync": "error", - "react-dom/no-hydrate": "error", - "react-dom/no-render": "error", - "react-dom/no-render-return-value": "error", - "react-dom/no-script-url": "warn", - "react-dom/no-unsafe-iframe-sandbox": "warn", - "react-dom/no-use-form-state": "error", - "react-dom/no-void-elements-with-children": "error", - "react-perf/jsx-no-new-object-as-prop": "error", - "react-perf/jsx-no-new-array-as-prop": "error", - "react-perf/jsx-no-new-function-as-prop": "error", - "react-x/component-hook-factories": "error", - "react-x/error-boundaries": "error", - "react-x/exhaustive-deps": "warn", - "react-x/no-access-state-in-setstate": "error", - "react-x/no-array-index-key": "warn", - "react-x/no-children-count": "warn", - "react-x/no-children-for-each": "warn", - "react-x/no-children-map": "warn", - "react-x/no-children-only": "warn", - "react-x/no-children-to-array": "warn", - "react-x/no-clone-element": "warn", - "react-x/no-component-will-mount": "error", - "react-x/no-component-will-receive-props": "error", - "react-x/no-component-will-update": "error", - "react-x/no-context-provider": "warn", - "react-x/no-create-ref": "error", - "react-x/no-direct-mutation-state": "error", - "react-x/no-forward-ref": "warn", - "react-x/no-missing-key": "error", - "react-x/no-nested-component-definitions": "error", - "react-x/no-nested-lazy-component-declarations": "error", - "react-x/no-redundant-should-component-update": "error", - "react-x/no-set-state-in-component-did-mount": "warn", - "react-x/no-set-state-in-component-did-update": "warn", - "react-x/no-set-state-in-component-will-update": "warn", - "react-x/no-unnecessary-use-prefix": "warn", - "react-x/no-unsafe-component-will-mount": "warn", - "react-x/no-unsafe-component-will-receive-props": "warn", - "react-x/no-unsafe-component-will-update": "warn", - "react-x/no-unused-class-component-members": "warn", - "react-x/no-use-context": "warn", - "react-x/purity": "warn", - "react-x/rules-of-hooks": "error", - "react-x/set-state-in-effect": "warn", - "react-x/set-state-in-render": "error", - "react-x/unsupported-syntax": "error", - "react-x/use-memo": "error", - "react-x/use-state": "warn", - "react-x/no-class-component": "error", - "react-x/no-misused-capture-owner-stack": "error", - "react-x/no-unnecessary-use-callback": "warn", - "react-x/no-unnecessary-use-memo": "warn", - "react-x/no-unstable-context-value": "warn", - "react-x/no-unstable-default-props": "warn", - "react-x/no-unused-state": "warn", - "react-x/prefer-destructuring-assignment": "warn", "no-negated-condition": "off", "no-nested-ternary": "off", "unicorn/catch-error-name": "error", @@ -303,6 +316,7 @@ "unicorn/consistent-empty-array-spread": "error", "unicorn/consistent-existence-index-check": "error", "unicorn/consistent-function-scoping": "error", + "unicorn/consistent-template-literal-escape": "error", "unicorn/custom-error-definition": "off", "unicorn/empty-brace-spaces": "error", "unicorn/error-message": "error", @@ -353,6 +367,7 @@ "unicorn/no-useless-collection-argument": "error", "unicorn/no-useless-error-capture-stack-trace": "error", "unicorn/no-useless-fallback-in-spread": "error", + "unicorn/no-useless-iterator-to-array": "error", "unicorn/no-useless-length-check": "error", "unicorn/no-useless-promise-resolve-reject": "error", "unicorn/no-useless-spread": "error", @@ -381,6 +396,7 @@ "unicorn/prefer-dom-node-text-content": "error", "unicorn/prefer-event-target": "error", "unicorn/prefer-global-this": "error", + "unicorn/prefer-import-meta-properties": "off", "unicorn/prefer-includes": "error", "unicorn/prefer-keyboard-event-key": "error", "unicorn/prefer-logical-operator-over-ternary": "error", @@ -419,11 +435,35 @@ "unicorn/require-number-to-fixed-digits-argument": "error", "unicorn/require-post-message-target-origin": "off", "unicorn/switch-case-braces": "error", + "unicorn/switch-case-break-position": "error", "unicorn/text-encoding-identifier-case": "error", - "unicorn/throw-new-error": "error" + "unicorn/throw-new-error": "error", + "@tanstack/query/exhaustive-deps": "error", + "@tanstack/query/no-rest-destructuring": "warn", + "@tanstack/query/stable-query-client": "error", + "@tanstack/query/no-unstable-deps": "error", + "@tanstack/query/infinite-query-property-order": "error", + "@tanstack/query/no-void-query-fn": "error", + "@tanstack/query/mutation-property-order": "error", + "@tanstack/router/create-route-property-order": "warn", + "@tanstack/router/route-param-names": "error" }, - "plugins": ["typescript", "import", "jsx-a11y", "react-perf", "unicorn"], - "jsPlugins": ["eslint-plugin-react-dom", "eslint-plugin-react-x"], + "plugins": [ + "typescript", + "react", + "import", + "react-perf", + "jsx-a11y", + "unicorn" + ], + "jsPlugins": [ + "eslint-plugin-react-x", + "eslint-plugin-react-dom", + "eslint-plugin-react-naming-convention", + "eslint-plugin-react-jsx", + "@tanstack/eslint-plugin-query", + "@tanstack/eslint-plugin-router" + ], "env": { "es2026": true, "es2020": true, @@ -431,4 +471,4 @@ } } ] -} +} \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js index c6bdb34c..23a585b9 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,5 +1,3 @@ -import pluginQuery from "@tanstack/eslint-plugin-query"; -import pluginRouter from "@tanstack/eslint-plugin-router"; import oxlint from "eslint-plugin-oxlint"; import reactHooks from "eslint-plugin-react-hooks"; import { defineConfig, globalIgnores } from "eslint/config"; @@ -26,10 +24,6 @@ export default defineConfig([ // React-specific configurations reactHooks.configs.flat.recommended, - // Tanstack-specific ESLint configuration - pluginQuery.configs["flat/recommended"], - pluginRouter.configs["flat/recommended"], - oxlint.configs["flat/recommended"], ], languageOptions: { diff --git a/index.old.tsx b/index.old.tsx deleted file mode 100644 index bd70831e..00000000 --- a/index.old.tsx +++ /dev/null @@ -1,171 +0,0 @@ -import { ChevronDown } from "lucide-react"; -import { useId } from "react"; - - -import { - Accordion, - AccordionContent, - AccordionItem, - AccordionTrigger, -} from "@/components/ui/accordion"; -import { Button } from "@/components/ui/button"; - -import { cn } from "@/lib/utils"; - -interface MenuAnchorProps { - targetId: string; - className?: string; -} - -function MenuAnchorButton({ targetId, className }: Readonly) { - const handleClick = () => { - const targetElement = document.getElementById(targetId); - - if (targetElement) { - targetElement.scrollIntoView(); - } - }; - return ( - - ); -} -function Index() { - const aboutSection = useId(); - - return ( - <> - {/* Hero section */} -
-
-
-

- Where Theory and Practice Fuse -

-

- Central Valley's Flagship Computer Science Community at UC Merced -

- -
- -
- placeholder -
-
- -
- -
-
- - {/* Introduction section */} -
-
-
- placeholder -
- -
-
-

- Providing professional and community expertise in Computer - Science to you -

-

- ACM at UC Merced is an student-run computing organization that - fosters an community environment where individuals interested in - Computer Science can discuss, educate, and collaborate. We - strive to create and maintain and community where students are - prepared for practical CS skills and knowledge through - collaboration, workshops, seminars, and passion. -

-
-
-
-
- - {/* SIGs Intro */} -
-
-

Student Interest Groups

-

- ACM @ UC Merced has 6 groups, which all independently host workshops - and other events to support the goal. -

- -
-
- - {/* FAQ section */} -
-
-

- Frequently Asked Questions -

- - - Is it accessible? - - Yes. It adheres to the WAI-ARIA design pattern. - - - - Is it accessible? - - Yes. It adheres to the WAI-ARIA design pattern. - - - -
-
- - ); -} - -export { Index }; diff --git a/package.json b/package.json index dce2c5a1..ad121c02 100644 --- a/package.json +++ b/package.json @@ -11,11 +11,15 @@ "dependencies": { "@base-ui/react": "^1.3.0", "@fontsource-variable/raleway": "^5.2.8", + "@icons-pack/react-simple-icons": "^13.13.0", "@tanstack/react-query": "^5.96.2", "@tanstack/react-router": "^1.168.10", + "axios": "^1.16.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "embla-carousel-react": "^8.6.0", "lucide-react": "^1.0.0", + "motion": "^12.38.0", "next-themes": "^0.4.6", "react": "^19.2.4", "react-dom": "^19.2.4", @@ -39,7 +43,9 @@ "eslint-plugin-oxlint": "^1.58.0", "eslint-plugin-react-dom": "^5.0.0", "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-react-x": "^5.0.0", + "eslint-plugin-react-jsx": "^5.7.1", + "eslint-plugin-react-naming-convention": "^5.7.1", + "eslint-plugin-react-x": "^5.7.1", "globals": "^17.4.0", "oxfmt": "^0.47.0", "oxlint": "^1.58.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7433965f..50b7f013 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,21 +14,33 @@ importers: '@fontsource-variable/raleway': specifier: ^5.2.8 version: 5.2.8 + '@icons-pack/react-simple-icons': + specifier: ^13.13.0 + version: 13.13.0(react@19.2.5) '@tanstack/react-query': specifier: ^5.96.2 version: 5.100.9(react@19.2.5) '@tanstack/react-router': specifier: ^1.168.10 version: 1.169.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + axios: + specifier: ^1.16.0 + version: 1.16.0 class-variance-authority: specifier: ^0.7.1 version: 0.7.1 clsx: specifier: ^2.1.1 version: 2.1.1 + embla-carousel-react: + specifier: ^8.6.0 + version: 8.6.0(react@19.2.5) lucide-react: specifier: ^1.0.0 version: 1.14.0(react@19.2.5) + motion: + specifier: ^12.38.0 + version: 12.38.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -93,8 +105,14 @@ importers: eslint-plugin-react-hooks: specifier: ^7.0.1 version: 7.1.1(eslint@10.3.0(jiti@2.6.1)) + eslint-plugin-react-jsx: + specifier: ^5.7.1 + version: 5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) + eslint-plugin-react-naming-convention: + specifier: ^5.7.1 + version: 5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) eslint-plugin-react-x: - specifier: ^5.0.0 + specifier: ^5.7.1 version: 5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) globals: specifier: ^17.4.0 @@ -129,8 +147,9 @@ importers: packages: - '@antfu/ni@0.23.2': - resolution: {integrity: sha512-FSEVWXvwroExDXUu8qV6Wqp2X3D1nJ0Li4LFymCyvCVrm7I3lNfG0zZWSWvGU1RE7891eTnFTyh31L3igOwNKQ==} + '@antfu/ni@30.1.0': + resolution: {integrity: sha512-3VuAbPjgY52rQNn4wABaXMhBU2Oq91uy6L8nX49eJ35OLI68CyckGU+HZxcaHix4ymuGM2nFL1D6sLpgODK5xw==} + engines: {node: '>=20.19.0'} hasBin: true '@babel/code-frame@7.29.0': @@ -428,6 +447,12 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@icons-pack/react-simple-icons@13.13.0': + resolution: {integrity: sha512-B5HhQMIpcSH4z8IZ8HFhD59CboHceKYMpPC9kAwGyKntvPdyJJv26DLu4Z1wAjcCLyrJhf11tMhiQGom9Rxb9g==} + engines: {node: '>=24', pnpm: '>=10'} + peerDependencies: + react: ^16.13 || ^17 || ^18 || ^19 + '@inquirer/ansi@2.0.5': resolution: {integrity: sha512-doc2sWgJpbFQ64UflSVd17ibMGDuxO1yKgOgLMwavzESnXjFWJqUeG8saYosqKpHp4kWiM5x1nXvEjbpx90gzw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -820,8 +845,8 @@ packages: peerDependencies: preact: 10.x - '@react-grab/cli@0.1.32': - resolution: {integrity: sha512-TI4SHATLH2yM1DMRXgH3dt/8b3Rj51BplDOqOQiHQKAMOuKVAR9WE2WGWJRT3LwFpl8BXR9ytAM9vrGDrB7QGw==} + '@react-grab/cli@0.1.33': + resolution: {integrity: sha512-UOc3PwN11Osw0NzaxRLK8trP4X+5iW1Dst3gvHRCafe3wXHyadzHYH8H1hdkcXdlIx3gsoD9ASJ+G/JH+A/jqA==} hasBin: true '@rolldown/binding-android-arm64@1.0.0-rc.17': @@ -1312,6 +1337,12 @@ packages: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.16.0: + resolution: {integrity: sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==} + babel-dead-code-elimination@1.0.12: resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} @@ -1395,6 +1426,10 @@ packages: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} + cli-spinners@3.4.0: + resolution: {integrity: sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==} + engines: {node: '>=18.20'} + cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} @@ -1417,6 +1452,10 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + commander@11.1.0: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} @@ -1519,6 +1558,10 @@ packages: resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} engines: {node: '>=12'} + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -1549,6 +1592,19 @@ packages: electron-to-chromium@1.5.349: resolution: {integrity: sha512-QsWVGyRuY07Aqb234QytTfwd5d9AJlfNIQ5wIOl1L+PZDzI9d9+Fn0FRale/QYlFxt/bUnB0/nLd1jFPGxGK1A==} + embla-carousel-react@8.6.0: + resolution: {integrity: sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==} + peerDependencies: + react: ^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + + embla-carousel-reactive-utils@8.6.0: + resolution: {integrity: sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==} + peerDependencies: + embla-carousel: 8.6.0 + + embla-carousel@8.6.0: + resolution: {integrity: sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==} + emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -1582,6 +1638,10 @@ packages: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -1611,6 +1671,20 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0 + eslint-plugin-react-jsx@5.7.1: + resolution: {integrity: sha512-pIDQQU5QZXLsaAShv7J2yVBpC9KAMQmOyBIEAPzDkOShVvH8p4Jyy/xQbvoTUE6UaOkpzsHRmOaTISLtdulmMA==} + engines: {node: '>=22.0.0'} + peerDependencies: + eslint: ^10.2.1 + typescript: '*' + + eslint-plugin-react-naming-convention@5.7.1: + resolution: {integrity: sha512-kmWTEgTyaCCmtpG0OvDzhQOCawSxLphX6Hs1cAskRFn2DO9So8JjHUX+/Q0D8MzR5rX6WL5jBu+I2AgdLXcpvw==} + engines: {node: '>=22.0.0'} + peerDependencies: + eslint: ^10.2.1 + typescript: '*' + eslint-plugin-react-x@5.7.1: resolution: {integrity: sha512-XskzY5TH6asFkAIqmUXXjrxJjJS74YIAm6Q1fIC835gOkPlPOPOLNG1Sy9eS4uJ1fFhGnZ5jzlRFL8WgdU9LOQ==} engines: {node: '>=22.0.0'} @@ -1766,6 +1840,19 @@ packages: flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} @@ -1774,6 +1861,20 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} + framer-motion@12.38.0: + resolution: {integrity: sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + fresh@2.0.0: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} @@ -1793,6 +1894,9 @@ packages: fuzzysort@3.1.0: resolution: {integrity: sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ==} + fzf@0.5.2: + resolution: {integrity: sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q==} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -1852,6 +1956,10 @@ packages: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + hasown@2.0.3: resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} engines: {node: '>= 0.4'} @@ -2154,6 +2262,10 @@ packages: resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} engines: {node: '>=18'} + log-symbols@7.0.1: + resolution: {integrity: sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==} + engines: {node: '>=18'} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -2188,10 +2300,18 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + mime-db@1.54.0: resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + mime-types@3.0.2: resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} @@ -2211,6 +2331,26 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + motion-dom@12.38.0: + resolution: {integrity: sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==} + + motion-utils@12.36.0: + resolution: {integrity: sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==} + + motion@12.38.0: + resolution: {integrity: sha512-uYfXzeHlgThchzwz5Te47dlv5JOUC7OB4rjJ/7XTUgtBZD8CchMN8qEJ4ZVsUmTyYA44zjV0fBwsiktRuFnn+w==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2309,6 +2449,10 @@ packages: resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} engines: {node: '>=18'} + ora@9.4.0: + resolution: {integrity: sha512-84cglkRILFxdtA8hAvLNdMrtBpPNBTrQ9/ulg0FA7xLMnD6mifv+enAIeRmvtv+WgdCE+LPGOfQmtJRrVaIVhQ==} + engines: {node: '>=20'} + outvariant@1.4.3: resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} @@ -2339,6 +2483,9 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2430,6 +2577,10 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2454,8 +2605,8 @@ packages: peerDependencies: react: ^19.2.5 - react-grab@0.1.32: - resolution: {integrity: sha512-ODZkzu4zjwX/5a1VxTdIkagPD6uPnp8IkSN2v5FDgFMZkH5r/YEMq43hIsdpHV5/R2ymqS9zLxp4H7SNSRx5ng==} + react-grab@0.1.33: + resolution: {integrity: sha512-ER919JMsE4TTrb2CpEivqsIjNMSycD4HtS8v7mS3pq67U7WL1K3+C8m9AYOwW4dpuYh+EanC2eJBmfuczHJZ0A==} hasBin: true peerDependencies: react: '>=17.0.0' @@ -2631,6 +2782,10 @@ packages: resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} engines: {node: '>=18'} + stdin-discarder@0.3.2: + resolution: {integrity: sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A==} + engines: {node: '>=18'} + strict-event-emitter@0.5.1: resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} @@ -2645,6 +2800,10 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string-width@8.2.1: + resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==} + engines: {node: '>=20'} + stringify-object@5.0.0: resolution: {integrity: sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg==} engines: {node: '>=14.16'} @@ -2686,6 +2845,10 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tinyexec@1.1.2: + resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} + engines: {node: '>=18'} + tinyglobby@0.2.16: resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} engines: {node: '>=12.0.0'} @@ -2931,7 +3094,12 @@ packages: snapshots: - '@antfu/ni@0.23.2': {} + '@antfu/ni@30.1.0': + dependencies: + fzf: 0.5.2 + package-manager-detector: 1.6.0 + tinyexec: 1.1.2 + tinyglobby: 0.2.16 '@babel/code-frame@7.29.0': dependencies: @@ -3319,6 +3487,10 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@icons-pack/react-simple-icons@13.13.0(react@19.2.5)': + dependencies: + react: 19.2.5 + '@inquirer/ansi@2.0.5': {} '@inquirer/confirm@6.0.12(@types/node@25.6.0)': @@ -3575,13 +3747,13 @@ snapshots: '@preact/signals-core': 1.14.1 preact: 10.29.1 - '@react-grab/cli@0.1.32': + '@react-grab/cli@0.1.33': dependencies: - '@antfu/ni': 0.23.2 + '@antfu/ni': 30.1.0 commander: 14.0.3 ignore: 7.0.5 jsonc-parser: 3.3.1 - ora: 8.2.0 + ora: 9.4.0 picocolors: 1.1.1 prompts: 2.4.2 smol-toml: 1.6.1 @@ -4036,6 +4208,16 @@ snapshots: dependencies: tslib: 2.8.1 + asynckit@0.4.0: {} + + axios@1.16.0: + dependencies: + follow-redirects: 1.16.0 + form-data: 4.0.5 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + babel-dead-code-elimination@1.0.12: dependencies: '@babel/core': 7.29.0 @@ -4133,6 +4315,8 @@ snapshots: cli-spinners@2.9.2: {} + cli-spinners@3.4.0: {} + cli-width@4.1.0: {} cliui@8.0.1: @@ -4151,6 +4335,10 @@ snapshots: color-name@1.1.4: {} + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + commander@11.1.0: {} commander@14.0.3: {} @@ -4216,6 +4404,8 @@ snapshots: define-lazy-prop@3.0.0: {} + delayed-stream@1.0.0: {} + depd@2.0.0: {} detect-libc@2.1.2: {} @@ -4241,6 +4431,18 @@ snapshots: electron-to-chromium@1.5.349: {} + embla-carousel-react@8.6.0(react@19.2.5): + dependencies: + embla-carousel: 8.6.0 + embla-carousel-reactive-utils: 8.6.0(embla-carousel@8.6.0) + react: 19.2.5 + + embla-carousel-reactive-utils@8.6.0(embla-carousel@8.6.0): + dependencies: + embla-carousel: 8.6.0 + + embla-carousel@8.6.0: {} + emoji-regex@10.6.0: {} emoji-regex@8.0.0: {} @@ -4266,6 +4468,13 @@ snapshots: dependencies: es-errors: 1.3.0 + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.3 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -4302,6 +4511,34 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-plugin-react-jsx@5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3): + dependencies: + '@eslint-react/ast': 5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) + '@eslint-react/core': 5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) + '@eslint-react/eslint': 5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) + '@eslint-react/jsx': 5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) + '@eslint-react/shared': 5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/utils': 8.59.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) + eslint: 10.3.0(jiti@2.6.1) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + eslint-plugin-react-naming-convention@5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3): + dependencies: + '@eslint-react/ast': 5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) + '@eslint-react/core': 5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) + '@eslint-react/eslint': 5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) + '@eslint-react/var': 5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/utils': 8.59.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) + eslint: 10.3.0(jiti@2.6.1) + ts-pattern: 5.9.0 + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + eslint-plugin-react-x@5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3): dependencies: '@eslint-react/ast': 5.7.1(eslint@10.3.0(jiti@2.6.1))(typescript@6.0.3) @@ -4541,12 +4778,31 @@ snapshots: flatted@3.4.2: {} + follow-redirects@1.16.0: {} + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.3 + mime-types: 2.1.35 + formdata-polyfill@4.0.10: dependencies: fetch-blob: 3.2.0 forwarded@0.2.0: {} + framer-motion@12.38.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + dependencies: + motion-dom: 12.38.0 + motion-utils: 12.36.0 + tslib: 2.8.1 + optionalDependencies: + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + fresh@2.0.0: {} fs-extra@11.3.4: @@ -4562,6 +4818,8 @@ snapshots: fuzzysort@3.1.0: {} + fzf@0.5.2: {} + gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -4613,6 +4871,10 @@ snapshots: has-symbols@1.1.0: {} + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + hasown@2.0.3: dependencies: function-bind: 1.1.2 @@ -4831,6 +5093,11 @@ snapshots: chalk: 5.6.2 is-unicode-supported: 1.3.0 + log-symbols@7.0.1: + dependencies: + is-unicode-supported: 2.1.0 + yoctocolors: 2.1.2 + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -4858,8 +5125,14 @@ snapshots: braces: 3.0.3 picomatch: 2.3.2 + mime-db@1.52.0: {} + mime-db@1.54.0: {} + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + mime-types@3.0.2: dependencies: mime-db: 1.54.0 @@ -4874,6 +5147,20 @@ snapshots: minimist@1.2.8: {} + motion-dom@12.38.0: + dependencies: + motion-utils: 12.36.0 + + motion-utils@12.36.0: {} + + motion@12.38.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5): + dependencies: + framer-motion: 12.38.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + tslib: 2.8.1 + optionalDependencies: + react: 19.2.5 + react-dom: 19.2.5(react@19.2.5) + ms@2.1.3: {} msw@2.14.2(@types/node@25.6.0)(typescript@6.0.3): @@ -4987,6 +5274,17 @@ snapshots: string-width: 7.2.0 strip-ansi: 7.2.0 + ora@9.4.0: + dependencies: + chalk: 5.6.2 + cli-cursor: 5.0.0 + cli-spinners: 3.4.0 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 7.0.1 + stdin-discarder: 0.3.2 + string-width: 8.2.1 + outvariant@1.4.3: {} oxfmt@0.47.0: @@ -5053,6 +5351,8 @@ snapshots: dependencies: p-limit: 3.1.0 + package-manager-detector@1.6.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -5123,6 +5423,8 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 + proxy-from-env@2.1.0: {} + punycode@2.3.1: {} qs@6.15.1: @@ -5145,9 +5447,9 @@ snapshots: react: 19.2.5 scheduler: 0.27.0 - react-grab@0.1.32(react@19.2.5): + react-grab@0.1.33(react@19.2.5): dependencies: - '@react-grab/cli': 0.1.32 + '@react-grab/cli': 0.1.33 bippy: 0.5.39(react@19.2.5) optionalDependencies: react: 19.2.5 @@ -5165,7 +5467,7 @@ snapshots: prompts: 2.4.2 react: 19.2.5 react-dom: 19.2.5(react@19.2.5) - react-grab: 0.1.32(react@19.2.5) + react-grab: 0.1.33(react@19.2.5) optionalDependencies: unplugin: 2.1.0 transitivePeerDependencies: @@ -5381,6 +5683,8 @@ snapshots: stdin-discarder@0.2.2: {} + stdin-discarder@0.3.2: {} + strict-event-emitter@0.5.1: {} string-ts@2.3.1: {} @@ -5397,6 +5701,11 @@ snapshots: get-east-asian-width: 1.5.0 strip-ansi: 7.2.0 + string-width@8.2.1: + dependencies: + get-east-asian-width: 1.5.0 + strip-ansi: 7.2.0 + stringify-object@5.0.0: dependencies: get-own-enumerable-keys: 1.0.0 @@ -5427,6 +5736,8 @@ snapshots: tiny-invariant@1.3.3: {} + tinyexec@1.1.2: {} + tinyglobby@0.2.16: dependencies: fdir: 6.5.0(picomatch@4.0.4) diff --git a/src/assets/images/acm-logo-v2.svg b/src/assets/images/acm-logo-v2.svg new file mode 100644 index 00000000..0e760d81 --- /dev/null +++ b/src/assets/images/acm-logo-v2.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/beginnings_logo.png b/src/assets/images/beginnings_logo.png new file mode 100644 index 00000000..a510da66 Binary files /dev/null and b/src/assets/images/beginnings_logo.png differ diff --git a/src/assets/images/hero-bg.jpg b/src/assets/images/hero-bg.jpg new file mode 100644 index 00000000..4096c2a6 Binary files /dev/null and b/src/assets/images/hero-bg.jpg differ diff --git a/src/assets/images/sig-ai-logo.svg b/src/assets/images/sig-ai-logo.svg new file mode 100644 index 00000000..0cb287f8 --- /dev/null +++ b/src/assets/images/sig-ai-logo.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/sig-arch-logo.svg b/src/assets/images/sig-arch-logo.svg new file mode 100644 index 00000000..ba56d715 --- /dev/null +++ b/src/assets/images/sig-arch-logo.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/sig-cyber-logo.svg b/src/assets/images/sig-cyber-logo.svg new file mode 100644 index 00000000..93555c18 --- /dev/null +++ b/src/assets/images/sig-cyber-logo.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/sig-data-logo.svg b/src/assets/images/sig-data-logo.svg new file mode 100644 index 00000000..143e90c5 --- /dev/null +++ b/src/assets/images/sig-data-logo.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/sig-graph-logo.svg b/src/assets/images/sig-graph-logo.svg new file mode 100644 index 00000000..ed309d73 --- /dev/null +++ b/src/assets/images/sig-graph-logo.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/sig-swe-logo.svg b/src/assets/images/sig-swe-logo.svg new file mode 100644 index 00000000..0b937a82 --- /dev/null +++ b/src/assets/images/sig-swe-logo.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/app/footer.tsx b/src/components/app/footer.tsx new file mode 100644 index 00000000..36b20b3a --- /dev/null +++ b/src/components/app/footer.tsx @@ -0,0 +1,43 @@ +import { SiInstagram, SiDiscord, SiGithub, type IconType } from "@icons-pack/react-simple-icons"; + +import { ThemeToggle } from "@/components/app/theme-toggle"; + +interface SocialEntry { + label: string; + href: string; + Icon: IconType; +} + +const SOCIALS: SocialEntry[] = [ + { label: "Discord", href: "https://discord.com", Icon: SiDiscord }, + { label: "GitHub", href: "https://github.com/UCMercedACM", Icon: SiGithub }, + { label: "Instagram", href: "https://instagram.com", Icon: SiInstagram }, +]; + +export function Footer() { + return ( + + ); +} diff --git a/src/components/app/navigation-bar.tsx b/src/components/app/navigation-bar.tsx index 24255888..b24b8dff 100644 --- a/src/components/app/navigation-bar.tsx +++ b/src/components/app/navigation-bar.tsx @@ -1,43 +1,58 @@ import { Link } from "@tanstack/react-router"; -import { ChevronDown, Menu } from "lucide-react"; +import { Menu } from "lucide-react"; import { memo, useCallback, useState } from "react"; -import Logo from "@/assets/logo-full.svg"; +import acmLogo from "@/assets/images/acm-logo-v2.svg"; import { Button } from "@/components/ui/button"; -import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"; -import { - NavigationMenu, - NavigationMenuContent, - NavigationMenuItem, - NavigationMenuLink, - NavigationMenuList, - NavigationMenuTrigger, - navigationMenuTriggerStyle, -} from "@/components/ui/navigation-menu"; import { Sheet, SheetContent, SheetHeader, SheetTrigger } from "@/components/ui/sheet"; -interface NavItem { +interface NavEntry { href: string; label: string; } -interface NavGroup { - label: string; - items: NavItem[]; -} - -type NavEntry = NavItem | NavGroup; - -const NAVIGATION_ENTRIES: NavEntry[] = [ +const NAV_LINKS: NavEntry[] = [ + { href: "/about", label: "About" }, { href: "/events", label: "Events" }, - { href: "/about-us/sigs", label: "SIGs" }, + { href: "/sigs", label: "SIGs" }, + { href: "/projects", label: "Projects" }, { href: "/resources", label: "Resources" }, -] as const; +]; + +const NAV_LINK_CLASSES = + "relative cursor-pointer pb-1 text-[15px] font-bold tracking-[0.02em] transition-colors text-brand-text-sub hover:text-foreground data-[status=active]:text-foreground"; +const NAV_LINK_UNDERLINE_CLASSES = + "absolute -bottom-0.75 left-0 h-1.25 w-full rounded-[9px] bg-brand-sky opacity-0 [[data-status=active]>&]:opacity-100"; -function isNavGroup(entry: NavEntry): entry is NavGroup { - return "items" in entry; +const DesktopNavLink = memo(function DesktopNavLink({ entry }: Readonly<{ entry: NavEntry }>) { + return ( + + {entry.label} + + + ); +}); + +interface SheetNavLinkProps { + entry: NavEntry; + onNavigate: () => void; } +const SheetNavLink = memo(function SheetNavLink({ + entry, + onNavigate, +}: Readonly) { + return ( + + {entry.label} + + ); +}); + function MobileNav() { const [open, setOpen] = useState(false); const closeSheet = useCallback(() => { @@ -46,111 +61,53 @@ function MobileNav() { return ( - }> + + } + > Open menu - + ); } -const DesktopNavItems = memo(function DesktopNavItems() { - return ( - - {NAVIGATION_ENTRIES.map((entry) => { - if (isNavGroup(entry)) { - return ( - - {entry.label} - -
    - {entry.items.map((item) => ( -
  • - }> - {item.label} - -
  • - ))} -
-
-
- ); - } - return ( - - } - className={navigationMenuTriggerStyle()} - > - {entry.label} - - - ); - })} -
- ); -}); - export function Navbar() { return ( -