Skip to content

Commit c2f1c82

Browse files
authored
Redesign (#11)
* docs: Update URL in README * feat: AI Redesign Used Claude Sonnet 4.5 to conduct an entire redesign focusing on a clean UI and legibility. Unit tests also written for many UI components. * test(WhatsNew): Fix tests so they are not too specific
1 parent 1d67471 commit c2f1c82

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+10116
-740
lines changed

README.md

Lines changed: 78 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,92 @@
1-
# Butter_CMS_Utilities
2-
An unofficial collection of client-side utilities for Butter CMS that I found myself needing but aren't available out of the box (yet).
1+
# Butter CMS Utilities
32

4-
## 🎯 Why This Exists
5-
While working with Butter CMS, I needed certain utilities for searching and managing content that surprisingly weren't provided by default. Rather than building these into a larger project or waiting for official tools, I created this simple, no-frills utility page.
3+
An unofficial collection of client-side utilities for Butter CMS. These tools fill gaps in the Butter CMS workflow that are not available out of the box.
64

7-
## 🤖 Why AI?
8-
I used AI to scaffold this project because:
5+
## 🎯 What This Is
96

10-
- I needed a quick, simple tool without the overhead of frameworks
11-
- AI helped me iterate faster on something that's meant to be functional, not fancy
12-
13-
I did have to convert the project to Vue from static HTML/JS/CSS files though so it could scale. The HTML file after 1 feature was getting quite large.
7+
A simple, focused web application that provides utilities for working with Butter CMS content. All operations run entirely in your browser - no servers, no data collection, no third-party tracking.
148

159
## 🔒 Privacy & Security
16-
Important: All utilities run entirely in your browser. No API tokens or data are stored, cached, or transmitted to any third-party servers. Your Butter CMS token is used only for direct API calls to the official Butter CMS API.
10+
11+
**Everything happens in your browser:**
12+
- No API tokens stored on servers
13+
- No usage analytics or tracking
14+
- No server-side logging
15+
- No data shared with third parties
16+
- Your Butter CMS token makes direct API calls to Butter CMS only
17+
- Settings stored locally in your browser's localStorage
18+
19+
**Only requires a read-only API token.** This application never writes or modifies your Butter CMS content.
1720

1821
## 🚀 Usage
19-
Simply visit the GitHub Pages site (https://jackdomleo7.github.io/Butter_CMS_Utilities/) and use the utilities with your Butter CMS API token.
22+
23+
1. Visit [buttercmsutilities.jackdomleo.dev](https://buttercmsutilities.jackdomleo.dev/)
24+
2. Enter your read-only Butter CMS API token
25+
3. Configure your page types and collection keys (optional, for search functionality)
26+
4. Use the utilities
27+
28+
Your configuration is saved locally in your browser for convenience.
2029

2130
## 🛠️ Current Utilities
2231

23-
- **Search Content** - Search for specific content across a given page type, a give collection type, or the entire blog engine
32+
### Search Content
33+
Search for specific content across your Butter CMS account:
34+
- Search across blog posts, page types, and collections simultaneously
35+
- Search for items containing OR NOT containing specific terms
36+
- See exactly where matches were found with context snippets
37+
- Highlighted matches for easy scanning
38+
- Include draft content or published only
39+
40+
## 🔧 Development
41+
42+
Built with:
43+
- **Vue 3** (Composition API with `<script setup>`)
44+
- **TypeScript** (Strict mode)
45+
- **Vite** for lightning-fast development
46+
- **Pinia** for state management
47+
- **SCSS** for styling
48+
- **Vitest** for unit testing
49+
50+
### Setup
51+
52+
```bash
53+
pnpm install
54+
pnpm run dev
55+
```
56+
57+
### Commands
58+
59+
```bash
60+
pnpm run build # Build for production
61+
pnpm run typecheck # TypeScript type checking
62+
pnpm run lint # ESLint with auto-fixes
63+
pnpm run format # Format with Prettier
64+
pnpm run test:unit # Run unit tests
65+
```
66+
67+
## 📝 Contributing
68+
69+
Contributions welcome! Please ensure:
70+
71+
```bash
72+
pnpm run typecheck # Must pass with 0 errors
73+
pnpm run lint # Must pass with 0 errors
74+
pnpm run format # Format all code
75+
pnpm run test:unit # All tests must pass
76+
```
77+
78+
**Quality Standards:**
79+
- Test coverage: 90%+ (current: 94.8%)
80+
- TypeScript strict mode with no `any` types
81+
- Accessible (WCAG AA 2.2)
82+
- Follows existing component patterns
83+
84+
See [agents.md](agents.md) for detailed coding guidelines.
85+
86+
## 📄 License
2487

25-
## 📝 License
2688
MIT - Feel free to use, modify, and share!
2789

28-
---
90+
## ⚠️ Disclaimer
2991

30-
Note: This is an unofficial tool and is not affiliated with or endorsed by Butter CMS.
92+
This is an unofficial tool and is not affiliated with or endorsed by Butter CMS.

agents.md

Lines changed: 150 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -26,80 +26,185 @@ pnpm run test:unit # Run Vitest (add file path for specific tests)
2626

2727
## Core Coding Principles
2828

29-
- **Always use `<script setup lang="ts">`** for Vue components
30-
- **PascalCase filenames** (e.g., `SearchItem.vue`)
31-
- **Props:** `defineProps<{ ... }>()` with full types; **Events:** `defineEmits<{ ... }>()` with camelCase names
32-
- **No `any`** - use `unknown` or interfaces from `@/types.ts`
33-
- **No Options API** - never use `data()`, `methods`, or `computed()` outside `<script setup>`
34-
- **Don't mutate props** - emit events to parent instead
35-
- **Reactivity:** `ref()` for primitives/arrays, `reactive()` only for complex objects, `computed()` for derived state
36-
- **Use `v-memo`** on `v-for` lists to prevent unnecessary re-renders
37-
- **Keep components focused** - single responsibility
29+
**Vue Components:**
30+
- Always use `<script setup lang="ts">` with Composition API
31+
- PascalCase filenames (e.g. `SearchContent.vue`)
32+
- Full prop types: `defineProps<{ ... }>()`
33+
- Emit events with camelCase names: `defineEmits<{ ... }>()`
34+
- Never mutate props - emit events to parent instead
35+
36+
**TypeScript:**
37+
- Strict mode enabled - no `any` types
38+
- Use type inference where clear, explicit types for props/interfaces
39+
- Prefer `unknown` over `any` for truly dynamic values
40+
41+
**Reactivity:**
42+
- `ref()` for primitives and arrays
43+
- `reactive()` only for complex objects
44+
- `computed()` for derived state
45+
- `v-memo` on `v-for` lists to optimize re-renders
46+
47+
**Component Design:**
48+
- Single responsibility principle
49+
- Reuse existing components before creating new ones
3850

3951
---
4052

41-
## State Management
53+
## Design System
54+
55+
All design tokens are defined in [_variables.scss](src/assets/styles/_variables.scss) and [_colors.scss](src/assets/styles/_colors.scss).
56+
57+
**Use CSS custom properties (not SCSS variables):** `--font-size-*`, `--space-*`, `--gray-*`, `--text-*`, `--bg-*`, `--border-*`, `--radius-*`, `--shadow-*`, `--transition-*`
58+
59+
**Font weights:** Hardcode directly: 400 (normal), 500 (medium), 600 (semibold)
60+
61+
**Color strategy:**
62+
- Primary palette: Neutral grays (`--gray-50` through `--gray-900`)
63+
- Links: `--accent-blue` (#0505e5)
64+
- Highlights: `--accent-yellow` (#fbe700) - use sparingly
65+
- All text must meet WCAG AA contrast standards
66+
67+
**SCSS:** Only use for breakpoints, mixins, or computed values where CSS custom properties can't work
68+
69+
---
70+
71+
## Component Library
72+
73+
Always use existing components before creating new ones. Key components:
74+
75+
- **Btn.vue** - Button with loading state, status variants (primary/secondary/tertiary)
76+
- **TextInput.vue** - Input with validation, native HTML icons (✘/✔)
77+
- **Toggle.vue** - Binary switch (role="switch") with keyboard support
78+
- **Accordion.vue** - Collapsible `<details>` with CSS Grid animation
79+
- **Card.vue** - Content wrapper with `skeleton` prop for loading states
80+
- **Chip.vue** - Badge/tag with optional close button
81+
- **InfoBanner.vue** - Status messages (info/warning/error/success)
82+
- **Modal.vue** - Dialog with focus trap, `aria-modal`
83+
- **ApiConfiguration.vue** - Accordion with token input, page types, collections, draft toggle
4284

43-
Uses **Pinia** with **localStorage** for persistence:
85+
### Component Patterns
4486

87+
**Toggle vs Checkbox:**
88+
- Single binary choice (yes/no, on/off) → **Toggle**
89+
- Multiple independent selections → **Checkbox**
90+
- Example: Draft content = Toggle, Blog/Page Types = Checkboxes
91+
92+
**Card Component:**
93+
- Skeleton loading: `<Card :skeleton="true" />` (show 3-5 during load)
94+
- Results: `<Card>` wrapper with content slot
95+
96+
**Lazy Loading:**
97+
- Use `defineAsyncComponent()` for Card, Modal, WhatsNew (loaded conditionally)
98+
- SearchContent and ComingSoon are synchronous (rendered immediately)
99+
100+
---
101+
102+
## State Management
103+
104+
**Pinia** with **localStorage** persistence:
45105
1. App loads → hydrates from `localStorage.butter_cms_config`
46-
2. User updates config → Pinia watchers save changes to localStorage
47-
3. Components access via store computed properties
106+
2. User updates config → watchers save to localStorage
107+
3. Store has single `config` ref with deep watchers
48108

49-
```typescript
50-
import { useStore } from '@/stores'
109+
**Important:** Maintain backwards compatibility for localStorage schemas
51110

52-
const store = useStore()
53-
store.token = 'new_token' // Auto-persists to localStorage
54-
```
111+
---
112+
113+
## Error Handling Pattern
55114

56-
Store structure: Single `config` ref with deep watchers. Cleans up `selectedScopes` when page types/collection keys are deleted.
115+
**Search Content:**
116+
- Try-catch per scope (blog/page type/collection)
117+
- Log failures: `console.error("Failed to fetch page type 'X':", error)`
118+
- Continue with successful scopes
119+
- Return `failedScopes` array for UI display
120+
- Only return `success: false` if ALL scopes fail
57121

58-
**Important:** Maintain backwards compatibility when adding new config properties—users may have old localStorage schemas.
122+
Reference: [searchContent.ts](src/features/searchContent.ts)
59123

60124
---
61125

62-
## Conventional Commits
126+
## Branding & Content
63127

64-
Format: `<type>(<scope>): <subject>`
128+
- **Tagline:** "I can't believe it's not Butter CMS!" (keep for personality)
129+
- **Tone:** Professional, helpful, concise
130+
- **Privacy:** Emphasize client-side execution, zero data collection
131+
- **No AI mentions** - removed for professional positioning
65132

66-
Types: `feat`, `fix`, `refactor`, `perf`, `test`, `docs`, `style`, `chore`
133+
---
67134

68-
Examples:
69-
```
70-
feat(search): add filter by date range
71-
fix(store): persist collection keys to localStorage
72-
test(searchContent): add unit tests for filtering
73-
```
135+
## Testing Patterns
136+
137+
**General Guidelines:**
138+
- Aim for 90%+ test coverage
139+
- Focus on meaningful tests over coverage numbers
140+
- Test user interactions, not implementation details
141+
142+
**TypeScript in Tests:**
143+
- Avoid explicit `any` types - use type inference
144+
- For component internals, create typed interfaces:
145+
```typescript
146+
interface ComponentInstance extends ComponentPublicInstance {
147+
store: ReturnType<typeof useStore>
148+
internalProp: string
149+
}
150+
const getVm = (wrapper: ReturnType<typeof mount>) =>
151+
wrapper.vm as ComponentInstance
152+
```
153+
154+
**Non-Null Assertions:**
155+
- Use `!` when you're certain an element exists:
156+
```typescript
157+
const button = wrapper.find('.my-button')!
158+
```
159+
- Only use when test context guarantees existence
160+
161+
**Common Patterns:**
162+
- Test component rendering, props, events, and state
163+
- Use `await wrapper.vm.$nextTick()` after state changes
164+
- Mock external dependencies (APIs, localStorage, etc.)
165+
- Test accessibility attributes (aria-label, role, etc.)
74166

75167
---
76168

77169
## Quality Standards
78170

79-
- **Accessibility:** Must be high—use semantic HTML and ARIA where appropriate
80-
- **@src/core coverage:** Minimum **98%+ unit test coverage** with meaningful tests covering multiple scenarios
81-
- **Component reuse:** Always use existing components from `@/components` (`Btn.vue`, `TextInput.vue`, `Modal.vue`, `InfoBanner.vue`, `Chip.vue`, etc) instead of creating new HTML/CSS
82-
- **WhatsNew.vue:** Displays changelog to users on revisit. Add new features to the `features` array with `utcDatetimeAdded` timestamps. Modal auto-shows only new items based on `butter_cms_last_visit` localStorage key.
171+
- **Accessibility:** WCAG AA 2.2, semantic HTML, proper ARIA, 24x24px minimum touch targets
172+
- **Test coverage:** 90%+ overall with focus on core business logic
173+
- **Component reuse:** Always use existing components before creating new HTML/CSS
174+
- **Design consistency:** Follow design system tokens consistently
175+
- **Functional minimalism:** Clean, focused UI prioritizing content legibility
83176

84177
---
85178

86-
## For AI Agents: Auto-Update This File When You:
179+
## WhatsNew.vue Pattern
87180

88-
- Add new core features
89-
- Change tech stack or major dependencies
90-
- Establish new coding conventions or patterns
91-
- Modify state management or API structure
92-
- Change project structure
181+
Add new features to `features` array with `utcDatetimeAdded` timestamps. Modal auto-shows based on `butter_cms_last_visit` localStorage key.
93182

94-
**Do NOT update for:** bug fixes, minor refactors, or individual component changes.
183+
---
184+
185+
## Conventional Commits
186+
187+
Format: `<type>(<scope>): <subject>`
188+
189+
Types: `feat`, `fix`, `refactor`, `perf`, `test`, `docs`, `style`, `chore`
95190

96191
---
97192

98-
## Before Submitting Changes
193+
## Before Submitting
99194

100195
```bash
101-
pnpm run typecheck # Verify type safety
102-
pnpm run lint # Fix linting issues
103-
pnpm run format # Format code
104-
pnpm run test:unit # Run tests (especially @src/core with 98%+ coverage)
196+
pnpm run typecheck # Must pass with 0 errors
197+
pnpm run lint # Must pass with 0 errors
198+
pnpm run format # Format all code
199+
pnpm run test:unit # All tests must pass (585+ tests)
105200
```
201+
202+
**All commands must pass without errors.** Do not commit code with TypeScript or linting violations.
203+
204+
---
205+
206+
## For Maintainers
207+
208+
Update this file when you: add core features/components, change tech stack, establish new patterns, modify state management, or update design system.
209+
210+
**Do NOT update for:** bug fixes, minor refactors, or individual component changes.

0 commit comments

Comments
 (0)