diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 22a1505..0000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "recommendations": ["astro-build.astro-vscode"], - "unwantedRecommendations": [] -} diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index d642209..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "command": "./node_modules/.bin/astro dev", - "name": "Development server", - "request": "launch", - "type": "node-terminal" - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json index 0013f78..0c203b4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,7 @@ { - "editor.formatOnSave": true, - "[astro]": { - "editor.defaultFormatter": "astro-build.astro-vscode" - }, - "editor.defaultFormatter": "biomejs.biome", - "typescript.tsdk": "node_modules/typescript/lib" -} \ No newline at end of file + "editor.formatOnSave": true, + "editor.defaultFormatter": "biomejs.biome", + "[astro]": { + "editor.defaultFormatter": "astro-build.astro-vscode" + } +} diff --git a/bun.lockb b/bun.lockb index 56658e6..aa6a593 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 893537b..9dbae8a 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "astro": "astro" }, "dependencies": { - "@astrojs/check": "^0.8.0", + "@astrojs/check": "^0.8.1", "@astrojs/node": "^8.3.2", "@astrojs/react": "^3.6.0", "@types/react": "^18.3.3", diff --git a/src/components/DebouceInput.tsx b/src/components/DebouceInput.tsx index e691831..57f6396 100644 --- a/src/components/DebouceInput.tsx +++ b/src/components/DebouceInput.tsx @@ -33,6 +33,10 @@ export default function DebounceInput(props: DebouceInputProps) { () => props.onDebounce(e.target.value), props.debouceDelay, ); + + if (props.onChange) { + props.onChange(e); + } } const inputAttr = { @@ -45,9 +49,11 @@ export default function DebounceInput(props: DebouceInputProps) { ); } diff --git a/src/components/MoviesSearchInput.tsx b/src/components/MoviesSearchInput.tsx new file mode 100644 index 0000000..eda929c --- /dev/null +++ b/src/components/MoviesSearchInput.tsx @@ -0,0 +1,37 @@ +import { useState } from "react"; +import DebounceInput from "./DebouceInput"; + +interface MoviesSearchInput { + searchUrl: string; +} + +export default function MoviesSearchInput({ searchUrl }: MoviesSearchInput) { + const [value, setValue] = useState(""); + + function handleOnDebounce(value: string) {} + + function handleOnChange(event: React.ChangeEvent) { + setValue(event.target.value); + } + + function handleOnKeyDown(e: React.KeyboardEvent) { + if (e.key === "Enter") { + window.location.href = `${searchUrl}?q=${value}`; + } + } + + return ( +
+ + +
+ ); +} diff --git a/src/components/forms/MovieFormData.tsx b/src/components/forms/MovieFormData.tsx index 30306f7..fff30d5 100644 --- a/src/components/forms/MovieFormData.tsx +++ b/src/components/forms/MovieFormData.tsx @@ -2,12 +2,15 @@ import { useState } from "react"; import type { CreateMovie } from "../../types"; import MovieForm from "./MovieForm"; +declare let bootstrap: any; + interface MovieFormDataProps { defaultValue?: CreateMovie; } export default function MovieFormData({ defaultValue }: MovieFormDataProps) { const [loading, setLoading] = useState(false); + const [showModal, setShowModal] = useState(false); function handleOnSubmit(createMovie: CreateMovie) { const searchParams = new URLSearchParams(window.location.search); @@ -24,6 +27,11 @@ export default function MovieFormData({ defaultValue }: MovieFormDataProps) { }) .then((res) => res.json()) .then((movie) => { + const myModal = new bootstrap.Modal( + document.getElementById("exampleModal"), + ); + + myModal?.show(); console.log(movie); }) .catch((err) => console.log(err)) @@ -31,10 +39,44 @@ export default function MovieFormData({ defaultValue }: MovieFormDataProps) { } return ( - + <> + + + ); } diff --git a/src/components/lists/movies/CardMoviesList.tsx b/src/components/lists/movies/CardMoviesList.tsx new file mode 100644 index 0000000..d9380ad --- /dev/null +++ b/src/components/lists/movies/CardMoviesList.tsx @@ -0,0 +1,18 @@ +import type { Movie } from "../../../types"; +import CardMoviesListItem from "./CardMoviesListItem"; + +interface CardMoviesListProps { + movies: Movie[]; +} + +export default function CardMoviesList({ movies }: CardMoviesListProps) { + const items = movies.map((elt) => { + return ( +
+ +
+ ); + }); + + return
{items}
; +} diff --git a/src/components/lists/movies/CardMoviesListItem.tsx b/src/components/lists/movies/CardMoviesListItem.tsx new file mode 100644 index 0000000..a7c2ce8 --- /dev/null +++ b/src/components/lists/movies/CardMoviesListItem.tsx @@ -0,0 +1,50 @@ +import { FaEye } from "react-icons/fa"; +import type { Movie } from "../../../types"; + +interface CardMoviesListItemProps { + movie: Movie; +} + +export default function CardMoviesListItem({ movie }: CardMoviesListItemProps) { + return ( +
+
+
+
+
+
+
+ {movie.title} +
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+ ); +} diff --git a/src/layouts/RootLayout.astro b/src/layouts/RootLayout.astro index b1fcb9e..3229bd9 100644 --- a/src/layouts/RootLayout.astro +++ b/src/layouts/RootLayout.astro @@ -6,6 +6,7 @@ interface Props { const { title } = Astro.props; import "bootstrap/dist/css/bootstrap.min.css"; +import "../styles/index.css"; --- @@ -19,7 +20,7 @@ import "bootstrap/dist/css/bootstrap.min.css"; {title} -
+
diff --git a/src/pages/home/index.astro b/src/pages/home/index.astro index 3163211..719ce9d 100644 --- a/src/pages/home/index.astro +++ b/src/pages/home/index.astro @@ -1,9 +1,43 @@ --- +import MoviesSearchInput from "../../components/MoviesSearchInput"; +import CardMoviesList from "../../components/lists/movies/CardMoviesList"; import HomeLayout from "../../layouts/HomeLayout.astro"; +import type { Movie } from "../../types"; +const jwt = Astro.cookies.get("jwt")?.value as string; +const url = new URL(Astro.request.url); + +const queryParams = new URLSearchParams(); +const query = url.searchParams.get("q"); + +if (query) { + queryParams.append("q", query); +} + +const res = await fetch( + `${import.meta.env.API_URL}/movies?${queryParams.toString()}`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwt}`, + }, + }, +); + +const resBody = (await res.json()) as { movies: Movie[] }; const account = Astro.locals.account; --- - Hello {account?.username} +
+
+ +
+
+
+
+ +
+
diff --git a/src/pages/home/movies/[id].astro b/src/pages/home/movies/[id].astro new file mode 100644 index 0000000..5a54344 --- /dev/null +++ b/src/pages/home/movies/[id].astro @@ -0,0 +1,61 @@ +--- +import { FaEye } from "react-icons/fa"; +import HomeLayout from "../../../layouts/HomeLayout.astro"; +import type { Movie } from "../../../types"; + +const jwt = Astro.cookies.get("jwt")?.value as string; +const { id } = Astro.params; + +const res = await fetch(`${import.meta.env.API_URL}/movies/${id}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwt}`, + }, +}); + +const movie = (await res.json()).movie as Movie; +--- + + + <> +

{movie.title}

+
+
+
+
+

{movie.overview}

+
+
+ +
+ + +
+
+
+
+ +
diff --git a/src/pages/home/settings/movies.astro b/src/pages/home/settings/movies.astro index 52a09de..e1fc2e0 100644 --- a/src/pages/home/settings/movies.astro +++ b/src/pages/home/settings/movies.astro @@ -1,6 +1,5 @@ --- import AddMovieForm from "../../../components/forms/AddMovieForm"; -import TmdbSearch from "../../../components/TmdbSearch"; import HomeLayout from "../../../layouts/HomeLayout.astro"; --- diff --git a/src/pages/index.astro b/src/pages/index.astro index e80e5d5..446aa3c 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -4,5 +4,5 @@ import EmptyLayout from "../layouts/EmptyLayout.astro"; --- - + diff --git a/src/styles/index.css b/src/styles/index.css new file mode 100644 index 0000000..217912a --- /dev/null +++ b/src/styles/index.css @@ -0,0 +1,27 @@ +.cardshadow { + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.4); + transition: box-shadow 0.2s ease-in-out; +} + +.cardshadow:hover { + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.8); +} + +.movieitem { + opacity: 0; + background-color: rgba(0, 0, 0, 0.75); + color: rgba(255, 255, 255, 1); +} + +.movieitem:hover { + animation: 0.2s ease-in-out forwards moviehover; +} + +@keyframes moviehover { + from { + opacity: 0; + } + to { + opacity: 1; + } +}