Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
afbe22d
MDX page architecture for non-dev editing
kylemh Mar 24, 2026
a16fd64
Visual refresh, shadcn/Base UI, static podcast
kylemh Mar 25, 2026
adf7438
Lint config cleanup, native audio, fix sitemap
kylemh Mar 25, 2026
357932c
modulify podcast data for types
kylemh Mar 25, 2026
3281e0a
more mdx
kylemh Mar 25, 2026
4cf77e0
Remove Storybook, Chromatic, and all stories
kylemh Mar 25, 2026
e9bda7e
Remove unused common/ utils, constants, and styles
kylemh Mar 25, 2026
f342122
Remove replaced custom components
kylemh Mar 25, 2026
c1cb347
Update and add shadcn/ui components
kylemh Mar 25, 2026
aa293a9
Migrate forms to shadcn/ui primitives
kylemh Mar 25, 2026
359bbab
Update components to use shadcn/ui imports
kylemh Mar 25, 2026
b32e61f
Update app pages and layouts for new imports
kylemh Mar 25, 2026
da35266
Update test config and e2e specs
kylemh Mar 25, 2026
d901c82
Update project config and dependencies
kylemh Mar 25, 2026
8a2dcb0
update snapshots
kylemh Mar 25, 2026
77467b6
animated accordion
kylemh Mar 25, 2026
946ad10
update deps
kylemh Apr 12, 2026
867c3a4
update vitest config
kylemh Apr 12, 2026
e50f5be
update snaps
kylemh Apr 12, 2026
b5e3165
fix tsconfig
kylemh Apr 12, 2026
1e06c6a
resolve type errors
kylemh Apr 12, 2026
2f6455d
enable react compiler
kylemh Apr 12, 2026
b618a73
swap lint deps and add typecheck script
kylemh Apr 12, 2026
0fd8f8f
button style changes
kylemh Apr 12, 2026
bda04c9
update lint config and resolve lint warnings/errors
kylemh Apr 12, 2026
7bf2f76
update meta images
kylemh Apr 12, 2026
96a8ee9
whoops
kylemh Apr 12, 2026
d740ed9
fix nav bg
kylemh Apr 12, 2026
a951d8b
integrate eslint-plugin-react-you-might-not-need-an-effect
kylemh Apr 12, 2026
344460f
hope i fixed type error
kylemh Apr 12, 2026
8f4e9e4
downgrade zod
kylemh Apr 12, 2026
5d0d808
whoopsie
kylemh Apr 12, 2026
9e530fd
re-add Storybook
kylemh Apr 12, 2026
38f4fde
reorganize stories
kylemh Apr 12, 2026
e9a123f
fix disabled checkbox styles
kylemh Apr 12, 2026
1dccc10
fix 404 image
kylemh Apr 12, 2026
28c92cd
empty commit
kylemh Apr 12, 2026
5760791
empty commit
kylemh Apr 12, 2026
ca8a310
attempt to assuage flake
kylemh Apr 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
18 changes: 5 additions & 13 deletions .github/workflows/chromatic.yml
Original file line number Diff line number Diff line change
@@ -1,39 +1,31 @@
# .github/workflows/chromatic.yml

# Workflow name
name: Chromatic

# Event for the workflow
on: push

# List of jobs
jobs:
visual_regression_check:
runs-on: ubuntu-latest

steps:
- name: Begin CI...
uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0

- name: Install pnpm
uses: pnpm/action-setup@v4

- name: Read .nvmrc
run: echo "NODE_VERSION=$(cat .nvmrc)" >> $GITHUB_ENV

- name: Use Node
- name: Setup Node
uses: actions/setup-node@v5
with:
node-version: ${{ env.NODE_VERSION }}
node-version-file: ".nvmrc"
cache: "pnpm"

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Publish to Chromatic
uses: chromaui/action@v1
uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
autoAcceptChanges: main
Expand Down
7 changes: 3 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,6 @@ typings/
.next
out

# storybook build output
.storybook-dist
.storybook-static
storybook-static

# WebStorm Config
.idea
Expand All @@ -99,5 +95,8 @@ tsconfig.tsbuildinfo

# MCP config (local tool settings)
.mcp.json
# Storybook
storybook-static

# next-agents-md
.next-docs/
3 changes: 1 addition & 2 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
node_modules
package.json
pnpm-lock.yaml
.babelrc
**/.babelrc
next-env.d.ts
.next
.github
bin
Expand Down
19 changes: 19 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "base-nova",
"rsc": true,
"tailwind": {
"config": "",
"css": "src/lib/styles/globals.css",
"baseColor": "slate",
"cssVariables": true
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib/utils",
"hooks": "@/lib/hooks"
},
"iconLibrary": "lucide"
}
129 changes: 36 additions & 93 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import tseslint from 'typescript-eslint';
import eslint from '@eslint/js';
import { FlatCompat } from '@eslint/eslintrc';
import eslintPluginUnicorn from 'eslint-plugin-unicorn';
import eslintPluginReact from 'eslint-plugin-react';
import eslintPluginReactHooks from 'eslint-plugin-react-hooks';
import eslintPluginJsxA11y from 'eslint-plugin-jsx-a11y';
import eslintReact from '@eslint-react/eslint-plugin';
import eslintPluginVitest from '@vitest/eslint-plugin';
import eslintPluginImportX from 'eslint-plugin-import-x';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
Expand All @@ -14,16 +12,19 @@ import { getDefaultCallees } from 'eslint-plugin-better-tailwindcss/defaults';
import noBarrelFiles from 'eslint-plugin-no-barrel-files';
import eslintPluginLodash from 'eslint-plugin-lodash';
import eslintPluginPlaywright from 'eslint-plugin-playwright';
import eslintPluginReactHooks from 'eslint-plugin-react-hooks';
import reactYouMightNotNeedAnEffect from 'eslint-plugin-react-you-might-not-need-an-effect';
import eslintPluginStorybook from 'eslint-plugin-storybook';


const compat = new FlatCompat({
baseDirectory: import.meta.dirname,
});

/** @type {import("eslint").Linter.Config['languageOptions']} */
const languageOptions = {
parserOptions: {
project: true,
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
ecmaVersion: 'latest',
Expand All @@ -38,26 +39,14 @@ export default defineConfig(
'.next/**',
'.github/**',
'bin/**',
'static/**',
'cypress-coverage/**',
'vitest-coverage/**',
'src/.storybook/**',
'.storybook-dist/**',
'storybook-static/**',
'playwright-report/**',
'test-results/**',
'public/**',
'src/.storybook/**',
'*.svg',
'vitest.setup.tsx',
'vitest.config.mts',
'prettier.config.js',
'postcss.config.js',
'next-sitemap.config.js',
'next.config.ts',
'next.config.js',
'playwright.config.ts',
'sentry.client.config.js',
'sentry.server.config.js',
]),

// ── Base configs ──
Expand Down Expand Up @@ -98,64 +87,34 @@ export default defineConfig(
},
},

// ── React ──
eslintPluginReact.configs.flat['jsx-runtime'],
// ── React (via @eslint-react) ──
{
plugins: { 'react-hooks': eslintPluginReactHooks },
rules: eslintPluginReactHooks.configs.recommended.rules,
files: ['**/*.{ts,tsx}'],
extends: [eslintReact.configs['recommended-typescript']],
},

// ── React Hooks / React Compiler (compiler-specific rules only; overlaps with @eslint-react disabled) ──
{
files: ['**/*.{ts,tsx,js,jsx}'],
settings: { react: { version: 'detect' } },
files: ['**/*.{ts,tsx}'],
...eslintPluginReactHooks.configs.flat['recommended-latest'],
rules: {
'react/function-component-definition': [
'error',
{
namedComponents: ['arrow-function', 'function-declaration'],
unnamedComponents: ['arrow-function', 'function-expression'],
},
],
'react/forbid-prop-types': ['error', { forbid: ['any'] }],
'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never' }],
'react/jsx-filename-extension': ['error', { extensions: ['.js', '.tsx'] }],
'react/jsx-max-props-per-line': ['error', { maximum: 1, when: 'multiline' }],
'react/no-unescaped-entities': 'off',
'react/jsx-no-target-blank': 'off',
'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }],
'react/jsx-one-expression-per-line': 'off',
'react/jsx-props-no-spreading': 'off',
'react/no-did-mount-set-state': 'off',
'react/no-unused-prop-types': 'error',
'react/no-unused-state': 'error',
'react/prefer-stateless-function': 'off',
'react/react-in-jsx-scope': 'off',
'react/state-in-constructor': ['error', 'never'],
'react/static-property-placement': 'off',
...eslintPluginReactHooks.configs.flat['recommended-latest'].rules,
'react-hooks/rules-of-hooks': 'off',
'react-hooks/exhaustive-deps': 'off',
'react-hooks/use-memo': 'off',
'react-hooks/component-hook-factories': 'off',
'react-hooks/set-state-in-effect': 'off',
'react-hooks/error-boundaries': 'off',
'react-hooks/purity': 'off',
'react-hooks/set-state-in-render': 'off',
'react-hooks/unsupported-syntax': 'off',
},
},

// ── JSX Accessibility ──
eslintPluginJsxA11y.flatConfigs.recommended,
// ── React "You Might Not Need an Effect" ──
{
files: ['**/*.{ts,tsx,js,jsx}'],
rules: {
'jsx-a11y/anchor-is-valid': [
'error',
{
components: ['Link'],
specialLink: ['hrefLeft', 'hrefRight'],
aspects: ['invalidHref', 'preferButton'],
},
],
'jsx-a11y/label-has-associated-control': [
2,
{
labelComponents: ['Label'],
labelAttributes: ['for'],
controlComponents: ['Input', 'Select'],
},
],
},
files: ['**/*.{ts,tsx}'],
...reactYouMightNotNeedAnEffect.configs.recommended,
},

// ── Import-X (replaces eslint-plugin-import) ──
Expand All @@ -173,7 +132,6 @@ export default defineConfig(
json: 'always',
png: 'always',
svg: 'always',
stories: 'always',
},
],
'import-x/no-unresolved': 'off',
Expand Down Expand Up @@ -232,18 +190,15 @@ export default defineConfig(
},
settings: {
'better-tailwindcss': {
entryPoint: './src/common/styles/globals.css',
callees: [...getDefaultCallees(), 'cx', 'cva'],
entryPoint: './src/lib/styles/globals.css',
callees: [...getDefaultCallees(), 'cn', 'cva'],
},
},
},

// ── No Barrel Files ──
noBarrelFiles.flat,

// ── Storybook (flat config) ──
...eslintPluginStorybook.configs['flat/recommended'],

// ── CommonJS files ──
{
files: ['**/*.js'],
Expand Down Expand Up @@ -296,12 +251,6 @@ export default defineConfig(
message:
'Please use named imports of "prop-types".\n Example: "import { func } from \'prop-types\';"',
},
{
name: 'formik',
importNames: ['Form'],
message:
'Please use our Form component to have good defaults defined.\n "import Form from \'@/components/Form/Form\';"',
},
{
name: 'react',
importNames: ['default'],
Expand All @@ -311,13 +260,13 @@ export default defineConfig(
name: 'tailwind-merge',
importNames: ['twMerge'],
message:
'Please import `cx` from `@/common/utils/cva.ts` instead of directly from tailwind-merge.',
'Please import `cn` from `@/lib/utils.ts` instead of directly from tailwind-merge.',
},
{
name: 'class-variance-authority',
importNames: ['cx', 'cva'],
message:
'Please import from `@/common/utils/cva.ts` instead of directly from class-variance-authority.',
'Please import from `@/lib/utils.ts` instead of directly from class-variance-authority.',
},
],
},
Expand All @@ -332,10 +281,6 @@ export default defineConfig(
rules: {
'no-restricted-imports': 'off',

'react/prop-types': 'off',
'react/no-array-index-key': 'off',
'react/require-default-props': 'off',

'@typescript-eslint/consistent-type-imports': 'error',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/naming-convention': [
Expand Down Expand Up @@ -377,12 +322,6 @@ export default defineConfig(
name: 'react-select',
message: 'Please use `@/components/Form/Select/ThemedReactSelect` instead.',
},
{
name: 'formik',
importNames: ['Form'],
message:
'Please use our Form component to have good defaults defined.\n "import { Form } from \'@/components/Form/Form\';"',
},
{
name: 'react',
importNames: ['default'],
Expand All @@ -392,13 +331,13 @@ export default defineConfig(
name: 'tailwind-merge',
importNames: ['twMerge'],
message:
'Please import `cx` from `@/common/utils/cva.ts` instead of directly from tailwind-merge.',
'Please import `cn` from `@/lib/utils.ts` instead of directly from tailwind-merge.',
},
{
name: 'class-variance-authority',
importNames: ['cx', 'cva'],
message:
'Please import from `@/common/utils/cva.ts` instead of directly from class-variance-authority.',
'Please import from `@/lib/utils.ts` instead of directly from class-variance-authority.',
},
],
},
Expand Down Expand Up @@ -448,6 +387,7 @@ export default defineConfig(
files: ['**/*.test.ts', '**/*.test.tsx'],
rules: {
'@typescript-eslint/no-non-null-assertion': 'off',
'@eslint-react/component-hook-factories': 'off',
},
},

Expand All @@ -474,6 +414,9 @@ export default defineConfig(
},
},

// ── Storybook stories ──
...eslintPluginStorybook.configs['flat/recommended'],

// ── Prettier (must be last) ──
eslintPluginPrettierRecommended,
);
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import './.next/types/routes.d.ts';
import "./.next/dev/types/routes.d.ts";

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
13 changes: 8 additions & 5 deletions next-sitemap.config.js → next-sitemap.config.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
const priorities = { '/': '1.00', '/join': '1.00' };
import type { IConfig } from 'next-sitemap';

/** @type {import('next-sitemap').IConfig} */
module.exports = {
// eslint-disable-next-line unicorn/no-zero-fractions
const priorities: Record<string, number> = { '/': 1.0, '/join': 1.0 };

const config: IConfig = {
siteUrl: 'https://www.operationcode.org',
generateIndexSitemap: false, // Simplification to make robots.txt "Sitemap" easier
generateIndexSitemap: false,
priority: 0.8,
changefreq: 'weekly',
// Modified default transform function
transform: async (config, path) => {
return {
loc: path,
Expand All @@ -31,3 +32,5 @@ module.exports = {
'/confirm_email',
],
};

export default config;
Loading
Loading