PROJECT OVERVIEW:
The application is called 'Retro Weather' and aims to provide weather information with a distinct retro, vintage computer or old-school game console aesthetic. It solves the problem of monotonous and generic weather app interfaces by offering a nostalgic and visually unique user experience. The core value proposition is to deliver accurate weather data through a highly stylized, retro-themed interface that evokes feelings of nostalgia and offers a fun alternative to standard weather apps.
TECH STACK:
- Framework: Next.js (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- ORM: Drizzle ORM with PostgreSQL (using Neon or similar managed PostgreSQL)
- UI Components: shadcn/ui for accessible and customizable components
- Authentication: NextAuth.js (or Clerk for easier integration)
- State Management: React Context API / Zustand
- Data Fetching: React Server Components, fetch API, SWR (for client-side caching if needed)
- Icons: Lucide React
- Form Handling: react-hook-form with Zod for validation
- Deployment: Vercel
- Other Libraries: `date-fns` for date manipulation, `axios` (if needed for external APIs), charting library (e.g., `chart.js` if complex visualizations are added later, but not for MVP).
DATABASE SCHEMA (using Drizzle ORM with PostgreSQL):
1. `users` table:
- `id`: uuid PRIMARY KEY (generated by server)
- `name`: text
- `email`: text UNIQUE NOT NULL
- `emailVerified`: timestamp with time zone
- `image`: text
- `createdAt`: timestamp with time zone DEFAULT now()
- `updatedAt`: timestamp with time zone DEFAULT now()
2. `accounts` table (for NextAuth.js):
- `id`: uuid PRIMARY KEY
- `userId`: uuid REFERENCES `users`(`id`) ON DELETE CASCADE
- `type`: text
- `provider`: text
- `providerAccountId`: text
- `refresh_token`: text
- `access_token`: text
- `expires_at`: bigint
- `token_type`: text
- `scope`: text
- `id_token`: text
3. `sessions` table (for NextAuth.js):
- `sessionToken`: text PRIMARY KEY
- `userId`: uuid REFERENCES `users`(`id`) ON DELETE CASCADE
- `expires`: timestamp with time zone NOT NULL
4. `verificationTokens` table (for NextAuth.js):
- `identifier`: text
- `token`: text PRIMARY KEY
- `expires`: timestamp with time zone NOT NULL
5. `favoriteLocations` table:
- `id`: uuid PRIMARY KEY
- `userId`: uuid REFERENCES `users`(`id`) ON DELETE CASCADE
- `name`: text NOT NULL
- `latitude`: decimal NOT NULL
- `longitude`: decimal NOT NULL
- `createdAt`: timestamp with time zone DEFAULT now()
- UNIQUE (`userId`, `name`) // Prevent duplicate location names for the same user
6. `userSettings` table:
- `id`: uuid PRIMARY KEY
- `userId`: uuid REFERENCES `users`(`id`) ON DELETE CASCADE UNIQUE
- `units`: text DEFAULT 'metric' CHECK (`units` IN ('metric', 'imperial'))
- `theme`: text DEFAULT 'default' // e.g., 'default', 'c64', 'atari', 'dos'
- `updatedAt`: timestamp with time zone DEFAULT now()
CORE FEATURES & USER FLOW:
1. Authentication Flow:
- User lands on the homepage.
- Option to 'Sign In' or 'Sign Up'.
- Sign Up: Email, Password fields. On submit, validate input, create user in `users` table, create default entry in `userSettings`. Redirect to dashboard.
- Sign In: Email, Password fields. On submit, validate input, authenticate using NextAuth.js. Redirect to dashboard.
- OAuth (Google/Apple): Click button, redirect to provider, return, create/login user, redirect to dashboard.
- Sign Out: Button in user menu, clears session, redirects to homepage.
2. Weather Display (Homepage/Dashboard):
- If logged in: Automatically detect location (browser geolocation API) or use the first saved favorite location.
- If not logged in: Prompt for location permission or allow manual input.
- Fetch current weather data using a reliable weather API (e.g., OpenWeatherMap, WeatherAPI.com) based on coordinates or city name.
- Display current weather data (temp, condition, wind speed/direction, humidity, pressure, visibility, dew point, heat index) using retro-themed UI components.
- Display today's high/low and a brief forecast summary.
- User Flow: Load page -> Detect/Input Location -> Fetch Weather API -> Render Retro UI.
3. 5-Day Forecast:
- Accessible via a button/tab on the main weather display.
- Fetch daily forecast data (high/low temp, condition summary) for the next 5 days from the weather API.
- Render forecast data in a retro, list-like format (e.g., similar to old command-line outputs or simple pixelated grids).
- User Flow: Main Display -> Click 'Forecast' -> Fetch Forecast API -> Render Forecast List.
4. Favorite Locations Management:
- On the Dashboard, an option to 'Add Location'.
- Input field for city name or address. Geocoding API to get lat/lon.
- Save location (name, lat, lon) to the `favoriteLocations` table, linked to the logged-in user.
- Display a list of saved favorite locations in a dropdown or sidebar.
- Clicking a favorite location fetches and displays its weather.
- Option to remove/delete a favorite location.
- User Flow: Dashboard -> Add Location -> Input Name/Search -> Save -> Location appears in list -> Select Location -> Display Weather.
5. Settings Page:
- Accessible from the user menu.
- Allows users to change units (Celsius/Fahrenheit) and select different retro themes.
- Update `userSettings` table.
- User Flow: Dashboard -> User Menu -> Settings -> Change Unit/Theme -> Save -> UI updates apply.
API & DATA FETCHING:
- Weather API: Use a third-party API (e.g., OpenWeatherMap API Key). Needs endpoints for current weather and forecast. Data will be fetched server-side in Server Components or client-side if required for dynamic updates without page reloads.
- Example Current Weather Endpoint (`/api/weather/current` - Server Action or Route Handler):
- POST Request Body: `{ latitude: number, longitude: number, units: 'metric' | 'imperial' }`
- Response Body (JSON): `{ temp: number, feels_like: number, humidity: number, pressure: number, visibility: number, dew_point: number, heat_index: number, description: string, icon: string, wind_speed: number, wind_deg: number, city: string, country: string, sunrise: number, sunset: number }`
- Example Forecast Endpoint (`/api/weather/forecast` - Server Action or Route Handler):
- POST Request Body: `{ latitude: number, longitude: number, units: 'metric' | 'imperial' }`
- Response Body (JSON): `[{ date: string, temp_high: number, temp_low: number, description: string, icon: string }, ...]`
- Geocoding API (if needed for adding locations): Use a service like OpenCage Geocoding or Nominatim to convert addresses to lat/lon.
- NextAuth.js: Handles authentication API routes (`/api/auth/...`).
- Drizzle ORM: Used for all database interactions within Route Handlers or Server Actions.
UI/UX DESIGN & VISUAL IDENTITY:
- Design Style: "Retro Computer Terminal" / "8-bit Game UI". Think C64, early DOS games, or Game Boy aesthetics.
- Color Palette:
- Primary: Deep Black (`#000000`)
- Secondary: Dark Gray (`#1E1E1E`)
- Accent 1: Neon Green (`#00FF00`)
- Accent 2: Bright Cyan (`#00FFFF`)
- Accent 3: Electric Blue (`#0000FF`)
- Text: White (`#FFFFFF`), Light Gray (`#CCCCCC`)
- Typography:
- Headings: Pixelated/Monospaced font (e.g., 'Press Start 2P' from Google Fonts, or a similar free alternative).
- Body Text: Monospaced font (e.g., 'VT323', 'IBM Plex Mono').
- Layout:
- Primarily centered content blocks with distinct borders.
- Use of scanlines effect for screen background (optional, can be a theme option).
- Information presented in distinct, bordered sections (like terminal output).
- Minimal use of whitespace; elements are tightly packed.
- Responsive Rules:
- Mobile: Single column layout, elements stack vertically. Ensure touch targets are large enough.
- Tablet/Desktop: Wider layout, potentially 2 columns for forecast or side-by-side info. Maintain the retro feel.
- Animations:
- Typing effect for text elements (subtle, optional).
- Fade-ins/outs for new data loading.
- Subtle pulsing or blinking for active elements.
- Smooth transitions between themes.
COMPONENT BREAKDOWN (Next.js App Router):
- `app/layout.tsx`: Root layout, includes global styles, providers (Auth, Theme), main HTML structure.
- `app/page.tsx`: Landing page (if not logged in) or the main Dashboard/Weather Display (if logged in).
- Contains `WeatherDisplay` and `ForecastSection` components.
- Handles initial location detection/input.
- `app/auth/signin/page.tsx`: Sign-in page with email/password and OAuth options.
- `app/dashboard/page.tsx`: (If separate from root) User dashboard.
- `app/settings/page.tsx`: User settings page.
- Includes `ThemeSelector`, `UnitSelector` components.
- `app/favorites/page.tsx`: Page to manage favorite locations.
- `components/ui/` (shadcn/ui components):
- `Button`
- `Input`
- `Card`
- `Dialog` / `Modal`
- `DropdownMenu`
- `Separator`
- `Switch`
- `Label`
- `Tooltip`
- `components/` (Custom components):
- `Header.tsx`: Top navigation bar with logo, auth status, links.
- `Footer.tsx`: Simple footer.
- `Sidebar.tsx`: For favorite locations navigation (optional).
- `UserProfileMenu.tsx`: Dropdown for user profile, settings, logout.
- `WeatherDisplay.tsx`: Core component for current weather data. Fetches data via Server Actions/Components.
- Sub-components: `CurrentTemp.tsx`, `WeatherIcon.tsx`, `WindDisplay.tsx`, etc.
- `ForecastSection.tsx`: Displays the 5-day forecast.
- Sub-components: `ForecastDayCard.tsx`.
- `LocationInput.tsx`: Form for searching/adding new locations.
- `FavoriteLocationList.tsx`: Displays the list of user's favorite locations.
- `ThemeSelector.tsx`: UI for choosing between retro themes.
- `UnitSelector.tsx`: UI for choosing metric/imperial units.
- `RetroDisplay.tsx`: A wrapper component to apply retro styling (borders, pixel fonts, background effects) to its children.
- `LoadingSpinner.tsx`: Retro-styled loading indicator.
- `lib/`: Utility functions, API client setup, database connection (Drizzle).
- `styles/globals.css`: Tailwind CSS configuration and global styles.
- `hooks/`: Custom React hooks (e.g., `useTheme`, `useAuth`).
State Management:
- Global state (Auth, User Settings, Theme) managed by Context API or Zustand.
- Server Component data is directly rendered; client-side fetching uses SWR or component-level `useState`.
- Form state managed by `react-hook-form`.
ANIMATIONS:
- Page Transitions: Subtle fade-in/out between pages using `AnimatePresence` (if using `framer-motion`) or CSS transitions.
- Data Loading: Use `LoadingSpinner.tsx` with a blinking cursor or pixelated animation when fetching weather data. `[...loading.tsx]` files in App Router.
- Element Hover Effects: Subtle color changes or slight scaling for buttons and interactive elements, fitting the retro style (e.g., "color cycling" effect on hover).
- Input Field Focus: A blinking caret/cursor effect when an input field is focused.
- Theme Switch: Smooth transition (cross-fade) when switching themes.
EDGE CASES:
- **No Location Data**: If browser geolocation fails or is denied, prompt the user to enter a location manually or select a favorite.
- **API Errors**: Gracefully handle errors from the weather API (e.g., rate limits, invalid key, network issues). Display a retro-styled error message (e.g., "ERROR: API CONNECTION FAILED") and potentially retry logic.
- **Empty States**: For favorite locations or initial dashboard load, display informative messages in the retro style (e.g., "NO FAVORITE LOCATIONS SAVED. ADD ONE!").
- **Authentication**: Implement robust authentication using NextAuth.js. Protect routes that require login. Handle expired sessions.
- **Validation**: Use Zod with `react-hook-form` for all form inputs (sign up, login, add location) on both client and server sides.
- **Invalid City/Location Input**: Handle cases where the Geocoding API or Weather API doesn't recognize the entered location. Provide clear feedback.
- **Offline Mode**: (Future consideration) Cache current weather data for offline viewing.
SAMPLE/MOCK DATA:
1. **Current Weather (Metric):**
`{ temp: 15, feels_like: 14, humidity: 75, pressure: 1012, visibility: 10, dew_point: 10, heat_index: 15, description: 'Partly Cloudy', icon: '02d', wind_speed: 5, wind_deg: 180, city: 'London', country: 'UK', sunrise: 1678876800, sunset: 1678919400 }`
2. **Current Weather (Imperial):**
`{ temp: 59, feels_like: 57, humidity: 75, pressure: 29.98, visibility: 10, dew_point: 50, heat_index: 59, description: 'Partly Cloudy', icon: '02d', wind_speed: 3, wind_deg: 180, city: 'London', country: 'UK', sunrise: 1678876800, sunset: 1678919400 }`
3. **5-Day Forecast (Day 1 - Metric):**
`{ date: '2023-03-16', temp_high: 18, temp_low: 9, description: 'Sunny', icon: '01d' }`
4. **5-Day Forecast (Day 2 - Imperial):**
`{ date: '2023-03-17', temp_high: 64, temp_low: 48, description: 'Light Rain', icon: '10d' }`
5. **Favorite Location:**
`{ id: 'uuid-1', userId: 'user-uuid', name: 'New York', latitude: 40.7128, longitude: -74.0060, createdAt: '2023-01-15T10:00:00Z' }`
6. **Favorite Location:**
`{ id: 'uuid-2', userId: 'user-uuid', name: 'Tokyo', latitude: 35.6895, longitude: 139.6917, createdAt: '2023-01-16T11:30:00Z' }`
7. **User Settings:**
`{ id: 'user-uuid', userId: 'user-uuid', units: 'metric', theme: 'c64', updatedAt: '2023-02-01T09:00:00Z' }`
8. **User (for Auth):**
`{ id: 'user-uuid', name: 'John Doe', email: 'john.doe@example.com', image: 'null', createdAt: '2023-01-01T12:00:00Z', updatedAt: '2023-01-01T12:00:00Z' }`
9. **Empty Favorite Locations State:**
`[]` (Rendered with a message like "NO LOCATIONS SAVED")
10. **API Error Response Mock:**
`{ error: { code: 401, message: 'Invalid API Key' } }` (Display as "API KEY ERROR")
11. **Loading State Mock:**
`null` (Render `LoadingSpinner` component)
TURKISH TRANSLATIONS:
- App Title: Retro Hava Durumu
- Sign In: Giriş Yap
- Sign Up: Kayıt Ol
- Email: E-posta
- Password: Şifre
- Forgot Password: Şifremi Unuttum
- Add Location: Konum Ekle
- Favorite Locations: Favori Konumlar
- Settings: Ayarlar
- Units: Birimler
- Metric: Metrik
- Imperial: İmparatorluk
- Theme: Tema
- Logout: Çıkış Yap
- Search: Ara
- Save: Kaydet
- Cancel: İptal
- Current Weather: Mevcut Hava Durumu
- Today's Forecast: Bugünkü Tahmin
- High: Yüksek
- Low: Düşük
- Humidity: Nem
- Pressure: Basınç
- Visibility: Görüş Mesafesi
- Wind Speed: Rüzgar Hızı
- Wind Direction: Rüzgar Yönü
- Add to Favorites: Favorilere Ekle
- Remove from Favorites: Favorilerden Kaldır
- Loading: Yükleniyor...
- Error: Hata
- No data available: Veri mevcut değil
- Weather condition descriptions (e.g., Cloudy, Sunny, Rainy): Bulutlu, Güneşli, Yağmurlu
- Add New Location: Yeni Konum Ekle
- Manage Favorites: Favorileri Yönet
- Select Theme: Tema Seç
- Default Theme: Varsayılan Tema
- C64 Theme: C64 Teması
- Atari Theme: Atari Teması
- DOS Theme: DOS Teması
- Terms of Service: Hizmet Şartları
- Privacy Policy: Gizlilik Politikası