diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..04dbccf --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "semi": true, + "trailingComma": "es5", + "singleQuote": true, + "printWidth": 80, + "tabWidth": 2, + "useTabs": false, + "arrowParens": "avoid" +} diff --git a/src/app/page.tsx b/src/app/page.tsx index 0c66bf4..4ff9b89 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,12 +1,14 @@ -import { GenreList } from "@/components/molecules/GenreList"; -import { MovieList } from "@/components/molecules/MovieList"; -import { TrackedMovies } from "@/components/molecules/TrackedMovies"; +import { GenreList } from '@/components/molecules/GenreList'; +import { MovieList } from '@/components/molecules/MovieList'; +import { RandomMovie } from '@/components/molecules/RandomMovie'; +import { TrackedMovies } from '@/components/molecules/TrackedMovies'; export default async function Home() { return ( <> + ); diff --git a/src/components/molecules/RandomMovie/index.tsx b/src/components/molecules/RandomMovie/index.tsx new file mode 100644 index 0000000..0bea6b4 --- /dev/null +++ b/src/components/molecules/RandomMovie/index.tsx @@ -0,0 +1,137 @@ +'use client'; +import { FC, useMemo, useState } from 'react'; +import { useGlobalStore } from '@/app/store/globalStore'; +import { Button } from '@/components/atoms/Button'; +import { FaDice } from 'react-icons/fa'; +import { useRouter } from 'next/navigation'; +import Link from 'next/link'; +import { Movie } from '@/types/global'; + +type StoreFilter = 'all' | 'not_seen' | 'released' | 'favorites' | 'to_watch'; + +type Props = { + heading?: string; + storeFilter?: StoreFilter; + colors?: keyof typeof colorsMap; + className?: string; +}; + +export const RandomMovie: FC = ({ + heading = 'Losowy film', + storeFilter = 'not_seen', + colors = 'purple', + className = '', +}) => { + const { movies } = useGlobalStore(); + const [selectedMovie, setSelectedMovie] = useState(null); + + // Filter movies based on the selected store filter. + const filteredMovies = useMemo(() => { + const today = new Date(); + + return movies.filter(movie => { + switch (storeFilter) { + case 'not_seen': + return !movie.seen; + case 'released': + return new Date(movie.release_date) < today; + case 'favorites': + return movie.favorite; + case 'to_watch': + return !movie.seen && new Date(movie.release_date) < today; + case 'all': + default: + return true; + } + }); + }, [movies, storeFilter]); + + const handleRandomize = () => { + if (filteredMovies.length === 0) return; + + const randomIndex = Math.floor(Math.random() * filteredMovies.length); + const randomMovie = filteredMovies[randomIndex]; + + setSelectedMovie(randomMovie); + }; + + if (filteredMovies.length === 0) { + return ( +
+
+ {heading && ( +
+
+ +
+

+ {heading} +

+
+ )} +
+

Brak filmów w kategorii

+
+
+
+ ); + } + + return ( +
+
+ {heading && ( +
+

+ {heading} +

+
+ )} + +
+

+ Dostępnych {filteredMovies.length} filmów +

+
+
+ +
+ + {selectedMovie && ( +
+

+ + {selectedMovie.title} + +

+
+ )} +
+
+ ); +}; + +const colorsMap = { + white: 'bg-gradient-to-r from-white to-gray-300', + yellow: 'bg-gradient-to-r from-yellow-400 to-orange-400', + blue: 'bg-gradient-to-r from-blue-400 to-purple-400', + green: 'bg-gradient-to-r from-green-400 to-teal-400', + red: 'bg-gradient-to-r from-red-400 to-pink-400', + purple: 'bg-gradient-to-r from-purple-400 to-pink-400', + orange: 'bg-gradient-to-r from-orange-400 to-yellow-400', + pink: 'bg-gradient-to-r from-pink-400 to-purple-400', + teal: 'bg-gradient-to-r from-teal-400 to-green-400', + gray: 'bg-gradient-to-r from-gray-400 to-gray-400', +}; diff --git a/todo.md b/todo.md index 7451661..1662405 100644 --- a/todo.md +++ b/todo.md @@ -1,36 +1,51 @@ -# +UI/UX Improvements +Dark/Light Mode Toggle - Obecnie tylko ciemny motyw +Responsywny design na urządzenia mobilne - Niektóre komponenty mogą wymagać poprawy +Loading states - Dodać skeletony zamiast spinnerów +Infinite scroll - Zamiast paginacji dla lepszego UX +Gesture support - Swipe na mobilnych dla akcji (dodaj/usuń film) -## ✅ `TODO.md` – Etapy rozwoju aplikacji +Zarządzanie filmami +Własne notatki do filmów - Pole w bazie danych już wspomniane w README +Tagi/kategorie użytkownika - Własne etykiety +Oceny użytkownika - Osobne od TMDB +Data obejrzenia - Kiedy użytkownik obejrzał film +Lista "Do obejrzenia" - Oddzielna od "Obejrzane" +Planowanie seansów - Kalendarz z datami +Eksport/import listy - JSON/CSV backup -```md -# TODO – MovieBox +Funkcje społecznościowe +Udostępnianie list - Link do publicznej listy +Rekomendacje na podstawie gustu - ML/AI sugestie +Porównanie list z znajomymi - Wspólne filmy -## 🔧 Faza 1 – MVP (funkcjonalna wersja lokalna) +Dodatkowe dane i integracje +Informacje o aktorach - Rozszerzone profile (już częściowo jest) +Gdzie obejrzeć - Streaming platforms API +Zwiastuny - YouTube API integration +Recenzje użytkowników - Własne mini-forum +Galeria zdjęć z filmu - Więcej materiałów wizualnych -- [ ] Integracja z TMDB API (wyszukiwanie filmów) -- [ ] Utworzenie bazy danych (SQLite + Drizzle) -- [ ] Modele: Movie, WatchlistEntry -- [ ] Dodanie filmu do watchlisty (z podglądem szczegółów) -- [ ] Lista “Do obejrzenia” i “Obejrzane” -- [ ] Możliwość dodania tagu lub notatki do filmu -- [ ] UI (Tailwind + ShadCN) – responsywna siatka filmów +Performance i techniczne +PWA - Offline support, push notifications o premierach +Lepsze caching - Redis/SWR optimizations +Lazy loading - Obrazy i komponenty +Search indexing - Full-text search w bazie +API rate limiting - Lepsze zarządzanie requestami do TMDB -## 🌐 Faza 2 – Rozszerzenie +Statystyki i analytics +Dashboard statystyk - Filmy obejrzane/miesiąc, ulubione gatunki +Streak tracking - Dni z rzędu oglądania filmów +Cele filmowe - X filmów do obejrzenia w roku +Porównanie z poprzednimi latami - Trendy -- [ ] Podgląd dat premier z TMDB -- [ ] Filtrowanie według daty premiery -- [ ] Sortowanie / filtrowanie po tagach/statusie +Powiadomienia +Email notifications - O premierach z listy +Push notifications - PWA alerts +Reminder system - Przypomnienia o filmach do obejrzenia -## 🔐 Faza 3 – Rozszerzenia prywatne - -- [ ] Dodanie Auth.js (logowanie) -- [ ] Migracja bazy do PostgreSQL -- [ ] Eksport listy filmów (np. JSON) -- [ ] Backup na GitHub (np. GitHub Actions) - -## 💡 Pomysły na później - -- [ ] System rekomendacji (podobne filmy) -- [ ] Powiadomienia o premierach -- [ ] Integracja z Letterboxd -``` +Baza danych i backend +Migracja na PostgreSQL - Jak wspomniano w README +User authentication - Currently brak systemu użytkowników +API endpoints - Własne REST API +Backup system - Automatyczne kopie zapasowe