Files
BMAD-METHOD/demos/early-v3alpha-full-stack-app-demo/9-v0-one-shot-prompt.txt

123 lines
8.3 KiB
Plaintext

Generate a Next.js 14 (App Router) application using React, TypeScript, and Tailwind CSS for a project called "BMad DiCaster".
The application's purpose is to display daily summaries of Hacker News posts, including an optional AI-generated podcast.
**1. Overall Project Context & Technology Stack:**
- Framework: Next.js 14+ (App Router)
- Language: TypeScript
- UI Library: React (19+)
- Styling: Tailwind CSS (v3.4+)
- Base Component Library: Shadcn UI (latest). Assume necessary Shadcn UI components (like Button, Card, Dialog, Audio player if available, or primitives to build one) can be easily added or are available.
- State Management (Client-Side): Zustand (for specific client components like the podcast player). For initial scaffolding, component-level state is acceptable.
- Data Source (for displayed content): Supabase (PostgreSQL). For this initial v0 generation, use placeholder data or clearly indicate where data fetching from Supabase would occur. Server Components should be preferred for data fetching.
**2. Design System & Visual Styling:**
- Theme: "Synthwave technical glowing purple vibes." This translates to:
- A predominantly dark theme for the application background.
- Accent Color: A vibrant purple (e.g., Tailwind's `purple-500` or a custom shade like `#800080`) for interactive elements, links, highlights, and potentially subtle glows or text shadows on headings.
- Layout: Modern, minimalist, and clean, focusing on content readability and efficient information consumption.
- Typography: Use Tailwind's default sans-serif font stack. Employ semantic HTML and Tailwind's typography utilities (e.g., `text-2xl font-bold` for titles, `text-base` for body).
- Responsiveness: The application must be mobile-first and responsive across common breakpoints (sm, md, lg, xl) using Tailwind CSS.
- Accessibility: Adhere to WCAG 2.1 Level A. This includes semantic HTML, keyboard navigability, sufficient color contrast (especially with the dark theme and purple accents), and alt text for any images (though MVP is mostly text/content based).
**3. Application Structure & Routing (Next.js App Router):**
- The main application will live under the `/` path, effectively serving as the newsletter list page.
- `/newsletters`: This route should display a list of available newsletters. If the root `/` path doesn't directly serve this, it should redirect here or this should be the primary view.
- `/newsletters/[newsletterId]`: This dynamic route will display the content of a single, selected newsletter. `[newsletterId]` will be a unique identifier (e.g., a UUID).
**4. Page Structure & Key Components:**
**A. PageWrapper Component (Conceptual - Create if useful for consistency):**
- A layout component that wraps page content.
- Provides consistent horizontal padding (e.g., `px-4 md:px-8`) and a max-width container (e.g., `max-w-4xl mx-auto`) to ensure content is well-centered and readable on larger screens.
- Should include a simple header placeholder (e.g., just the text "BMad DiCaster" with the logo if available or a placeholder for it) and a simple footer placeholder (e.g., copyright text).
**B. Newsletter List Page (`/` or `/newsletters` -> `app/(web)/newsletters/page.tsx`):**
- Purpose: Display a list of available newsletters, ordered by date (most recent first).
- Key UI Elements:
- Page Title: e.g., "Daily DiCaster Updates" or "Latest Newsletters".
- List of `NewsletterCard` components.
- Data: Each card represents a newsletter and should display at least a title and date. Clicking a card navigates to the Newsletter Detail Page. For v0, use an array of 3-5 placeholder newsletter objects (e.g., `{ id: 'uuid-1', title: 'Tech Highlights - May 14, 2025', date: '2025-05-14', summary_short: 'A quick rundown of today\'s top tech news...' }`).
- Structure:
```html
<PageWrapper>
<h1>[Page Title]</h1>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
</div>
</PageWrapper>
```
**C. Newsletter Detail Page (`/newsletters/[newsletterId]` -> `app/(web)/newsletters/[newsletterId]/page.tsx`):**
- Purpose: Display the full content of a selected newsletter, including its podcast version.
- Key UI Elements:
- `BackButton` component to navigate back to the Newsletter List Page.
- Newsletter Title.
- Newsletter Date.
- Full HTML content of the newsletter.
- `PodcastPlayer` component (if a podcast URL is available for the newsletter).
- `DownloadButton` component to download the newsletter.
- Data: For v0, use a placeholder newsletter object (e.g., `{ id: 'uuid-1', title: 'Tech Highlights - May 14, 2025', date: '2025-05-14', htmlContent: '<p>This is the full <b>HTML</b> content...</p><ul><li>Point 1</li></ul>', podcastUrl: 'placeholder_audio.mp3' }`).
- Structure:
```html
<PageWrapper>
<BackButton />
<h2>[Newsletter Title]</h2>
<p class="text-sm text-gray-400">[Newsletter Date]</p>
<article class="prose dark:prose-invert mt-4">
</article>
<div class="mt-6">
<PodcastPlayer audioUrl="{placeholder_audio.mp3 (if available)}" />
</div>
<div class="mt-4">
<DownloadButton newsletterId="{newsletterId}" />
</div>
</PageWrapper>
```
(Note: `prose` and `dark:prose-invert` are Tailwind Typography plugin classes. Assume this plugin is or can be installed.)
**5. Core Reusable Components (to be placed in `app/components/core/`):**
**a. `NewsletterCard.tsx`:**
- Purpose: Displays a summary of a newsletter in the list view.
- Props: `id: string`, `title: string`, `date: string`, `summary_short?: string`.
- UI: Use a Shadcn UI `Card` component as a base. Display title, date, and summary. The entire card should be clickable and navigate to `/newsletters/[id]`.
- Styling: Minimalist, synthwave accents on hover/focus.
**b. `PodcastPlayer.tsx`:**
- Purpose: Plays the podcast audio associated with a newsletter.
- Props: `audioUrl: string`.
- UI:
- If a Shadcn UI audio player component is available, use it.
- Otherwise, create a simple player using HTML5 `<audio>` element and custom controls styled with Tailwind CSS.
- Controls: Play/Pause button, current time / total duration display, volume control (slider or button), and a simple progress bar.
- State: Manage internal state for play/pause, current time, volume using component-level state (useState) or a simple Zustand slice (`podcastPlayerSlice.ts`).
- Styling: Clean, integrated into the page, synthwave accents for controls.
**c. `DownloadButton.tsx`:**
- Purpose: Allows the user to download the newsletter.
- Props: `newsletterId: string` (or `downloadUrl: string` if preferred).
- UI: Use a Shadcn UI `Button` component. Icon for download is a plus.
- Action: For v0, this can be a placeholder button. In the actual app, it would trigger a download.
- Styling: Consistent with other buttons, synthwave accent.
**d. `BackButton.tsx`:**
- Purpose: Navigates the user to the previous page (typically the newsletter list).
- UI: Use a Shadcn UI `Button` (perhaps with `variant="outline"` or `variant="ghost"`). Should ideally include a "back" icon and/or text "Back to list".
- Action: Use Next.js `useRouter` hook for navigation (`router.back()` or to a specific path like `/newsletters`).
**6. General Instructions for Vercel v0:**
- Generate separate, well-commented files for each component and page.
- Use placeholder data where actual data fetching from Supabase would occur. Clearly comment these locations.
- Ensure basic folder structure aligns with Next.js App Router best practices (e.g., `app/(web)/newsletters/page.tsx`, `app/components/core/NewsletterCard.tsx`).
- Prioritize functional scaffolding of the layout and components over pixel-perfect styling if choices need to be made, but apply the synthwave theme (dark base, purple accents) generally.
- The code should be clean, readable, and easily modifiable.
**Example of a placeholder newsletter data structure (for v0):**
```typescript
interface PlaceholderNewsletter {
id: string;
title: string;
date: string; // e.g., "YYYY-MM-DD"
summary_short?: string; // For card view
htmlContent?: string; // For detail view
podcastUrl?: string; // URL to an mp3 file
}