Fix dark mode parziale e fix remove film e episode

This commit is contained in:
Lovi 2024-12-13 17:18:32 +01:00
parent c093687e9f
commit 29f8edf7a4
11 changed files with 92 additions and 37 deletions

View File

@ -1,17 +1,18 @@
Per testare
1. Installare requirements
2. Inserire url per mongodb e creare database
3. Runnare server.py
0. Installare nodejs "https://nodejs.org/en/download/package-manager"
1. Installare requirements "pip install -r "requirements.txt"
2. Inserire url per mongodb "https://www.mongodb.com/it-it"
3. Eseguire server.py con "python server.py"
4. Spostarsi su client\dashboard
5. Eseguire npm install, npm run build, npm install -g serve
Cosa da fare
- Dark mode su tutta la pagina
- Aggiungere documentazione
- Bottone download intera stagione
- Messaggio con richiesta se scaricare le nuove stagione quando si fa il check in watchlist
- Migliore player in case watch con bottone
- Coda di download con bottone aggiungere alla coda (complessa)
- MIgliorare dark mode.
- Aggiungere documentazione.
- Migliorare controlli.
- Aggiungere bottone per scaricare una stagione intera.
- Messaggio con richiesta se scaricare le nuove stagione quando si fa il check in watchlist.
- Migliore player in case watch con bottone.
- Coda di download con bottone aggiungere alla coda.
...

View File

@ -8,12 +8,21 @@
gap: 20px;
}
.search-results-container {
background-color: var(--background-color);
color: var(--text-color);
}
.search-result-item {
cursor: pointer;
transition: transform 0.3s ease;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
background-color: #f0f0f0; /* Default (light mode) */
color: var(--text-color);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2);
}
@media (prefers-color-scheme: dark) {
.search-result-item {
background-color: #1e1e1e;
}
}
.search-result-item:hover {

View File

@ -35,11 +35,11 @@ function App() {
<Router>
<Navbar toggleTheme={toggleTheme} theme={theme} />
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/search" element={<SearchResults />} />
<Route path="/title/:id" element={<TitleDetail />} />
<Route path="/watchlist" element={<Watchlist />} />
<Route path="/downloads" element={<Downloads />} />
<Route path="/" element={<Dashboard theme={theme} />} />
<Route path="/search" element={<SearchResults theme={theme} />} />
<Route path="/title/:id" element={<TitleDetail theme={theme} />} />
<Route path="/watchlist" element={<Watchlist theme={theme} />} />
<Route path="/downloads" element={<Downloads theme={theme} />} />
</Routes>
</Router>
);

View File

@ -1,11 +1,12 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import axios from 'axios';
import { Container, Button, Form, InputGroup } from 'react-bootstrap';
import SearchBar from './SearchBar.js';
import { API_URL } from './ApiUrl.js';
const Dashboard = () => {
const Dashboard = ({ theme }) => {
const [items, setItems] = useState([]);
useEffect(() => {
@ -26,7 +27,10 @@ const Dashboard = () => {
};
return (
<Container fluid className="p-4">
<Container fluid className="p-4" style={{
backgroundColor: theme === 'dark' ? '#121212' : '#ffffff',
color: theme === 'dark' ? '#ffffff' : '#000000'
}}>
<h1 className="mb-4">Dashboard</h1>
<div className="d-flex justify-content-between align-items-center mb-4">
@ -37,4 +41,9 @@ const Dashboard = () => {
);
};
Dashboard.propTypes = {
toggleTheme: PropTypes.func.isRequired,
theme: PropTypes.oneOf(['light', 'dark']).isRequired,
};
export default Dashboard;

View File

@ -1,4 +1,5 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import axios from 'axios';
import { Container, Row, Col, Card, Button, Badge, Modal } from 'react-bootstrap';
import { FaTrash, FaPlay } from 'react-icons/fa';
@ -6,7 +7,7 @@ import { Link } from 'react-router-dom';
import { SERVER_PATH_URL, SERVER_DELETE_URL, API_URL } from './ApiUrl';
const Downloads = () => {
const Downloads = ({ theme }) => {
const [downloads, setDownloads] = useState([]);
const [loading, setLoading] = useState(true);
const [showPlayer, setShowPlayer] = useState(false);
@ -28,7 +29,7 @@ const Downloads = () => {
const handleDeleteEpisode = async (id, season, episode) => {
try {
await axios.delete(`${SERVER_DELETE_URL}/episode`, {
params: { id, season, episode }
params: { series_id: id, season_number: season, episode_number: episode }
});
fetchDownloads(); // Refresh the list
} catch (error) {
@ -40,7 +41,7 @@ const Downloads = () => {
const handleDeleteMovie = async (id) => {
try {
await axios.delete(`${SERVER_DELETE_URL}/movie`, {
params: { id }
params: { movie_id: id }
});
fetchDownloads(); // Refresh the list
} catch (error) {
@ -80,7 +81,10 @@ const Downloads = () => {
}, {});
return (
<Container fluid className="p-0">
<Container fluid className="p-0" style={{
backgroundColor: theme === 'dark' ? '#121212' : '#ffffff',
color: theme === 'dark' ? '#ffffff' : '#000000'
}}>
<Container className="mt-4">
<h2 className="mb-4">My Downloads</h2>
@ -195,4 +199,9 @@ const Downloads = () => {
);
};
Downloads.propTypes = {
toggleTheme: PropTypes.func.isRequired,
theme: PropTypes.oneOf(['light', 'dark']).isRequired,
};
export default Downloads;

View File

@ -22,7 +22,7 @@ const SearchBar = ({ onSearch }) => {
};
return (
<Form onSubmit={handleSearch} className="w-100">
<Form onSubmit={handleSearch} className="w-100" >
<InputGroup>
<Form.Control
type="text"

View File

@ -1,4 +1,5 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { useLocation, useNavigate } from 'react-router-dom';
import axios from 'axios';
import { Container, Row, Col, Card, Spinner } from 'react-bootstrap';
@ -6,7 +7,7 @@ import { Container, Row, Col, Card, Spinner } from 'react-bootstrap';
import SearchBar from './SearchBar.js';
import { API_URL } from './ApiUrl.js';
const SearchResults = () => {
const SearchResults = ({ theme }) => {
const [results, setResults] = useState([]);
const [loading, setLoading] = useState(true);
const location = useLocation();
@ -44,7 +45,10 @@ const SearchResults = () => {
};
return (
<Container fluid className="p-4">
<Container fluid className="p-4" style={{
backgroundColor: theme === 'dark' ? '#121212' : '#ffffff',
color: theme === 'dark' ? '#ffffff' : '#000000'
}}>
<div className="mb-4">
<SearchBar />
</div>
@ -91,4 +95,10 @@ const SearchResults = () => {
);
};
SearchResults.propTypes = {
toggleTheme: PropTypes.func.isRequired,
theme: PropTypes.oneOf(['light', 'dark']).isRequired,
};
export default SearchResults;

View File

@ -1,5 +1,6 @@
import React, { useState, useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import PropTypes from 'prop-types';
import axios from 'axios';
import { Container, Row, Col, Image, Button, Dropdown, Modal, Alert } from 'react-bootstrap';
import { FaDownload, FaPlay, FaPlus, FaTrash } from 'react-icons/fa';
@ -8,7 +9,7 @@ import SearchBar from './SearchBar.js';
import { API_URL, SERVER_WATCHLIST_URL, SERVER_PATH_URL } from './ApiUrl.js';
const TitleDetail = () => {
const TitleDetail = ({ theme }) => {
const [titleDetails, setTitleDetails] = useState(null);
const [loading, setLoading] = useState(true);
const [selectedSeason, setSelectedSeason] = useState(1);
@ -233,7 +234,10 @@ const TitleDetail = () => {
}
return (
<Container fluid className="p-0">
<Container fluid className="p-0" style={{
backgroundColor: theme === 'dark' ? '#121212' : '#ffffff',
color: theme === 'dark' ? '#ffffff' : '#000000'
}}>
<SearchBar />
{/* Background Image */}
@ -406,4 +410,9 @@ const TitleDetail = () => {
);
};
TitleDetail.propTypes = {
toggleTheme: PropTypes.func.isRequired,
theme: PropTypes.oneOf(['light', 'dark']).isRequired,
};
export default TitleDetail;

View File

@ -1,16 +1,17 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import PropTypes from 'prop-types';
import { Container, Row, Col, Card, Button, Badge, Alert } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import { FaTrash } from 'react-icons/fa';
import { SERVER_WATCHLIST_URL } from './ApiUrl';
const Watchlist = () => {
const Watchlist = ({ theme }) => {
const [watchlistItems, setWatchlistItems] = useState([]);
const [newSeasons, setNewSeasons] = useState([]);
const [loading, setLoading] = useState(true);
const [newSeasonsMessage, setNewSeasonsMessage] = useState(""); // Stato per il messaggio delle nuove stagioni
const [newSeasonsMessage, setNewSeasonsMessage] = useState("");
// Funzione per recuperare i dati della watchlist
const fetchWatchlistData = async () => {
@ -93,7 +94,10 @@ const Watchlist = () => {
}
return (
<Container fluid className="p-0">
<Container fluid className="p-0" style={{
backgroundColor: theme === 'dark' ? '#121212' : '#ffffff',
color: theme === 'dark' ? '#ffffff' : '#000000'
}}>
<Container className="mt-4">
<h2 className="mb-4">My Watchlist</h2>
@ -162,4 +166,9 @@ const Watchlist = () => {
);
};
Watchlist.propTypes = {
toggleTheme: PropTypes.func.isRequired,
theme: PropTypes.oneOf(['light', 'dark']).isRequired,
};
export default Watchlist;

View File

@ -13,5 +13,4 @@ qbittorrent-api
python-qbittorrent
googlesearch-python
pymongo
fastapi
pyclean
fastapi

View File

@ -449,7 +449,7 @@ async def remove_episode(series_id: int = Query(...), season_number: int = Query
return {"success": True}
@app.delete("/server/delete/movie")
async def remove_movie(movie_id: int = Query(...)):
async def remove_movie(movie_id: str = Query(...)):
movie = downloads_collection.find_one({'type': 'movie', 'id': movie_id}, {'_id': 0, 'path': 1})
if not movie: