diff --git a/src/assets/star-filled.svg b/src/assets/star-filled.svg new file mode 100644 index 0000000..86218f8 --- /dev/null +++ b/src/assets/star-filled.svg @@ -0,0 +1 @@ + diff --git a/src/components/CharacterCardSmall.css b/src/components/CharacterCardSmall.css index 1e3248b..4adfb70 100644 --- a/src/components/CharacterCardSmall.css +++ b/src/components/CharacterCardSmall.css @@ -81,7 +81,7 @@ } .star-favorite { - filter: brightness(0) saturate(100%) invert(84%) sepia(85%) saturate(829%) hue-rotate(359deg) brightness(105%) contrast(104%); + filter: none; } .details-button { @@ -120,4 +120,4 @@ .card-content { width: min(100%, 12rem); } -} \ No newline at end of file +} diff --git a/src/components/CharacterCardSmall.tsx b/src/components/CharacterCardSmall.tsx index 91c3c2e..358b2c8 100644 --- a/src/components/CharacterCardSmall.tsx +++ b/src/components/CharacterCardSmall.tsx @@ -1,6 +1,7 @@ import "./CharacterCardSmall.css"; import CardShape from "../assets/card-shape.svg"; import StarShape from "../assets/star.svg"; +import StarFilledShape from "../assets/star-filled.svg"; type CharacterCardSmallProps = { name: string; @@ -44,7 +45,7 @@ export default function CharacterCardSmall({ } > diff --git a/src/components/CharacterDetailCard.css b/src/components/CharacterDetailCard.css index 9977cab..23e3f11 100644 --- a/src/components/CharacterDetailCard.css +++ b/src/components/CharacterDetailCard.css @@ -249,8 +249,7 @@ } .detail-star-favorite { - filter: brightness(0) saturate(100%) invert(84%) sepia(85%) saturate(829%) - hue-rotate(359deg) brightness(105%) contrast(104%); + filter: none; } @media (max-width: 750px) { diff --git a/src/components/CharacterDetailCard.tsx b/src/components/CharacterDetailCard.tsx index ca14091..46781a5 100644 --- a/src/components/CharacterDetailCard.tsx +++ b/src/components/CharacterDetailCard.tsx @@ -11,6 +11,7 @@ import ArrowRight from "../assets/arrow-right.svg"; import UserRound from "../assets/user-round.svg"; import X from "../assets/X.svg"; import Star from "../assets/star.svg"; +import StarFilled from "../assets/star-filled.svg"; type CharacterDetailCardProps = { character: Character; @@ -99,7 +100,7 @@ export default function CharacterDetailCard({ } > .filter-group { +/* The CSS for the dropdown menu was made with help from AI */ +.filter-dropdown { + border: 2px solid #3f3f3f; + border-radius: 0.5rem; + background: #282828; +} + +.filter-dropdown summary { + display: flex; + align-items: center; + justify-content: space-between; + min-height: 2.75rem; + padding: 0 1rem; + font-weight: 700; + color: #f3f4f6; + cursor: pointer; + list-style: none; +} + +.filter-dropdown summary::-webkit-details-marker { + display: none; +} + +.filter-dropdown-icon { + display: inline-flex; + width: 0.6rem; + height: 0.6rem; + border-right: 2px solid currentColor; + border-bottom: 2px solid currentColor; + transform: rotate(45deg); + transition: transform 160ms ease; +} + +.filter-dropdown[open] .filter-dropdown-icon { + transform: rotate(225deg); +} + +.filter-options, +.filter-sidebar { display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); + grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.75rem; margin: 0; } +.filter-options { + padding: 0 1rem 1rem; +} + +.filter-sidebar { + display: none; +} + .filter-group legend { font-weight: 700; } @@ -134,8 +179,12 @@ } @media (min-width: 768px) { - .filter-area>.filter-group { - grid-template-columns: 1fr; + .filter-dropdown { + display: none; + } + + .filter-sidebar { + display: block; } .search-button { @@ -147,13 +196,14 @@ repeat(auto-fill, minmax(min(100%, 12rem), 1fr)); } - .filter-area>.filter-group { - display: block; + .filter-options, + .filter-sidebar { + grid-template-columns: 1fr; } } @media (max-width: 420px) { - .filter-area>.filter-group { + .filter-options { grid-template-columns: 1fr; } -} \ No newline at end of file +} diff --git a/src/pages/CharactersPage.tsx b/src/pages/CharactersPage.tsx index 7eb9710..ec36921 100644 --- a/src/pages/CharactersPage.tsx +++ b/src/pages/CharactersPage.tsx @@ -16,9 +16,10 @@ import { } from "../utils/filterCharacters"; const filters: { title: string; key: FilterCategory; options: string[] }[] = [ + { title: "Favorite", key: "favorite", options: ["My favorites"] }, { title: "Gender", key: "gender", options: ["Female", "Male", "Unknown"] }, { title: "Species", key: "species", options: ["Human", "Alien", "Unknown"] }, - { title: "Status", key: "status", options: ["Alive", "Dead", "Unknown"] }, + { title: "Status", key: "status", options: ["Alive", "Dead", "Unknown"] } ]; // AI was used to create the fetchCharacters function @@ -51,6 +52,7 @@ export default function CharactersPage() { } return { + favorite: [], gender: [], species: [], status: [], @@ -85,6 +87,7 @@ export default function CharactersPage() { characters, searchQuery, selectedFilters, + favoriteCharacterIds, ); function handleFilterChange( @@ -110,6 +113,35 @@ export default function CharactersPage() { ); } + // Changed with help from AI as it needed fitting for dropdown. + function renderFilterOptions() { + return filters.map((filter) => ( +
+ {filter.title} + {filter.options.map((option) => ( + + ))} +
+ )); + } + function showPreviousCharacter() { if (!selectedCharacter) return; @@ -158,32 +190,15 @@ export default function CharactersPage() {
-
{selectedCharacter && ( diff --git a/src/utils/filterCharacters.ts b/src/utils/filterCharacters.ts index fca1564..34b612c 100644 --- a/src/utils/filterCharacters.ts +++ b/src/utils/filterCharacters.ts @@ -1,13 +1,11 @@ import type { Character } from "../types/Character"; -export type FilterCategory = "gender" | "species" | "status"; +export type FilterCategory = "favorite" | "gender" | "species" | "status"; export type SelectedFilters = Record; export function filterCharacters( - // Takes in all characters, the value in the search field and the chosen filters - characters: Character[], - searchQuery: string, - selectedFilters: SelectedFilters, +// Takes in all characters, the value in the search field and the chosen filters +characters: Character[], searchQuery: string, selectedFilters: SelectedFilters, favoriteCharacterIds: number[], ): Character[] { return characters.filter((character) => { //Checks whether each character's name matches with the search and if the character's gender, specie or status is checked off in the filter @@ -15,6 +13,10 @@ export function filterCharacters( .toLowerCase() .includes(searchQuery.toLowerCase()); + const matchesFavorite = + selectedFilters.favorite.length === 0 || + favoriteCharacterIds.includes(character.id); + const matchesGender = selectedFilters.gender.length === 0 || selectedFilters.gender.includes(character.gender.toLowerCase()); @@ -27,6 +29,6 @@ export function filterCharacters( selectedFilters.status.length === 0 || selectedFilters.status.includes(character.status.toLowerCase()); //Returns the result of the checks mentioned above - return matchesSearch && matchesGender && matchesSpecies && matchesStatus; + return matchesSearch && matchesFavorite && matchesGender && matchesSpecies && matchesStatus; }); }