diff --git a/.env.sample b/.env.sample deleted file mode 100644 index 58b5fd7..0000000 --- a/.env.sample +++ /dev/null @@ -1,2 +0,0 @@ -PATREON_CREATOR_ACCESS_TOKEN="Check 1Password" -PATREON_CAMPAIGN_ID="Check 1Password" diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index b0d9e93..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,14 +0,0 @@ -# To get started with Dependabot version updates, you'll need to specify which -# package ecosystems to update and where the package manifests are located. -# Please see the documentation for all configuration options: -# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - -version: 2 -updates: - - package-ecosystem: "npm" # See documentation for possible values - directory: "/" # Location of package manifests - schedule: - interval: "daily" - open-pull-requests-limit: 10 - cooldown: - default_days: 7 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 765df35..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,100 +0,0 @@ -name: Build and Deploy - -on: - push: - branches: [ main ] - pull_request: - types: [opened, synchronize, reopened] - schedule: - - cron: '0 11 * * *' - workflow_dispatch: - -env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - S3_BUCKET: "${{ secrets.S3_BUCKET }}" - CLOUDFRONT_ID: ${{ secrets.CLOUDFRONT_ID }} - PATREON_CREATOR_ACCESS_TOKEN: ${{ secrets.PATREON_CREATOR_ACCESS_TOKEN }} - PATREON_CAMPAIGN_ID: ${{ secrets.PATREON_CAMPAIGN_ID }} - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - - name: Use Node.js 24.x - uses: actions/setup-node@v3 - with: - node-version: 24.x - cache: 'npm' - - - name: Cache node modules - id: cache-npm - uses: actions/cache@v4 - env: - cache-name: cache-node-modules - with: - # npm cache files are stored in `~/.npm` on Linux/macOS - path: ~/.npm - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- - - - name: Cache Next.js build - id: cache-nextjs - uses: actions/cache@v4 - with: - # See here for caching with `yarn`, `bun` or other package managers https://github.com/actions/cache/blob/main/examples.md or you can leverage caching with actions/setup-node https://github.com/actions/setup-node - path: | - ~/.npm - ${{ github.workspace }}/.next/cache - # Generate a new cache whenever packages or source files change. - key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} - # If source files changed but packages didn't, rebuild from a prior cache. - restore-keys: | - ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- - - - run: npm ci - - - run: npm run build - - - name: Archive site as artifact - uses: actions/upload-artifact@v4 - with: - name: out - path: out - - - name: Archive s3_website.yml as artifact - uses: actions/upload-artifact@v4 - with: - name: s3_website - path: s3_website.yml - - deploy: - runs-on: ubuntu-latest - needs: build - if: contains(github.ref, 'main') - steps: - - name: Retrieve site from artifacts - uses: actions/download-artifact@v4 - with: - name: out - path: out - - - name: Retrieve s3_website.yml from artifacts - uses: actions/download-artifact@v4 - with: - name: s3_website - path: s3_website - - - name: Move s3_website.yml into root - run: | - mv s3_website/s3_website.yml s3_website.yml - - - name: S3 Publish - uses: docker://justinharringa/s3_website:master - with: - args: 'push --site out' diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml deleted file mode 100644 index 3578dec..0000000 --- a/.github/workflows/chromatic.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: 'Chromatic' - -on: - push: - branches: - - main - pull_request: - -jobs: - chromatic: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 24.x - cache: 'npm' - - - name: Install dependencies - run: npm ci - - - name: Run Chromatic - uses: chromaui/action@latest - with: - projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} - exitOnceUploaded: true \ No newline at end of file diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 8a22d47..0000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Lint - -on: - push: - branches: [ main ] - pull_request: - types: [opened, synchronize, reopened] - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - - name: Use Node.js 24.x - uses: actions/setup-node@v3 - with: - node-version: 24.x - cache: 'npm' - - - name: Cache node modules - id: cache-npm - uses: actions/cache@v4 - env: - cache-name: cache-node-modules - with: - # npm cache files are stored in `~/.npm` on Linux/macOS - path: ~/.npm - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- - - - run: npm ci - - - run: npm run lint \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 17c254a..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Test - -on: - push: - branches: [ main ] - pull_request: - types: [opened, synchronize, reopened] - -env: - PATREON_CREATOR_ACCESS_TOKEN: ${{ secrets.PATREON_CREATOR_ACCESS_TOKEN }} - PATREON_CAMPAIGN_ID: ${{ secrets.PATREON_CAMPAIGN_ID }} - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v5 - - - name: Use Node.js 24.x - uses: actions/setup-node@v3 - with: - node-version: 24.x - cache: 'npm' - - - name: Cache node modules - id: cache-npm - uses: actions/cache@v4 - env: - cache-name: cache-node-modules - with: - # npm cache files are stored in `~/.npm` on Linux/macOS - path: ~/.npm - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- - - - run: npm ci - - - run: npm run test \ No newline at end of file diff --git a/.gitignore b/.gitignore index 495178b..d8c256c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,39 +1,42 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build +*.rbc +capybara-*.html +.rspec +/log +/tmp +/db/*.sqlite3 +/db/*.sqlite3-journal +/public/system +/coverage/ +/spec/tmp +**.orig +rerun.txt +pickle-email-*.html + +# TODO Comment out these rules if you are OK with secrets being uploaded to the repo +config/initializers/secret_token.rb +config/secrets.yml + +# dotenv +# TODO Comment out this rule if environment variables can be committed +.env -# misc -.DS_Store -*.pem +## Environment normalization: +/.bundle +/vendor/bundle -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.pnpm-debug.log* +# these should all be checked in to normalize the environment: +# Gemfile.lock, .ruby-version, .ruby-gemset -# local env files -.env -.env*.local +# unless supporting rvm < 1.11.0 or doing something fancy, ignore this: +.rvmrc -# vercel -.vercel +# if using bower-rails ignore default bower_components path bower.json files +/vendor/assets/bower_components +*.bowerrc +bower.json -# JetBrains IDEs -.idea +# Ignore pow environment settings +.powenv -storybook-static -build-storybook.log \ No newline at end of file +# Ignore Byebug command history file. +.byebug_history diff --git a/.storybook/decorators/withMockScenario.jsx b/.storybook/decorators/withMockScenario.jsx deleted file mode 100644 index b9f74e6..0000000 --- a/.storybook/decorators/withMockScenario.jsx +++ /dev/null @@ -1,37 +0,0 @@ -import { setMockScenario, resetMockScenario } from '../../src/api/__mocks__/mockDataManager' -import { useEffect } from 'react' - -/** - * Wrapper component that uses hooks to manage mock scenario - */ -function MockScenarioWrapper({ scenario, children }) { - useEffect(() => { - setMockScenario(scenario) - return () => resetMockScenario() - }, [scenario]) - - // Also set it immediately for server component rendering - setMockScenario(scenario) - - return children -} - -/** - * Storybook decorator that sets the mock data scenario before rendering - * - * Usage in stories: - * export const MyStory = { - * parameters: { - * mockScenario: 'fewEpisodes' - * } - * } - */ -export const withMockScenario = (Story, context) => { - const scenario = context.parameters.mockScenario || 'default' - - return ( - - - - ) -} diff --git a/.storybook/main.js b/.storybook/main.js deleted file mode 100644 index 3858ece..0000000 --- a/.storybook/main.js +++ /dev/null @@ -1,46 +0,0 @@ -// This file has been automatically migrated to valid ESM format by Storybook. -import { fileURLToPath } from "node:url"; -import { dirname } from "node:path"; -import { createRequire } from "node:module"; -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); -const require = createRequire(import.meta.url); -const webpack = require('webpack'); -const path = require('path'); - -/** @type { import('@storybook/nextjs').StorybookConfig } */ -const config = { - stories: [ - '../src/**/*.mdx', - '../src/stories/**/*.stories.@(js|jsx|mjs|ts|tsx)', - '../src/components/**/*.stories.@(js|jsx|mjs|ts|tsx)' - ], - addons: ['@storybook/addon-links', '@storybook/addon-docs'], - framework: { - name: '@storybook/nextjs', - options: {}, - }, - features: { - experimentalRSC: true, - }, - docs: {}, - staticDirs: ['../public'], - webpackFinal: async (config) => { - // Use NormalModuleReplacementPlugin to replace API modules with mocks - config.plugins.push( - new webpack.NormalModuleReplacementPlugin( - /^@\/api\/episodes$/, - path.resolve(__dirname, '../src/api/__mocks__/episodes.js') - ) - ); - config.plugins.push( - new webpack.NormalModuleReplacementPlugin( - /^@\/api\/patrons$/, - path.resolve(__dirname, '../src/api/__mocks__/patrons.js') - ) - ); - - return config - }, -} -export default config diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html deleted file mode 100644 index a9f6c62..0000000 --- a/.storybook/preview-head.html +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/.storybook/preview.js b/.storybook/preview.js deleted file mode 100644 index 990eff3..0000000 --- a/.storybook/preview.js +++ /dev/null @@ -1,39 +0,0 @@ -import '../src/styles/tailwind.css' -import 'focus-visible' -import { withMockScenario } from './decorators/withMockScenario' - -// Set up module mocks for API calls -if (typeof jest !== 'undefined') { - jest.mock('@/api/episodes') - jest.mock('@/api/patrons') -} - -/** @type { import('@storybook/nextjs').Preview } */ -const preview = { - parameters: { - actions: { argTypesRegex: '^on[A-Z].*' }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - backgrounds: { - options: { - light: { name: 'light', value: '#ffffff' }, - dark: { name: 'dark', value: '#1a1a1a' }, - "brand-yellow": { name: 'brand-yellow', value: '#ffde59' } - } - }, - }, - - initialGlobals: { - backgrounds: { - value: 'light' - } - }, - - decorators: [withMockScenario], -} - -export default preview diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 225f2e2..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,76 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Project Overview - -This is the website for the Legacy Code Rocks community and podcast, built with Next.js 13, Tailwind CSS, and Storybook. The site is based on the Transmit template from Tailwind UI. - -## Essential Commands - -### Development -- `npm run dev` - Start Next.js development server (port 3000) -- `npm run storybook` - Start Storybook development server (port 6006) - -### Build & Deploy -- `npm run build` - Build static site (configured with `output: 'export'`) -- `npm run build-storybook` - Build Storybook for deployment - -### Quality -- `npm run lint` - Run ESLint -- `npm run chromatic` - Deploy to Chromatic for visual regression testing - -### Dependencies -- `npm install` - Install all dependencies - -## Architecture - -### Static Site Export -The site uses Next.js static export (`output: 'export'` in next.config.js). This means: -- All pages are pre-rendered at build time -- Images are unoptimized (`images.unoptimized: true`) -- Dynamic routes must be generated via `getStaticPaths` - -### Data Fetching -- **Episodes**: Fetched from Libsyn RSS feed (https://feeds.libsyn.com/82186/rss) in src/api/episodes.js -- **Patrons**: Fetched from Patreon API using PATREON_CREATOR_ACCESS_TOKEN and PATREON_CAMPAIGN_ID env vars in src/api/patrons.js -- Episodes are paginated with 10 per page (EPISODES_PER_PAGE constant) - -### Audio Player Architecture -The audio player uses a global context-based architecture: -- **AudioProvider** (src/components/AudioProvider.jsx): Context provider with reducer pattern managing player state (playing, muted, duration, currentTime, meta) -- **useAudioPlayer** hook: Provides player controls bound to specific episode data -- Player state is shared globally but can control different episodes -- Actual HTML5 `