- Phase 5: Change line number to structural reference (before closing brace) - Fix all TypeScript build commands from 'npm run build' to 'npm run build:ts' - Ensures plan aligns with actual package.json scripts - Prevents execution failures during implementation
1051 lines
32 KiB
Markdown
1051 lines
32 KiB
Markdown
# Wood Paneling & Full-Width Layout Implementation
|
|
|
|
## Problem Statement
|
|
|
|
The current "wood themes" were implemented as color themes with CSS gradients, but they should be wood paneling textures applied to the dashboard bookshelf background only. Additionally, the app uses constrained width containers (`max-w-7xl`) which limit screen real estate on large monitors, unlike modern bookshelf apps like Audiobookshelf.
|
|
|
|
## Implementation Principles
|
|
|
|
### Critical Requirements
|
|
- ✅ **All JavaScript must be TypeScript** - No inline scripts (use separate .ts files)
|
|
- ✅ **Use TailwindCSS only** - No custom CSS, use CSS variables already defined in `input.css`
|
|
- ✅ **Post-edit verification mandatory** - Run build after each file edit
|
|
- ✅ **Sequential git commits** - No `&&` chaining, explicit verification between commands
|
|
- ✅ **Document user-facing changes** - Update `docs/user/` for new features
|
|
|
|
## Root Cause Analysis
|
|
|
|
### Current Implementation Issues
|
|
|
|
1. **Wood themes are misimplemented:**
|
|
- Wood themes (`wood-light`, `wood-dark`, `wood-mahogany`) are in the theme dropdown alongside color themes
|
|
- Applied via CSS gradients in `header.ts` `changeThemeTo()`
|
|
- Gradients applied to entire `<body>` instead of just bookshelf background
|
|
- Not integrated with `theme.ts` `applyTheme()` function
|
|
|
|
2. **Constrained layout:**
|
|
- Header uses `max-w-7xl mx-auto` container
|
|
- Dashboard content uses `max-w-7xl mx-auto` container
|
|
- Other pages use `max-w-7xl mx-auto` containers
|
|
- Wastes horizontal space on large monitors
|
|
|
|
3. **No active indicators:**
|
|
- Theme dropdown doesn't show which theme/wood option is currently active
|
|
- Users can't tell what's selected without remembering
|
|
|
|
## Solution Strategy
|
|
|
|
### Approach: Separate Concerns
|
|
|
|
**Principle:** Wood paneling is a visual treatment for the bookshelf, not a color theme. It should be:
|
|
- Separate from color themes
|
|
- Applied only to `#collections-container` on dashboard
|
|
- Stored in localStorage (not database)
|
|
- User-selectable from theme dropdown (but sectioned separately)
|
|
|
|
**Layout principle:** Full-width layout for modern app feel, better space utilization.
|
|
|
|
**CSS Variable Principle:** Use CSS variables already defined in `web/static/input.css` (`--bg-primary`, `--bg-secondary`, etc.) instead of inline styles.
|
|
|
|
## Git Commit Strategy
|
|
|
|
**CRITICAL:** All git commands must be run sequentially (no `&&` chaining):
|
|
1. `git add <files>` - Wait for completion
|
|
2. `git commit -m "<message>"` - Wait for completion
|
|
3. Verify commit succeeded before proceeding
|
|
|
|
**Post-Edit Verification (MANDATORY):**
|
|
- After each file edit: Run `go build ./...` for Go files, `npm run build:ts` for TypeScript
|
|
- Review `git diff` to verify only intended changes
|
|
- Never proceed to next file until current edit compiles successfully
|
|
|
|
## Implementation Plan
|
|
|
|
### Phase 0: Download Wood Textures (Manual)
|
|
|
|
**Source URLs:**
|
|
|
|
1. **Light Wood:** https://opengameart.org/content/light-wood-1024x1024
|
|
- Author: qubodup
|
|
- License: CC0 (no attribution required)
|
|
- File: qubodup-light_wood.png (1.9 MB)
|
|
- Resolution: 1024x1024
|
|
|
|
2. **Dark & Mahogany Wood:** https://opengameart.org/content/5-wood-textures
|
|
- Author: Luke.RUSTLTD
|
|
- License: CC0 (no attribution required)
|
|
- File: wood_0.zip (6.5 MB) - contains 5 textures
|
|
- Select 2 best: darkest and medium/reddish
|
|
- Resolution: Likely 512x512 or 1024x1024
|
|
|
|
**Download Steps:**
|
|
|
|
```bash
|
|
# Create textures directory
|
|
mkdir -p web/static/textures
|
|
|
|
# Download light wood
|
|
cd web/static/textures
|
|
curl -O https://opengameart.org/sites/default/files/qubodup-light_wood.png
|
|
mv qubodup-light_wood.png wood-light.png
|
|
|
|
# Download texture pack (dark & mahogany)
|
|
cd /tmp
|
|
curl -O https://opengameart.org/sites/default/files/wood_0.zip
|
|
unzip wood_0.zip
|
|
|
|
# Select and copy best 2 textures (you'll need to review and choose)
|
|
# Copy selected ones to web/static/textures/wood-dark.png
|
|
# Copy selected ones to web/static/textures/wood-mahogany.png
|
|
```
|
|
|
|
**Manual Steps:**
|
|
1. Extract `wood_0.zip`
|
|
2. Review the 5 textures
|
|
3. Select darkest → rename to `wood-dark.png`
|
|
4. Select medium/reddish → rename to `wood-mahogany.png`
|
|
5. Move both to `web/static/textures/`
|
|
|
|
**Optional Optimization:**
|
|
```bash
|
|
# Use ImageOptim (Mac) or FileOptimizer (Windows/Linux)
|
|
# Or use online: TinyPNG.com
|
|
# Goal: Keep each under 500 KB for fast loading
|
|
```
|
|
|
|
**Final Files:**
|
|
- `web/static/textures/wood-light.png`
|
|
- `web/static/textures/wood-dark.png`
|
|
- `web/static/textures/wood-mahogany.png`
|
|
|
|
---
|
|
|
|
### Phase 1: Remove Wood Themes from Core Theme System
|
|
|
|
**Goal:** Remove wood themes from the core theme system to prepare for separate wood paneling feature.
|
|
|
|
#### Files to Modify:
|
|
|
|
**1. `web/src/theme.ts`**
|
|
- Remove `wood-light`, `wood-dark`, `wood-mahogany` from `ThemeType` union (lines 15-17)
|
|
- Remove wood theme gradient logic from `applyTheme()` function (lines 26-46)
|
|
- Keep only regular theme handling
|
|
|
|
**Before (theme.ts):**
|
|
```typescript
|
|
type ThemeType =
|
|
| 'tokyo-night'
|
|
| 'dracula'
|
|
// ... other themes
|
|
| 'wood-light'
|
|
| 'wood-dark'
|
|
| 'wood-mahogany';
|
|
```
|
|
|
|
**After (theme.ts):**
|
|
```typescript
|
|
type ThemeType =
|
|
| 'tokyo-night'
|
|
| 'dracula'
|
|
// ... other themes (remove wood themes);
|
|
```
|
|
|
|
**Before (applyTheme function):**
|
|
```typescript
|
|
const applyTheme = (theme: string): void => {
|
|
// Handle wood themes with gradients
|
|
if (theme.startsWith('wood-')) {
|
|
document.body.className = `theme-${theme}`;
|
|
// ... wood gradient logic
|
|
} else {
|
|
// Apply regular theme
|
|
document.body.className = `theme-${theme}`;
|
|
document.body.style.background = '';
|
|
document.body.style.backgroundSize = '';
|
|
document.body.style.backgroundAttachment = '';
|
|
}
|
|
localStorage.setItem(THEME_STORAGE_KEY, theme);
|
|
};
|
|
```
|
|
|
|
**After (applyTheme function):**
|
|
```typescript
|
|
const applyTheme = (theme: string): void => {
|
|
// Apply regular theme only
|
|
document.body.className = `theme-${theme}`;
|
|
document.body.style.background = '';
|
|
document.body.style.backgroundSize = '';
|
|
document.body.style.backgroundAttachment = '';
|
|
localStorage.setItem(THEME_STORAGE_KEY, theme);
|
|
};
|
|
```
|
|
|
|
**2. `tailwind.config.ts`**
|
|
- Remove `theme-wood-light`, `theme-wood-dark`, `theme-wood-mahogany` from safelist (lines 21-23)
|
|
|
|
**Before:**
|
|
```typescript
|
|
safelist: [
|
|
'theme-tokyo-night',
|
|
// ... other themes
|
|
'theme-wood-light',
|
|
'theme-wood-dark',
|
|
'theme-wood-mahogany',
|
|
]
|
|
```
|
|
|
|
**After:**
|
|
```typescript
|
|
safelist: [
|
|
'theme-tokyo-night',
|
|
// ... other themes (remove wood theme entries)
|
|
]
|
|
```
|
|
|
|
**3. `web/static/input.css`**
|
|
- Remove `.theme-wood-light`, `.theme-wood-dark`, `.theme-wood-mahogany` blocks (lines 115-140)
|
|
|
|
#### Verification Steps:
|
|
```bash
|
|
# Build TypeScript
|
|
npm run build:ts
|
|
|
|
# Verify: Build succeeds with no TypeScript errors
|
|
# Verify: No references to wood themes remain in theme.ts
|
|
```
|
|
|
|
#### Git Commit:
|
|
```bash
|
|
git add web/src/theme.ts
|
|
git commit -m "refactor(theme): remove wood themes from core theme system
|
|
|
|
- Remove wood-light, wood-dark, wood-mahogany from ThemeType
|
|
- Remove wood theme gradient logic from applyTheme()
|
|
- Wood themes will be reimplemented as separate paneling feature
|
|
- Paneling will target dashboard bookshelf background only"
|
|
```
|
|
|
|
```bash
|
|
git add tailwind.config.ts
|
|
git commit -m "refactor(tailwind): remove wood themes from safelist
|
|
|
|
- Remove theme-wood-light, theme-wood-dark, theme-wood-mahogany
|
|
- Wood themes no longer exist as color themes"
|
|
```
|
|
|
|
```bash
|
|
git add web/static/input.css
|
|
git commit -m "refactor(css): remove wood theme CSS variables
|
|
|
|
- Remove .theme-wood-light, .theme-wood-dark, .theme-wood-mahogany
|
|
- Wood paneling will use separate background utilities"
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 1b: Remove Wood Themes from Profile Form
|
|
|
|
**Goal:** Remove wood theme options from profile settings form since wood paneling will be browser-only.
|
|
|
|
#### File: `templates/profile_form.templ`
|
|
|
|
**Remove lines 55-57 (wood theme options):**
|
|
|
|
```templ
|
|
<!-- Before -->
|
|
<option value="wood-light" selected?={user.Theme == "wood-light"}>Wood Light</option>
|
|
<option value="wood-dark" selected?={user.Theme == "wood-dark"}>Wood Dark</option>
|
|
<option value="wood-mahogany" selected?={user.Theme == "wood-mahogany"}>Wood Mahogany</option>
|
|
|
|
<!-- After (remove these 3 lines) -->
|
|
```
|
|
|
|
**Rationale:** Wood paneling is a browser preference (localStorage only), not a server-synced theme. Users will control wood paneling from the header dropdown's "Bookshelf Background" section, not profile settings.
|
|
|
|
#### Verification Steps:
|
|
```bash
|
|
# Build Go templates
|
|
go build ./...
|
|
|
|
# Verify: Build succeeds with no template errors
|
|
# Verify: Wood options removed from profile theme dropdown
|
|
```
|
|
|
|
#### Git Commit:
|
|
```bash
|
|
git add templates/profile_form.templ
|
|
git commit -m "refactor(profile): remove wood themes from profile settings
|
|
|
|
- Remove wood-light, wood-dark, wood-mahogany from theme dropdown
|
|
- Wood paneling is now browser-only (localStorage preference)
|
|
- Users select wood paneling from header dropdown, not profile
|
|
- Profile form only controls server-synced color themes"
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 2: Create Wood Paneling TypeScript Module
|
|
|
|
**Goal:** Create separate wood paneling preference system using localStorage and Tailwind classes.
|
|
|
|
#### New File: `web/src/woodPaneling.ts`
|
|
|
|
```typescript
|
|
// Wood paneling management functionality
|
|
|
|
type WoodPanelingType = 'none' | 'wood-light' | 'wood-dark' | 'wood-mahogany';
|
|
|
|
const WOOD_STORAGE_KEY = 'wood-paneling';
|
|
|
|
// Apply wood paneling to collections container
|
|
const applyWoodPaneling = (paneling: WoodPanelingType): void => {
|
|
const container = document.getElementById('collections-container');
|
|
if (!container) return;
|
|
|
|
// Remove all wood background classes
|
|
container.classList.remove('bg-wood-light', 'bg-wood-dark', 'bg-wood-mahogany');
|
|
|
|
if (paneling !== 'none') {
|
|
// Add selected wood background class
|
|
container.classList.add(`bg-${paneling}`);
|
|
}
|
|
|
|
// Save to localStorage
|
|
localStorage.setItem(WOOD_STORAGE_KEY, paneling);
|
|
};
|
|
|
|
// Load wood paneling from localStorage on page load
|
|
const loadWoodPaneling = (): void => {
|
|
const stored = localStorage.getItem(WOOD_STORAGE_KEY) as WoodPanelingType | null;
|
|
if (stored) {
|
|
applyWoodPaneling(stored);
|
|
} else {
|
|
// Default to none
|
|
applyWoodPaneling('none');
|
|
}
|
|
};
|
|
|
|
// Change wood paneling (called from theme dropdown)
|
|
const changeWoodPaneling = (paneling: WoodPanelingType): void => {
|
|
applyWoodPaneling(paneling);
|
|
|
|
// Update active indicators
|
|
updateWoodPanelingIndicators();
|
|
|
|
// Close dropdown
|
|
const dropdown = document.getElementById('theme-dropdown');
|
|
if (dropdown) {
|
|
dropdown.classList.add('hidden');
|
|
}
|
|
};
|
|
|
|
// Update visual indicators for wood paneling buttons
|
|
const updateWoodPanelingIndicators = (): void => {
|
|
const currentWood = localStorage.getItem(WOOD_STORAGE_KEY) || 'none';
|
|
|
|
// Update wood paneling buttons
|
|
document.querySelectorAll('.wood-paneling-btn').forEach(btn => {
|
|
const wood = btn.getAttribute('data-wood');
|
|
if (wood === currentWood) {
|
|
// Active state - use CSS class instead of inline style
|
|
btn.classList.add('bg-wood-active');
|
|
btn.classList.remove('bg-wood-inactive');
|
|
} else {
|
|
// Inactive state
|
|
btn.classList.remove('bg-wood-active');
|
|
btn.classList.add('bg-wood-inactive');
|
|
}
|
|
});
|
|
};
|
|
|
|
// Make functions available globally
|
|
(window as any).changeWoodPaneling = changeWoodPaneling;
|
|
(window as any).loadWoodPaneling = loadWoodPaneling;
|
|
(window as any).updateWoodPanelingIndicators = updateWoodPanelingIndicators;
|
|
|
|
// Auto-initialize when DOM is ready
|
|
if (typeof document !== 'undefined') {
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
loadWoodPaneling();
|
|
updateWoodPanelingIndicators();
|
|
});
|
|
} else {
|
|
loadWoodPaneling();
|
|
updateWoodPanelingIndicators();
|
|
}
|
|
}
|
|
```
|
|
|
|
**Note:** This uses Tailwind classes (`bg-wood-light`, etc.) instead of inline styles, and CSS variable classes (`bg-wood-active`, `bg-wood-inactive`) for indicators.
|
|
|
|
#### New File: `web/src/woodPanelingInit.ts`
|
|
|
|
```typescript
|
|
// Early initialization script to prevent flash of wrong background
|
|
// Loads before woodPaneling.js to apply paneling immediately
|
|
|
|
const WOOD_STORAGE_KEY = 'wood-paneling';
|
|
|
|
// Apply wood paneling immediately (before DOM ready if possible)
|
|
(function() {
|
|
const woodPaneling = localStorage.getItem(WOOD_STORAGE_KEY) || 'none';
|
|
if (woodPaneling !== 'none') {
|
|
const applyPaneling = () => {
|
|
const container = document.getElementById('collections-container');
|
|
if (container) {
|
|
container.classList.add(`bg-${woodPaneling}`);
|
|
}
|
|
};
|
|
|
|
// Apply immediately if DOM is ready, otherwise wait
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', applyPaneling);
|
|
} else {
|
|
applyPaneling();
|
|
}
|
|
}
|
|
})();
|
|
```
|
|
|
|
**Note:** This standalone script prevents flash of unstyled content by applying wood paneling as early as possible. It has no dependencies and runs before the main woodPaneling.js module.
|
|
|
|
#### Verification Steps:
|
|
```bash
|
|
# Build TypeScript
|
|
npm run build:ts
|
|
|
|
# Verify: woodPaneling.js compiled successfully to web/static/
|
|
# Verify: No TypeScript errors
|
|
```
|
|
|
|
#### Git Commit:
|
|
```bash
|
|
git add web/src/woodPaneling.ts web/src/woodPanelingInit.ts
|
|
git commit -m "feat(wood-paneling): create wood paneling management system
|
|
|
|
- Add woodPaneling.ts with localStorage-based paneling preferences
|
|
- Add woodPanelingInit.ts for early initialization (prevents flash)
|
|
- Support none, wood-light, wood-dark, wood-mahogany options
|
|
- Apply paneling to #collections-container only (not full body)
|
|
- Use Tailwind utility classes for backgrounds
|
|
- Use CSS variable classes for active indicators
|
|
- Export functions for HTML onclick handlers
|
|
- Auto-initialize on DOM ready"
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 3: Create Active Indicators Module
|
|
|
|
**Goal:** Create active indicators for theme dropdown to show which theme/wood option is selected.
|
|
|
|
#### New File: `web/src/themeDropdown.ts`
|
|
|
|
```typescript
|
|
// Theme dropdown active indicator management
|
|
|
|
// Update visual indicators for theme buttons
|
|
const updateThemeIndicators = (): void => {
|
|
const currentTheme = localStorage.getItem('theme') || 'tokyo-night';
|
|
|
|
// Update theme buttons (all buttons with changeThemeTo onclick)
|
|
document.querySelectorAll('[onclick^="changeThemeTo"]').forEach(btn => {
|
|
const onclick = btn.getAttribute('onclick') || '';
|
|
const match = onclick.match(/changeThemeTo\('(.+?)'\)/);
|
|
if (match) {
|
|
const theme = match[1];
|
|
if (theme === currentTheme) {
|
|
// Active state - use CSS class instead of inline style
|
|
btn.classList.add('bg-theme-active');
|
|
btn.classList.remove('bg-theme-inactive');
|
|
} else {
|
|
// Inactive state
|
|
btn.classList.remove('bg-theme-active');
|
|
btn.classList.add('bg-theme-inactive');
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
// Make function available globally
|
|
(window as any).updateThemeIndicators = updateThemeIndicators;
|
|
|
|
// Update on dropdown toggle
|
|
const originalToggleThemeDropdown = (window as any).toggleThemeDropdown;
|
|
if (originalToggleThemeDropdown) {
|
|
(window as any).toggleThemeDropdown = () => {
|
|
originalToggleThemeDropdown();
|
|
updateThemeIndicators();
|
|
(window as any).updateWoodPanelingIndicators?.();
|
|
};
|
|
}
|
|
|
|
// Update after theme changes
|
|
const originalChangeThemeTo = (window as any).changeThemeTo;
|
|
if (originalChangeThemeTo) {
|
|
(window as any).changeThemeTo = (...args: unknown[]) => {
|
|
originalChangeThemeTo(...args);
|
|
updateThemeIndicators();
|
|
};
|
|
}
|
|
|
|
// Auto-initialize when DOM is ready
|
|
if (typeof document !== 'undefined') {
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', updateThemeIndicators);
|
|
} else {
|
|
updateThemeIndicators();
|
|
}
|
|
}
|
|
```
|
|
|
|
**Note:** Uses CSS classes (`bg-theme-active`, `bg-theme-inactive`) instead of inline styles for better separation of concerns.
|
|
|
|
#### Verification Steps:
|
|
```bash
|
|
# Build TypeScript
|
|
npm run build:ts
|
|
|
|
# Verify: themeDropdown.js compiled successfully to web/static/
|
|
# Verify: No TypeScript errors
|
|
```
|
|
|
|
#### Git Commit:
|
|
```bash
|
|
git add web/src/themeDropdown.ts
|
|
git commit -m "feat(theme): add active indicators for theme dropdown
|
|
|
|
- Create themeDropdown.ts to manage active state highlighting
|
|
- Show which theme/wood option is currently selected
|
|
- Use CSS classes instead of inline styles for indicators
|
|
- Wrap existing functions to update indicators on toggle
|
|
- Auto-initialize indicators on DOM ready"
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 4: Update Tailwind Config for Wood Backgrounds
|
|
|
|
**Goal:** Add Tailwind utility classes for wood texture backgrounds.
|
|
|
|
#### File: `tailwind.config.ts`
|
|
|
|
**Add to `theme.extend`:**
|
|
|
|
```typescript
|
|
export default {
|
|
// ... existing config
|
|
theme: {
|
|
extend: {
|
|
// ... existing extensions
|
|
backgroundImage: {
|
|
'wood-light': "url('/static/textures/wood-light.png')",
|
|
'wood-dark': "url('/static/textures/wood-dark.png')",
|
|
'wood-mahogany': "url('/static/textures/wood-mahogany.png')",
|
|
},
|
|
},
|
|
},
|
|
};
|
|
```
|
|
|
|
#### Verification Steps:
|
|
```bash
|
|
# Regenerate CSS
|
|
npm run build:css
|
|
|
|
# Verify: CSS regenerated with wood background utilities
|
|
# Verify: No errors in build output
|
|
|
|
# Full build
|
|
npm run build:ts
|
|
|
|
# Verify: Full build succeeds
|
|
```
|
|
|
|
#### Git Commit:
|
|
```bash
|
|
git add tailwind.config.ts
|
|
git commit -m "feat(tailwind): add wood texture background utilities
|
|
|
|
- Add bg-wood-light, bg-wood-dark, bg-wood-mahogany utilities
|
|
- Reference texture files in web/static/textures/
|
|
- Extend theme.backgroundImage for seamless texture support"
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 5: Add CSS Classes for Active Indicators
|
|
|
|
**Goal:** Add CSS classes for active/inactive states using CSS variables already defined in `input.css`.
|
|
|
|
#### File: `web/static/input.css`
|
|
|
|
**Add to `@layer components` section (before closing brace, after existing rules):**
|
|
|
|
```css
|
|
/* Active/inactive states for theme and wood paneling buttons */
|
|
.bg-theme-active,
|
|
.bg-wood-active {
|
|
background-color: var(--bg-primary) !important;
|
|
}
|
|
|
|
.bg-theme-inactive,
|
|
.bg-wood-inactive {
|
|
background-color: var(--bg-secondary) !important;
|
|
}
|
|
```
|
|
|
|
**Note:** Uses `!important` to override inline styles in template. CSS variables (`--bg-primary`, `--bg-secondary`) are already defined in the `:root` and theme sections of `input.css`.
|
|
|
|
#### Verification Steps:
|
|
```bash
|
|
# Regenerate CSS
|
|
npm run build:css
|
|
|
|
# Verify: CSS regenerated successfully
|
|
# Verify: No errors
|
|
|
|
# Full build
|
|
npm run build:ts
|
|
```
|
|
|
|
#### Git Commit:
|
|
```bash
|
|
git add web/static/input.css
|
|
git commit -m "feat(styles): add active indicator classes for dropdown buttons
|
|
|
|
- Add bg-theme-active/inactive for theme buttons
|
|
- Add bg-wood-active/inactive for wood paneling buttons
|
|
- Use CSS variables already defined in input.css
|
|
- Use !important to override inline styles"
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 6: Update Header Template
|
|
|
|
**Goal:** Remove wood theme buttons, add wood paneling section, remove max-width constraint, and add script includes.
|
|
|
|
#### File: `templates/header.templ`
|
|
|
|
**Change 1 - Line 5: Remove `max-w-7xl`:**
|
|
|
|
```templ
|
|
<!-- Before -->
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
|
|
<!-- After -->
|
|
<div class="w-full px-4 sm:px-6 lg:px-8">
|
|
```
|
|
|
|
**Change 2 - Lines 85-99: Replace wood theme buttons with wood paneling section:**
|
|
|
|
```templ
|
|
<div class="border-t pt-2 mt-2" style="border-color: var(--border);">
|
|
<p class="text-xs mb-2" style="color: var(--text-secondary)">Bookshelf Background</p>
|
|
<button onclick="changeWoodPaneling('none')"
|
|
class="wood-paneling-btn w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity"
|
|
style="color: var(--text-primary);"
|
|
data-wood="none">
|
|
None
|
|
</button>
|
|
<button onclick="changeWoodPaneling('wood-light')"
|
|
class="wood-paneling-btn w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity"
|
|
style="color: var(--text-primary);"
|
|
data-wood="wood-light">
|
|
<span class="inline-block w-4 h-4 rounded mr-2"
|
|
style="background: url('/static/textures/wood-light.png'); background-size: cover;"></span>
|
|
Wood Light
|
|
</button>
|
|
<button onclick="changeWoodPaneling('wood-dark')"
|
|
class="wood-paneling-btn w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity"
|
|
style="color: var(--text-primary);"
|
|
data-wood="wood-dark">
|
|
<span class="inline-block w-4 h-4 rounded mr-2"
|
|
style="background: url('/static/textures/wood-dark.png'); background-size: cover;"></span>
|
|
Wood Dark
|
|
</button>
|
|
<button onclick="changeWoodPaneling('wood-mahogany')"
|
|
class="wood-paneling-btn w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity"
|
|
style="color: var(--text-primary);"
|
|
data-wood="wood-mahogany">
|
|
<span class="inline-block w-4 h-4 rounded mr-2"
|
|
style="background: url('/static/textures/wood-mahogany.png'); background-size: cover;"></span>
|
|
Wood Mahogany
|
|
</button>
|
|
</div>
|
|
```
|
|
|
|
**Change 3 - Before closing script tag: Add script includes:**
|
|
|
|
```templ
|
|
<script src="/static/woodPaneling.js"></script>
|
|
<script src="/static/themeDropdown.js"></script>
|
|
```
|
|
|
|
#### Verification Steps:
|
|
```bash
|
|
# Build Go templates
|
|
go build ./...
|
|
|
|
# Verify: Build succeeds with no template errors
|
|
# Verify: Script tags are properly placed
|
|
```
|
|
|
|
#### Git Commit:
|
|
```bash
|
|
git add templates/header.templ
|
|
git commit -m "refactor(header): separate wood paneling from color themes
|
|
|
|
- Remove max-w-7xl constraint, use full-width layout
|
|
- Replace wood theme buttons with wood paneling section
|
|
- Add visual previews for wood textures in dropdown
|
|
- Section labeled \"Bookshelf Background\" for clarity
|
|
- Include woodPaneling.js and themeDropdown.js scripts"
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 7: Apply Full-Width Layout to Dashboard
|
|
|
|
**Goal:** Apply full-width layout and include wood paneling initialization script.
|
|
|
|
#### File: `templates/dashboard.templ`
|
|
|
|
**Change 1 - Line ~27: Library selector - Remove `max-w-7xl`:**
|
|
|
|
```templ
|
|
<!-- Before -->
|
|
<div class="max-w-7xl mx-auto px-4 py-3 flex items-center justify-between">
|
|
|
|
<!-- After -->
|
|
<div class="w-full px-4 py-3 flex items-center justify-between">
|
|
```
|
|
|
|
**Change 2 - Line ~67: Collections container - Remove `max-w-7xl`:**
|
|
|
|
```templ
|
|
<!-- Before -->
|
|
<main id="collections-container" class="max-w-7xl mx-auto px-4 py-8">
|
|
|
|
<!-- After -->
|
|
<main id="collections-container" class="w-full px-4 py-8">
|
|
```
|
|
|
|
**Change 3 - Before closing body tag: Add wood paneling initialization script:**
|
|
|
|
```templ
|
|
<script src="/static/woodPanelingInit.js"></script>
|
|
```
|
|
|
|
**This ensures:**
|
|
- Wood paneling applied immediately when script loads (before DOM ready)
|
|
- No flash of wrong background
|
|
- All JavaScript is TypeScript (follows PROJECT_GUIDELINES.md)
|
|
|
|
#### Verification Steps:
|
|
```bash
|
|
# Build Go templates
|
|
go build ./...
|
|
|
|
# Verify: Build succeeds
|
|
# Verify: Script tag placed before closing body tag
|
|
# Verify: woodPanelingInit.js exists in web/static/
|
|
```
|
|
|
|
#### Git Commit:
|
|
```bash
|
|
git add templates/dashboard.templ
|
|
git commit -m "refactor(dashboard): apply full-width layout and wood paneling
|
|
|
|
- Remove max-w-7xl constraints from library selector and collections
|
|
- Include woodPanelingInit.js script for early paneling application
|
|
- Prevent flash of wrong background on page load
|
|
- Wood paneling applied only to #collections-container
|
|
"
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 8: Apply Full-Width Layout to All Remaining Pages
|
|
|
|
**Goal:** Remove `max-w-7xl` constraints from all remaining page templates.
|
|
|
|
#### Files to Modify:
|
|
|
|
**Regular pages:**
|
|
- `templates/collections.templ`
|
|
- `templates/progress.templ`
|
|
- `templates/queue.templ`
|
|
- `templates/devices.templ`
|
|
- `templates/analytics.templ`
|
|
- `templates/conflicts.templ`
|
|
- `templates/unlinked_books.templ`
|
|
- `templates/bookshelf.templ`
|
|
- `templates/profile.templ`
|
|
- `templates/docs.templ`
|
|
|
|
**Admin pages:**
|
|
- `templates/admin.templ`
|
|
- `templates/admin_library.templ`
|
|
- `templates/admin_users.templ`
|
|
|
|
**Pattern:** Replace `class="max-w-7xl mx-auto px-4 ..."` with `class="w-full px-4 ..."`
|
|
|
|
**Note:** Keep padding (`px-4`, `py-8`, etc.) for readability.
|
|
|
|
**Special note for admin templates:**
|
|
Admin templates have sidebar layout wrappers. The structure is:
|
|
```templ
|
|
<div class="flex min-h-screen" style="background-color: var(--bg-primary)">
|
|
@AdminSidebar(user, currentPath)
|
|
<main class="flex-1 p-8">
|
|
<div class="max-w-7xl"> <!-- Change this -->
|
|
(or <div class="max-w-6xl"> in some cases)
|
|
```
|
|
|
|
Change the inner div in all three admin templates:
|
|
```templ
|
|
<!-- Before -->
|
|
<div class="max-w-7xl"> (or <div class="max-w-6xl">)
|
|
|
|
<!-- After -->
|
|
<div class="w-full">
|
|
```
|
|
|
|
**Do NOT** modify the `main` element or the flex wrapper in admin templates - these are part of the admin sidebar layout.
|
|
|
|
#### Verification Steps:
|
|
```bash
|
|
# Build all templates
|
|
go build ./...
|
|
|
|
# Verify: All templates compile successfully
|
|
# Verify: No template errors
|
|
```
|
|
|
|
#### Git Commit:
|
|
```bash
|
|
git add templates/collections.templ templates/progress.templ templates/queue.templ templates/devices.templ templates/analytics.templ templates/conflicts.templ templates/unlinked_books.templ templates/bookshelf.templ templates/profile.templ templates/docs.templ templates/admin.templ templates/admin_library.templ templates/admin_users.templ
|
|
git commit -m "refactor(layout): apply full-width layout to all pages
|
|
|
|
- Remove max-w-7xl containers from all page templates
|
|
- Replace with w-full for full-screen width utilization
|
|
- Maintain padding for readability
|
|
- Admin templates: modify inner content div only (preserve sidebar layout)"
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 9: Add User Documentation
|
|
|
|
**Goal:** Document the wood paneling and theme features for end users.
|
|
|
|
#### New File: `docs/user/themes.md`
|
|
|
|
```markdown
|
|
# Themes and Wood Paneling
|
|
|
|
## Color Themes
|
|
|
|
Bookhoard includes multiple color themes to suit your preferences:
|
|
|
|
- **Tokyo Night** (default) - Dark blue/purple tones
|
|
- **Dracula** - Dark purple accent colors
|
|
- **Nord** - Arctic, bluish-gray colors
|
|
- **Solarized Dark** - Precision contrast for readability
|
|
- **Monokai** - Dark theme with vibrant accents
|
|
- **One Dark Pro** - Atom's favorite theme
|
|
- **Material Dark** - Material Design dark theme
|
|
- **Catppuccin Mocha** - Soothing pastel dark theme
|
|
- **Catppuccin Macchiato** - Warm mid-tone theme
|
|
- **Catppuccin Frappé** - Frothy cool tones
|
|
- **Catppuccin Latte** - Warm light theme
|
|
|
|
### Changing Your Theme
|
|
|
|
1. Click the theme icon (palette) in the header
|
|
2. Select your preferred color theme
|
|
3. Your choice is saved automatically and synced across devices
|
|
|
|
## Wood Paneling
|
|
|
|
Wood paneling adds texture to your dashboard bookshelf background, giving it a classic bookshelf feel.
|
|
|
|
### Available Wood Textures
|
|
|
|
- **None** (default) - Solid color background
|
|
- **Wood Light** - Light oak/birch texture
|
|
- **Wood Dark** - Dark walnut/mahogany texture
|
|
- **Wood Mahogany** - Reddish-brown mahogany texture
|
|
|
|
### Applying Wood Paneling
|
|
|
|
1. Click the theme icon (palette) in the header
|
|
2. Scroll to "Bookshelf Background" section
|
|
3. Select your preferred wood texture
|
|
4. Texture is applied to dashboard bookshelf only
|
|
|
|
**Note:** Wood paneling is a browser preference and is not synced across devices.
|
|
|
|
### Tips
|
|
|
|
- Wood textures work best with darker color themes (Tokyo Night, Nord, etc.)
|
|
- Light wood pairs well with light themes (Catppuccin Latte)
|
|
- Wood paneling only affects the dashboard bookshelf area
|
|
```
|
|
|
|
#### Verification Steps:
|
|
```bash
|
|
# Restart server and verify docs render
|
|
curl http://localhost:8080/docs
|
|
|
|
# Verify: themes.md appears in search
|
|
# Verify: Documentation renders correctly
|
|
```
|
|
|
|
#### Git Commit:
|
|
```bash
|
|
git add docs/user/themes.md
|
|
git commit -m "docs(user): add themes and wood paneling guide
|
|
|
|
- Document all available color themes with descriptions
|
|
- Explain wood paneling feature and available textures
|
|
- Provide step-by-step instructions for changing themes
|
|
- Add tips for theme/texture pairing"
|
|
```
|
|
|
|
---
|
|
|
|
### Phase 10: Final Testing and Verification
|
|
|
|
**Goal:** Complete end-to-end testing and verification.
|
|
|
|
#### Testing Checklist:
|
|
|
|
**Wood Paneling:**
|
|
- [ ] Wood paneling options appear in theme dropdown
|
|
- [ ] "None" option removes texture
|
|
- [ ] Wood textures apply to dashboard only (not header/sidebar)
|
|
- [ ] Active wood option highlighted
|
|
- [ ] Preference persists across page refreshes
|
|
|
|
**Full-Width Layout:**
|
|
- [ ] All pages use full width
|
|
- [ ] Content still readable with proper padding
|
|
- [ ] Responsive on mobile devices
|
|
|
|
**Theme System:**
|
|
- [ ] Wood themes removed from color theme section
|
|
- [ ] Color themes still work correctly
|
|
- [ ] Active theme highlighted
|
|
- [ ] Theme switching saves to server
|
|
|
|
**Performance:**
|
|
- [ ] Wood textures load quickly (<500 KB each)
|
|
- [ ] No flash of wrong background on page load
|
|
|
|
#### Final Verification:
|
|
```bash
|
|
# Build everything
|
|
npm run build:ts
|
|
npm run build:css
|
|
go build ./...
|
|
|
|
# Run verification script
|
|
bash scripts/verify-guidelines.sh
|
|
|
|
# Run tests
|
|
go test ./... -v
|
|
```
|
|
|
|
#### Final Git Commit:
|
|
```bash
|
|
git add .
|
|
git commit -m "chore: final cleanup for wood paneling and full-width layout
|
|
|
|
- All phases complete and tested
|
|
- Documentation updated in docs/user/themes.md
|
|
- Verification scripts passing
|
|
- Ready for testing"
|
|
```
|
|
|
|
---
|
|
|
|
## Files Summary
|
|
- `web/src/woodPaneling.ts` - Wood paneling management
|
|
- `web/src/woodPanelingInit.ts` - Early wood paneling initialization (prevents flash)
|
|
- `web/src/themeDropdown.ts` - Active indicator management
|
|
- `web/static/textures/wood-light.png` - Light wood texture
|
|
- `web/static/textures/wood-dark.png` - Dark wood texture
|
|
- `web/static/textures/wood-mahogany.png` - Mahogany texture
|
|
|
|
### Files Modified
|
|
- `templates/header.templ` - Remove wood themes, add wood paneling section, remove max-width
|
|
- `templates/profile_form.templ` - Remove wood theme options from profile settings
|
|
- `tailwind.config.ts` - Remove theme-wood-* from safelist, add wood background images
|
|
- `templates/dashboard.templ` - Remove max-width, add wood paneling script include
|
|
- `templates/*.templ` - Remove `max-w-7xl` from all page templates
|
|
|
|
---
|
|
|
|
## Migration Notes
|
|
|
|
### Breaking Changes
|
|
- Wood themes removed from theme system
|
|
- Users with wood theme selected will see tokyo-night (or their last color theme)
|
|
- Wood paneling preference starts as "none" (users must opt-in)
|
|
|
|
### Backward Compatibility
|
|
- Color themes unaffected
|
|
- localStorage theme preference still works
|
|
- Server-side theme sync still works
|
|
|
|
### Database Dependencies
|
|
- None (wood paneling is localStorage only)
|
|
|
|
### Performance
|
|
- Wood textures only loaded when selected
|
|
- "None" option = no texture load (fastest)
|
|
- Texture size optimized to ~200-500 KB each
|
|
|
|
### Progressive Enhancement
|
|
- Pages work without wood paneling (default "none")
|
|
- Wood paneling degrades gracefully if JS fails
|
|
- Color themes work independently of wood paneling
|
|
|
|
---
|
|
|
|
## Rollback Plan
|
|
|
|
If issues arise:
|
|
1. Remove wood paneling section from header
|
|
2. Restore `max-w-7xl` containers in templates
|
|
3. Delete wood texture files
|
|
4. Revert header.ts to include wood theme logic
|
|
5. Wood paneling preference in localStorage will be ignored (harmless)
|
|
|
|
---
|
|
|
|
## Future Improvements
|
|
|
|
1. **Per-page wood paneling:** Allow wood on bookshelf page, not just dashboard
|
|
2. **Texture variety:** Add more wood options (oak, pine, walnut)
|
|
3. **Texture intensity:** Add opacity slider for subtler effect
|
|
4. **Custom textures:** Allow users to upload their own backgrounds
|
|
5. **Server-side sync:** Store wood paneling preference in database for cross-device sync
|
|
6. **Preview mode:** Show texture preview before applying
|
|
7. **High-DPI textures:** Provide 2x versions for retina displays
|
|
|
|
---
|
|
|
|
## Attribution
|
|
|
|
All wood textures are CC0 licensed (no attribution required):
|
|
|
|
- **Light wood:** qubodup - https://opengameart.org/content/light-wood-1024x1024
|
|
- **Dark/Mahogany wood:** Luke.RUSTLTD - https://opengameart.org/content/5-wood-textures
|
|
|
|
**Optional:** Add to README.md or about page for documentation purposes.
|