From 1126852db4dd91bb90bb955af6df8cad7729fe14 Mon Sep 17 00:00:00 2001 From: Emma Fredriksen Date: Thu, 3 Sep 2026 15:07:10 +0200 Subject: [PATCH 1/5] feat: fetch and display characters --- src/main.tsx | 2 ++ src/pages/CharactersPage.tsx | 48 ++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/pages/CharactersPage.tsx diff --git a/src/main.tsx b/src/main.tsx index bef5202..5b4f9dc 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,9 +2,11 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' import App from './App.tsx' +import CharactersPage from './pages/CharactersPage.tsx' createRoot(document.getElementById('root')!).render( + , ) diff --git a/src/pages/CharactersPage.tsx b/src/pages/CharactersPage.tsx new file mode 100644 index 0000000..54b3317 --- /dev/null +++ b/src/pages/CharactersPage.tsx @@ -0,0 +1,48 @@ +import { useEffect, useState } from "react"; + +type Character = { + id: number; + name: string; + species: string; + status: string; + gender: string; + origin: string; + image: string; +}; + +export default function CharactersPage(){ + + const [characters, setCharacters] = useState([]); + + + + useEffect(() => { + async function fetchCharacters(){ + try{ + const response = await fetch("https://rickandmortyapi.com/api/character"); + + if (!response.ok) { + throw new Error('Could not fetch characters') + } + + const data = await response.json(); + setCharacters(data.results); + console.log(data.results) + } + catch(error) { + console.error(error); + } + } + fetchCharacters() + }, []) + + return( + <> + {characters.map((character) => ( +
{character.name} + +
+ ))} + + ) +} \ No newline at end of file From b3ce48983c7be97c6195db184713315d02064f40 Mon Sep 17 00:00:00 2001 From: Emma Fredriksen Date: Sun, 6 Sep 2026 16:29:08 +0200 Subject: [PATCH 2/5] feat: make cards responsive and set up layout --- src/assets/card-shape.svg | 23 +++++ src/assets/search.svg | 1 + src/assets/star.svg | 1 + src/components/CharacterCardSmall.css | 125 ++++++++++++++++++++++++++ src/components/CharacterCardSmall.tsx | 28 ++++++ src/components/placeHolderComp.tsx | 0 src/index.css | 7 +- src/pages/CharactersPage.css | 94 +++++++++++++++++++ src/pages/CharactersPage.tsx | 65 +++++++++++++- src/pages/placeholderPage.tsx | 0 10 files changed, 336 insertions(+), 8 deletions(-) create mode 100644 src/assets/card-shape.svg create mode 100644 src/assets/search.svg create mode 100644 src/assets/star.svg create mode 100644 src/components/CharacterCardSmall.css create mode 100644 src/components/CharacterCardSmall.tsx delete mode 100644 src/components/placeHolderComp.tsx create mode 100644 src/pages/CharactersPage.css delete mode 100644 src/pages/placeholderPage.tsx diff --git a/src/assets/card-shape.svg b/src/assets/card-shape.svg new file mode 100644 index 0000000..f31c980 --- /dev/null +++ b/src/assets/card-shape.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/search.svg b/src/assets/search.svg new file mode 100644 index 0000000..4e85ae4 --- /dev/null +++ b/src/assets/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/star.svg b/src/assets/star.svg new file mode 100644 index 0000000..44e0f1b --- /dev/null +++ b/src/assets/star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/CharacterCardSmall.css b/src/components/CharacterCardSmall.css new file mode 100644 index 0000000..b5c2fbf --- /dev/null +++ b/src/components/CharacterCardSmall.css @@ -0,0 +1,125 @@ +.card-content{ + container-type: inline-size; + position: relative; + display: flex; + align-items: center; + justify-content: center; + + width: 19rem; + height: 25.5rem; + border-radius: 1.5rem; + background-color: #5A7D0D; + +} + +@media (min-width: 600px){ + .card-content{ + container-type: inline-size; + position: relative; + display: flex; + align-items: center; + justify-content: center; + + width: 12rem; + height: 16.5rem; + border-radius: 1.5rem; + background-color: #5A7D0D; + } +} + +.card-shape{ + position: absolute; + width: 18rem; + height: 23rem +} + +@media (min-width:600px){ + .card-shape{ + position: absolute; + width: 11rem; + height: 16rem + } +} + +.character-info{ + display: flex; + text-align: center; + flex-direction: column; + align-items: center; + position: absolute; + color:white; + z-index: 1; +} + +.character-image{ + width: 15rem; + height: 15rem; + border-radius: 1.5rem; +} + +@media (min-width:600px){ + .character-image{ + width: 10rem; + height: 10rem; + border-radius: 1.5rem; + } +} + +.card-buttons{ + display: flex; + align-items: center; + justify-content: center; + max-width: inherit; + padding-top: 0.5rem; +} + +.star{ + width: 1.5rem; + height: 1.5rem; + + filter: brightness(0) invert(1); +} + +.favorite-button { + background: transparent; + border: 0; + transform: translateX(0.7rem) translateY(0.8rem); + cursor: pointer; +} + +.details-button{ + background-color: white; + color: black; + border-radius: 1rem; + border:none; + width: 12rem; + height: 2rem; +} + +@media (min-width:600px){ + .details-button{ + background-color: white; + color: black; + border-radius: 1rem; + border:none; + width: 8rem; + height: 2rem; + } +} + + +p{ + padding-top: 1rem; + padding-bottom: 1rem; + font-weight: 800; + font-size:2rem; + +} + +@media (min-width:600px){ + p{ + padding: 0; + font-weight: 800; + font-size:1.5rem; + } +} \ No newline at end of file diff --git a/src/components/CharacterCardSmall.tsx b/src/components/CharacterCardSmall.tsx new file mode 100644 index 0000000..a3a82e9 --- /dev/null +++ b/src/components/CharacterCardSmall.tsx @@ -0,0 +1,28 @@ +import './CharacterCardSmall.css' +import CardShape from '../assets/card-shape.svg' +import StarShape from '../assets/star.svg' + +type CharacterCardSmallProps = { + name: string; + image: string; +}; + +export default function CharacterCardSmall({name, image}: CharacterCardSmallProps){ + return( + <> +
+ +
+ character image +

{name}

+
+ + +
+
+
+ + ) +} \ No newline at end of file diff --git a/src/components/placeHolderComp.tsx b/src/components/placeHolderComp.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/index.css b/src/index.css index 5fb3313..f6e6759 100644 --- a/src/index.css +++ b/src/index.css @@ -51,10 +51,9 @@ } #root { - width: 1126px; - max-width: 100%; - margin: 0 auto; - text-align: center; + margin-top: 2rem; + margin-left: 2rem; + margin-right: 2rem; border-inline: 1px solid var(--border); min-height: 100svh; display: flex; diff --git a/src/pages/CharactersPage.css b/src/pages/CharactersPage.css new file mode 100644 index 0000000..c7690b3 --- /dev/null +++ b/src/pages/CharactersPage.css @@ -0,0 +1,94 @@ +.content{ + display: flex; +} + +.left{ + max-width: 56rem; +} + +.right{ + display: none; +} + +@media (min-width: 600px) { + .right { + display: block; + width: 13rem; + height: fit-content; + margin-right: 1rem; + border: 2px solid #3F3F3F; + + border-radius: 1rem; + padding: 2rem; + } +} + +.character-cards{ + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 2rem; +} + +.searchbar { + display: flex; + width: min(95%, 80rem); + margin-bottom: 2rem; + + overflow: hidden; + border: 2px solid #3f3f3f; + border-radius: 0.5rem; +} + +.searchfield { + flex: 1; + min-width: 0; + height: 2.5rem; + padding: 0 1rem; + + border: 0; + outline: 0; + font: inherit; +} + +.search-button { + min-height: 2.5rem; + padding: 0 1.25rem; + display: flex; + align-items: center; + justify-content: center; + + background-color: #42b4ca; + border: 0; + border-left: 2px solid #3f3f3f; + + font: inherit; + font-weight: 700; + cursor: pointer; +} + +.search-icon{ + filter: brightness(0) invert(1); +} + +.searchbar:focus-within { + border-color: #42b4ca; + box-shadow: 0 0 0 3px rgb(66 180 202 / 25%); +} + +.search-button:hover { + background-color: #369bad; +} + +.filter-group { + border:none; + margin-bottom: 1rem; +} +.checkbox-option { + display: flex; + align-items: center; + gap: 0.5rem; + + width: fit-content; + cursor: pointer; +} \ No newline at end of file diff --git a/src/pages/CharactersPage.tsx b/src/pages/CharactersPage.tsx index 54b3317..b989ebe 100644 --- a/src/pages/CharactersPage.tsx +++ b/src/pages/CharactersPage.tsx @@ -1,4 +1,8 @@ +import './CharactersPage.css' + import { useEffect, useState } from "react"; +import CharacterCardSmall from "../components/CharacterCardSmall"; +import SearchIcon from "../assets/search.svg" type Character = { id: number; @@ -38,11 +42,64 @@ export default function CharactersPage(){ return( <> - {characters.map((character) => ( -
{character.name} - +
+
+
+ + +
+
+ {characters.map((character) => ( + + ))} +
+
+
+
+

Gender

+ + + +
+ +
+

Spieces

+ + + +
+
+

Status

+ + + +
- ))} +
) } \ No newline at end of file diff --git a/src/pages/placeholderPage.tsx b/src/pages/placeholderPage.tsx deleted file mode 100644 index e69de29..0000000 From f0002f38575b2ff348b633d4bc41944d73b42746 Mon Sep 17 00:00:00 2001 From: Emma Fredriksen Date: Mon, 7 Sep 2026 09:16:58 +0200 Subject: [PATCH 3/5] refactor: refactor CharactersPage --- src/pages/CharactersPage.css | 6 +-- src/pages/CharactersPage.tsx | 76 +++++++++++++----------------------- 2 files changed, 30 insertions(+), 52 deletions(-) diff --git a/src/pages/CharactersPage.css b/src/pages/CharactersPage.css index c7690b3..04c9b51 100644 --- a/src/pages/CharactersPage.css +++ b/src/pages/CharactersPage.css @@ -2,16 +2,16 @@ display: flex; } -.left{ +.search-area{ max-width: 56rem; } -.right{ +.filter-area{ display: none; } @media (min-width: 600px) { - .right { + .filter-area { display: block; width: 13rem; height: fit-content; diff --git a/src/pages/CharactersPage.tsx b/src/pages/CharactersPage.tsx index b989ebe..ef78086 100644 --- a/src/pages/CharactersPage.tsx +++ b/src/pages/CharactersPage.tsx @@ -14,11 +14,15 @@ type Character = { image: string; }; +const filters = [ + {title: 'Gender', options: ['Female', 'Male', 'Unknown'] }, + {title: 'Species', options: ['Human', 'Aileen', 'Unknown']}, + {title: 'Status', options: ['Alive', 'Dead', 'Unknown']} +]; + export default function CharactersPage(){ const [characters, setCharacters] = useState([]); - - useEffect(() => { async function fetchCharacters(){ @@ -26,12 +30,11 @@ export default function CharactersPage(){ const response = await fetch("https://rickandmortyapi.com/api/character"); if (!response.ok) { - throw new Error('Could not fetch characters') + throw new Error(`Could not fetch characters: ${response.status}`) } const data = await response.json(); setCharacters(data.results); - console.log(data.results) } catch(error) { console.error(error); @@ -42,15 +45,15 @@ export default function CharactersPage(){ return( <> -
-
+
+
- +
-
+
{characters.map((character) => ( ))} -
-
-
-
-

Gender

- - - -
- -
-

Spieces

- - - -
-
-

Status

- - - -
+
+ +
+
- + ) } \ No newline at end of file From 5f170231d9d33c63facdcde82b18eb387d130b43 Mon Sep 17 00:00:00 2001 From: Emma Fredriksen Date: Mon, 7 Sep 2026 09:21:38 +0200 Subject: [PATCH 4/5] refactor: refactor CharacterCard --- src/components/CharacterCardSmall.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/components/CharacterCardSmall.tsx b/src/components/CharacterCardSmall.tsx index a3a82e9..756030a 100644 --- a/src/components/CharacterCardSmall.tsx +++ b/src/components/CharacterCardSmall.tsx @@ -9,20 +9,18 @@ type CharacterCardSmallProps = { export default function CharacterCardSmall({name, image}: CharacterCardSmallProps){ return( - <>
character image

{name}

- - +
- ) } \ No newline at end of file From a0913e9bad4d29fca0f80124a24560f2a6bc68a6 Mon Sep 17 00:00:00 2001 From: Emma Fredriksen Date: Mon, 7 Sep 2026 09:22:50 +0200 Subject: [PATCH 5/5] chore: clean up --- src/assets/react.svg | 1 - src/assets/vite.svg | 1 - src/pages/CharactersPage.tsx | 2 -- 3 files changed, 4 deletions(-) delete mode 100644 src/assets/react.svg delete mode 100644 src/assets/vite.svg diff --git a/src/assets/react.svg b/src/assets/react.svg deleted file mode 100644 index 6c87de9..0000000 --- a/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/vite.svg b/src/assets/vite.svg deleted file mode 100644 index 5101b67..0000000 --- a/src/assets/vite.svg +++ /dev/null @@ -1 +0,0 @@ -Vite diff --git a/src/pages/CharactersPage.tsx b/src/pages/CharactersPage.tsx index ef78086..b654f7d 100644 --- a/src/pages/CharactersPage.tsx +++ b/src/pages/CharactersPage.tsx @@ -44,7 +44,6 @@ export default function CharactersPage(){ }, []) return( - <>
@@ -78,6 +77,5 @@ export default function CharactersPage(){
- ) } \ No newline at end of file