You are an expert AI assistant tasked with generating a comprehensive, production-ready single-page application (SPA) for a web platform called 'Kanal Sörfü' (Channel Surfer). This application aims to recreate the 'cable TV' viewing experience for YouTube, addressing the 'too many options' problem. The core value proposition is to provide a simple, account-free way for users to import their YouTube subscriptions and browse content as if it were curated TV channels. The application should run entirely in the browser, leveraging local storage for data persistence and a bookmarklet for easy subscription import.
**1. PROJECT OVERVIEW:**
* **Purpose:** To solve the "decision fatigue" problem users face when browsing YouTube due to an overwhelming number of subscriptions and content options. It aims to provide a curated, channel-like viewing experience for YouTube content.
* **Problem Solved:** Eliminates the need to constantly choose what to watch from a vast list of subscriptions. Offers a passive, lean-back viewing experience similar to traditional cable TV.
* **Value Proposition:** "Watch YouTube like it's cable TV. Import your subscriptions instantly, no accounts needed. Discover content effortlessly."
* **Target User:** Users with numerous YouTube subscriptions experiencing choice paralysis, who prefer simple, browser-based, privacy-focused solutions.
**2. TECH STACK:**
* **Frontend Framework:** React (using Vite for fast development setup).
* **Styling:** Tailwind CSS for rapid UI development and utility-first styling. Ensure responsiveness across all devices.
* **State Management:** Zustand for lightweight and efficient global state management. Local state management using `useState` and `useReducer` where appropriate.
* **Routing:** React Router DOM for handling different views within the SPA (though primarily a single-page focus, future expansion might need it).
* **Data Persistence:** Browser Local Storage API for storing user subscriptions, watched history, and preferences.
* **YouTube API Interaction:** Primarily through user-provided data (via bookmarklet or manual import) rather than direct YouTube API calls for subscriptions to maintain the no-account, no-sign-in principle. Video playback will use standard YouTube embed parameters.
* **Iconography:** React Icons or similar for a consistent icon set.
**3. CORE FEATURES & USER FLOWS:****
* **Feature 1: Subscription Import**
* **Description:** Users can import their YouTube subscriptions. Initially, this will be supported via a bookmarklet that scrapes the subscription list from the YouTube website (requires user to be logged into YouTube on their browser when running the bookmarklet) or a manual input field for channel IDs/URLs.
* **User Flow (Bookmarklet):**
1. User navigates to their YouTube subscriptions page.
2. User clicks the "Kanal Sörfü" bookmarklet.
3. Bookmarklet runs JavaScript in the browser to extract channel IDs/names from the current page.
4. Extracted data is sent to the application's state.
* **User Flow (Manual):**
1. User navigates to the 'Settings' or 'Import' section of the app.
2. User pastes channel URLs or IDs into a text area.
3. User clicks 'Import'.
4. App parses the input and adds channels to the subscription list.
* **Feature 2: Channel Surfing Interface**
* **Description:** The main view displays a dynamic list of "channels" (which are essentially groups of videos from the user's subscriptions). Videos are presented in a card-like format, mimicking a TV guide or a scrolling channel list.
* **User Flow:**
1. Upon loading, the app displays the main "Channel Surfer" view.
2. Videos from imported subscriptions are fetched (initially mock data, then dynamically based on import).
3. Videos are grouped (e.g., by subscription, by upload date, randomly).
4. Each video is shown as a card with thumbnail, title, channel name, and upload date.
5. Users can scroll vertically through the "channels" or horizontally through videos within a channel.
* **Feature 3: Video Playback**
* **Description:** Clicking a video card opens an embedded YouTube player within the application.
* **User Flow:**
1. User clicks on a video card.
2. A modal or dedicated player view opens.
3. An embedded YouTube player loads and starts playing the selected video.
4. Controls for the player (play/pause, volume, fullscreen) are provided by the YouTube embed.
5. User can close the player to return to the Channel Surfer view.
* **Feature 4: Watch History & Progress**
* **Description:** The application keeps track of videos the user has started or finished watching, storing this information in local storage.
* **User Flow:**
1. When a video starts playing, its status is updated to 'watching' in local storage.
2. When a video is closed or playback finishes, its status is updated to 'watched'.
3. UI elements (e.g., video cards) visually indicate if a video has been watched or is currently being watched.
* **Feature 5: Settings & Data Management**
* **Description:** A simple settings area to manage imported subscriptions (view list, delete individual subscriptions).
* **User Flow:**
1. User navigates to the 'Settings' page.
2. User sees a list of all imported subscriptions.
3. User can click a 'delete' button next to each subscription to remove it.
4. Option to clear all imported data and start fresh.
**4. UI/UX DESIGN:**
* **Layout:** Single Page Application. A clean, minimalist layout. The primary view will be the "Channel Surfer" feed. A collapsible sidebar or a top navigation bar for settings, import, and potentially different viewing modes.
* **Color Palette:** A modern, slightly dark theme to complement video content. Primary colors: Dark grey/near-black background (`#121212`), accent color (e.g., a vibrant blue or green like `#00bcd4` or `#4caf50`) for interactive elements, buttons, and highlights. Secondary text/icons in light grey (`#bdbdbd`).
* **Typography:** A clean, readable sans-serif font family (e.g., Inter, Roboto, or Lato). Clear hierarchy using font size and weight.
* **Component Structure:** Highly componentized. Card components for videos, modal components for playback, list components for subscriptions, input components for manual import.
* **Responsiveness:** Mobile-first approach. Layout should adapt seamlessly from small mobile screens to large desktop monitors. Use Tailwind's responsive prefixes (sm:, md:, lg:).
* **Key Views:**
* **Main Feed (`ChannelSurfer.jsx`):** Displays video cards in a scrollable, channel-like format.
* **Video Player Modal (`VideoPlayerModal.jsx`):** Contains the embedded YouTube player.
* **Settings (`Settings.jsx`):** Manages subscription imports and data.
* **Import Area (within Settings or dedicated):** Handles bookmarklet trigger and manual input.
**5. DATA MODEL & STATE MANAGEMENT:**
* **State Structure (Zustand Store):**
```javascript
// Example store structure
interface Subscription {
id: string; // YouTube Channel ID
name: string;
thumbnail: string;
}
interface Video {
videoId: string;
title: string;
thumbnail: string;
channelId: string;
channelName: string;
publishedAt: string; // ISO 8601 format
viewedStatus: 'not_viewed' | 'watching' | 'watched';
watchedProgress: number; // Percentage or timestamp
}
interface AppState {
subscriptions: Subscription[];
allVideos: Video[]; // Potentially fetched or mocked
groupedVideos: {
[key: string]: Video[]; // Grouped by subscription, date, etc.
};
isPlayerOpen: boolean;
currentVideo: Video | null;
// Actions
importSubscriptions: (subs: Subscription[]) => void;
deleteSubscription: (channelId: string) => void;
setVideoWatchedStatus: (videoId: string, status: Video['viewedStatus'], progress?: number) => void;
openPlayer: (video: Video) => void;
closePlayer: () => void;
loadData: () => void; // Loads from local storage
saveData: () => void; // Saves to local storage
}
```
* **Local Storage:** All `subscriptions` and `allVideos` (with their `viewedStatus` and `watchedProgress`) will be serialized and stored under specific keys (e.g., `ks_subscriptions`, `ks_videos`). `loadData` will populate the state from Local Storage on app initialization, and `saveData` will be called after state mutations.
* **Mock Data:** Initial loading will use mock data for `allVideos` and `subscriptions` until the user imports their own. This mock data should represent a variety of channels and videos.
**6. COMPONENT BREAKDOWN:**
* **`App.jsx`:** Root component. Sets up context/store providers, basic layout structure, and routing (if applicable).
* **`ChannelSurfer.jsx`:** Main content component. Fetches and displays video groups. Handles scrolling and rendering of `VideoGrid.jsx` or `VideoChannel.jsx`.
* **`VideoChannel.jsx`:** Component to display a "channel" (a group of videos from one subscription or category). Contains a list of `VideoCard.jsx`.
* **`VideoCard.jsx`:** Displays individual video information (thumbnail, title, channel, date). Shows watched status indicators. Handles click events to open the player.
* Props: `video: Video`, `onClick: () => void`, `onMarkAsWatched: () => void`
* **`VideoPlayerModal.jsx`:** A modal component containing the embedded YouTube player.
* Props: `video: Video`, `isOpen: boolean`, `onClose: () => void`
* **`YouTubeEmbed.jsx`:** Wrapper component for the YouTube iframe embed. Handles passing the correct video ID and player parameters.
* Props: `videoId: string`, `height: string`, `width: string`
* **`Settings.jsx`:** Page for managing user data.
* Includes `SubscriptionManager.jsx` and potentially `ImportForm.jsx`.
* **`SubscriptionManager.jsx`:** Displays the list of imported subscriptions and provides functionality to delete them.
* Props: `subscriptions: Subscription[]`, `onDelete: (channelId: string) => void`
* **`ImportForm.jsx`:** Contains the manual input field and button for importing channels.
* Props: `onImport: (channelsData: string) => void`
* **`BookmarkletTrigger.jsx`:** A button or link that, when clicked, instructs the user on how to use the provided bookmarklet (or potentially injects/runs it if browser security permits, though direct injection is complex and often restricted).
* **`Header.jsx`:** Top navigation bar with app title, potentially links to settings, and branding.
* **`Footer.jsx`:** Basic footer with copyright and links.
**7. ANIMATIONS & INTERACTIONS:**
* **Page Transitions:** Subtle fade-in/fade-out for modal views (player, settings) using CSS transitions or a library like `Framer Motion` (optional, keep it light).
* **Hover Effects:** Slight scale-up or shadow effect on `VideoCard.jsx` on hover to indicate interactivity.
* **Loading States:** Display skeleton loaders or a subtle pulsing animation while fetching/processing video data initially or after an import action. The `YouTubeEmbed.jsx` should handle its own loading state.
* **Micro-interactions:** Smooth scrolling, subtle visual feedback when marking a video as watched.
* **Bookmarklet Interaction:** Clear visual cues or instructions guiding the user on how to add and use the bookmarklet.
**8. EDGE CASES & ACCESSIBILITY:**
* **Empty States:**
* **No Subscriptions Imported:** Display a friendly message encouraging the user to import subscriptions, with a clear call-to-action (e.g., "Import your YouTube subscriptions to start!" with a button linking to the import section).
* **No Videos Available:** If a subscription somehow has no videos, handle gracefully.
* **Player Not Loading:** Provide a fallback message if the YouTube embed fails.
* **Error Handling:**
* **Bookmarklet Issues:** Inform the user if the bookmarklet fails (e.g., "Could not import subscriptions. Please ensure you are on your YouTube subscriptions page and logged in.").
* **Data Corruption:** Implement basic checks on local storage data and provide a way to clear/reset if necessary.
* **Invalid Input:** Validate manual import input to ensure it's a valid URL or channel ID format.
* **Validation:** For manual import, basic regex validation for YouTube channel URLs or IDs.
* **Accessibility (a11y):**
* Use semantic HTML elements (nav, main, button, etc.).
* Ensure sufficient color contrast.
* Provide keyboard navigation for all interactive elements.
* Use ARIA attributes where necessary (e.g., for modal dialogs, status messages).
* Ensure focus management, especially when opening/closing modals.
* Add `alt` text for images where appropriate (though video thumbnails might be decorative in context).
**9. SAMPLE DATA:**
* **`Subscription` Mock Data:**
```json
[
{
"id": "UC-lHJZR3Gqxm24_Vd_AJswg",
"name": "Marques Brownlee",
"thumbnail": "https://yt3.ggpht.com/ytc/APjr1UypU4_aC7a3A0H03_8mX03P1T4LpD9Sj_Xv7Z_7qA=s88-c-k-c0x00ffffff-no-rj"
},
{
"id": "UCsXVk37bltHbXVn3M_Pxf0A",
"name": "Kurzgesagt – In a Nutshell",
"thumbnail": "https://yt3.ggpht.com/ytc/APjr1JyrO1LqJ9iN3h-i6Jj8kZ5O7U1L0yS6g0U2gQ=s88-c-k-c0x00ffffff-no-rj"
},
{
"id": "UC7_e5g0rvQy10V3P47xW3eA",
"name": "Vsauce",
"thumbnail": "https://yt3.ggpht.com/a-/ALV-j8r2k_45eQx_9P9v6ZzJ7z1L2s1k5E7F8C7v=s88-c-k-c0x00ffffff-no-rj"
}
]
```
* **`Video` Mock Data (for initial loading and testing):**
```json
[
{
"videoId": "dQw4w9WgXcQ",
"title": "Rick Astley - Never Gonna Give You Up (Official Music Video)",
"thumbnail": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hq720.jpg?sqp=-oaymwEcCOgEMo5sBCvfEB4QBw==&rs=AOn4CLBbY7kZq7U_G6g8q3r5y7q7y7q7y7q",
"channelId": "UC_x5XG1OV2X5hXcAz0_NfLQ",
"channelName": "Rick Astley",
"publishedAt": "2009-10-25T14:24:34Z",
"viewedStatus": "not_viewed",
"watchedProgress": 0
},
{
"videoId": "kXYiU_JCYsM",
"title": "What Is The Internet?",
"thumbnail": "https://i.ytimg.com/vi/kXYiU_JCYsM/hq720.jpg?sqp=-oaymwEcCOgEMo5sBCvfEB4QBw==&rs=AOn4CLBdq8dK5l9Q2q1y7j9w5r7q7w7q7w",
"channelId": "UCsXVk37bltHbXVn3M_Pxf0A",
"channelName": "Kurzgesagt – In a Nutshell",
"publishedAt": "2019-10-17T10:00:01Z",
"viewedStatus": "watched",
"watchedProgress": 100
},
{
"videoId": "6xK81C_fWkM",
"title": "The Surprising Science of Sleep - Vsauce",
"thumbnail": "https://i.ytimg.com/vi/6xK81C_fWkM/hq720.jpg?sqp=-oaymwEcCOgEMo5sBCvfEB4QBw==&rs=AOn4CLB4H7p4f4Q7q7w7q7w7q7w7q7w7q",
"channelId": "UC7_e5g0rvQy10V3P47xW3eA",
"channelName": "Vsauce",
"publishedAt": "2017-08-15T14:00:05Z",
"viewedStatus": "watching",
"watchedProgress": 450 // seconds
},
{
"videoId": "pPRp2r1k1fM",
"title": "The iPhone 15 Pro Max Review: It Just Works?",
"thumbnail": "https://i.ytimg.com/vi/pPRp2r1k1fM/hq720.jpg?sqp=-oaymwEcCOgEMo5sBCvfEB4QBw==&rs=AOn4CLBdQ7p7f7q7w7q7w7q7w7q7w7q",
"channelId": "UC-lHJZR3Gqxm24_Vd_AJswg",
"channelName": "Marques Brownlee",
"publishedAt": "2023-09-22T13:00:10Z",
"viewedStatus": "not_viewed",
"watchedProgress": 0
}
]
```
**10. DEPLOYMENT NOTES:**
* **Build Tool:** Vite (`npm run build`).
* **Output:** Generates a static `dist` folder suitable for hosting on any static web server (Netlify, Vercel, GitHub Pages, S3).
* **Environment Variables:** Use `.env` files for configuration if needed (though for this scope, primarily local storage, few env vars might be needed initially). Define `VITE_APP_NAME`, `VITE_BOOKMARKLET_JS` (if injecting script).
* **Performance Optimizations:**
* Code splitting (handled by Vite).
* Image optimization (using tools like `vite-plugin-imagemin` if needed, though YouTube thumbnails are generally optimized).
* Lazy loading of components, especially the `VideoPlayerModal`.
* Efficient state updates using Zustand selectors.
* Minimize DOM manipulations.
* **HTTPS:** Ensure deployment uses HTTPS for security and potential browser API restrictions.
* **CORS:** Not a significant issue as we are not making direct cross-origin API calls for subscription data, and YouTube embeds handle their own domain.
* **Bookmarklet:** Provide clear instructions on how users can create and use the bookmarklet. The JavaScript for the bookmarklet needs to be carefully crafted to run on `youtube.com/feed/subscriptions` and extract necessary data reliably. Example bookmarklet JS might look like:
```javascript
(function() {
const subs = [];
document.querySelectorAll('ytd-channel-renderer').forEach(el => {
const channelName = el.querySelector('#channel-name #text a').innerText;
const channelId = el.querySelector('#channel-name #text a').href.split('/').pop();
const thumbnail = el.querySelector('#channel-link img').src;
if (channelId) {
subs.push({ id: channelId, name: channelName, thumbnail: thumbnail });
}
});
if (subs.length > 0) {
// Logic to send 'subs' to your application's state/local storage
// This might involve opening your app's window/tab or directly updating local storage if possible
alert(`Imported ${subs.length} subscriptions!\n(Note: Actual implementation needs to communicate with the main app.)`);
// Example: window.opener.postMessage({ type: 'IMPORT_SUBS', payload: subs }, '*'); // If opened as popup
localStorage.setItem('ks_imported_subs_via_bookmarklet', JSON.stringify(subs));
console.log('Subscriptions:', subs);
} else {
alert('No subscriptions found. Make sure you are on the YouTube subscriptions page.');
}
})();
```
*(Note: The bookmarklet JS requires refinement to properly communicate with the main SPA, potentially using `localStorage` as an intermediate step or opening the app in a specific mode.)*
This prompt provides a detailed blueprint for creating the 'Kanal Sörfü' application. The AI should use this to generate the complete React codebase.