Skip to content

Commit

Permalink
add: MiniCard and eye candy
Browse files Browse the repository at this point in the history
  • Loading branch information
lyudmil-mitev committed Oct 9, 2024
1 parent df1a4cc commit 4cd9987
Show file tree
Hide file tree
Showing 25 changed files with 163 additions and 112 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"build": "tsc -b && vite build && cp -v dist/index.html dist/404.html",
"lint": "eslint .",
"preview": "vite preview"
},
Expand Down
Binary file added public/planet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/portal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/seasons/s01.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/seasons/s02.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/seasons/s03.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/seasons/s04.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/seasons/s05.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/seasons/s06.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions src/components/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import mortyLogo from '/android-chrome-512x512.png'
import starrySpace from '/StarrySpace.svg'

const Banner = () => <section className="flex justify-center items-center bg-cover bg-center py-20" style={{ backgroundImage: `url(${starrySpace})` }}>
<a href="https://rickandmortyapi.com/" target="_blank">
<a title="Powered by Rick and Morty API!" href="https://rickandmortyapi.com/" target="_blank">
<img src={mortyLogo} className="logo" alt="Morty Logo" />
</a>
<h1 className="text-3xl font-extrabold text-white sm:text-5xl">Rick and Morty Explorer</h1>
<h1 className="schwifty text-6xl sm:text-10xl">Rick and Morty Explorer</h1>
</section>

export default Banner;
16 changes: 2 additions & 14 deletions src/components/CharacterDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
import { Character } from 'rickmortyapi';
import { useLoaderData } from 'react-router-dom';
import MiniCard from './MiniCard';

export default function CharacterDetail({ character }: { character?: Character }) {
const char = character || useLoaderData() as Character;
return (
<section className="p-4 text-left">
<div className="flex gap-4 p-4 border-b border-gray-200 dark:border-gray-700">
<img src={char.image} alt={char.name} className="w-24 h-24 rounded-full" />
<div>
<h2 className="text-xl font-bold text-gray-800 dark:text-gray-200">{char.name}</h2>
<p className="text-gray-600 dark:text-gray-400">
{char.species} from {char.origin.name}
</p>
<p className="text-gray-600 dark:text-gray-400">
Status: {char.status}
</p>
</div>
</div>
</section>
<MiniCard title={char.name} image={char.image} description={char.species} />
);
}
19 changes: 0 additions & 19 deletions src/components/Characters.tsx

This file was deleted.

23 changes: 12 additions & 11 deletions src/components/EpisodeDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { useLoaderData } from "react-router-dom";
import { Episode } from "rickmortyapi";
import MiniCard from "./MiniCard";

import Season1 from "/seasons/s01.jpg";
import Season2 from "/seasons/s02.jpg";
import Season3 from "/seasons/s03.jpg";
import Season4 from "/seasons/s04.jpg";
import Season5 from "/seasons/s05.jpg";
import Season6 from "/seasons/s06.jpg";

export default function EpisodeDetail({ episode }: { episode?: Episode }) {
const ep = episode || useLoaderData() as Episode;
const season = parseInt(ep.episode.slice(2, 3), 10);
const images = [Season1, Season2, Season3, Season4, Season5, Season6];
const image = season <= 6 ? images[season - 1] : images[0];
return (
<section className="p-4 text-left">
<div className="flex gap-4 p-4 border-b border-gray-200 dark:border-gray-700">
<div>
<h2 className="text-xl font-bold text-gray-800 dark:text-gray-200">{ep.episode}: {ep.name}</h2>
<p className="text-gray-600 dark:text-gray-400">
{ep.air_date}
</p>
{ep.characters.length} characters
</div>
</div>
</section>
<MiniCard title={`${ep.episode}`} image={image} description={`${ep.name}`} />
);
}
19 changes: 0 additions & 19 deletions src/components/Episodes.tsx

This file was deleted.

17 changes: 4 additions & 13 deletions src/components/LocationDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import { useLoaderData } from "react-router-dom";
import { Location } from "rickmortyapi";
import MiniCard from "./MiniCard";
import PortalImage from "/portal.png"
import PlanetImage from "/planet.png"

export default function LocationDetail({ location }: { location?: Location }) {
const place = location || useLoaderData() as Location;
return (
<section className="p-4 text-left">
<div className="flex gap-4 p-4 border-b border-gray-200 dark:border-gray-700">
<div>
<h2 className="text-xl font-bold text-gray-800 dark:text-gray-200">{place.name}</h2>
<p className="text-gray-600 dark:text-gray-400">
{place.type} - {place.dimension}
</p>
<p className="text-gray-600 dark:text-gray-400">
{place.residents.length} residents
</p>
</div>
</div>
</section>
<MiniCard title={place.name} image={place.type === "Planet" ? PlanetImage : PortalImage} description={`${place.type}`} />
);
}
19 changes: 0 additions & 19 deletions src/components/Locations.tsx

This file was deleted.

13 changes: 13 additions & 0 deletions src/components/MiniCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default function MiniCard({ title, image, description}: { title: string, image: string, description: string }) {
return (<section className="portal-hover h-full text-left max-w-md mx-auto bg-white dark:bg-gray-800 rounded-lg shadow-md">
<div className="flex h-full gap-4">
<img src={image} alt={title} className="w-24 h-24 rounded-tl-lg rounded-bl-lg" />
<div className='z-10'>
<h2 className="text-xl mt-2 font-bold text-gray-800 dark:text-gray-200">{title}</h2>
<p className="text-gray-600 dark:text-gray-400">
{description}
</p>
</div>
</div>
</section>);
}
8 changes: 3 additions & 5 deletions src/components/TabBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,19 @@ const TabBar: React.FC<TabBarProps> = ({ tabs, selectedTab, onSelectTab }) => {
</div>

<div className="hidden sm:block">
<div className="border-b border-gray-300 dark:border-gray-600">
<nav className="-mb-px flex gap-6">
{tabs.map((tab) => (
<Link key={tab} to={`/${tab.toLowerCase()}`}
className={`shrink-0 border border-transparent p-3 text-sm font-medium ${tab === selectedTab
? "rounded-t-lg border-gray-500 border-b-white text-sky-600 dark:border-gray-400 dark:border-b-gray-800 bg-gray-200 dark:bg-gray-700"
: "text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
className={`shrink-0 p-3 text-sm font-medium ${tab === selectedTab
? "rounded-t-lg border-b-white text-sky-600 bg-gray-100 dark:bg-gray-700"
: "text-gray-300 hover:text-gray-100 dark:text-gray-400 dark:hover:text-gray-300"
}`}
>
{tab}
</Link>
))}
</nav>
</div>
</div>
</div>
);
Expand Down
10 changes: 5 additions & 5 deletions src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { createBrowserRouter, RouterProvider } from 'react-router-dom'
import { charactersLoader, characterDetailLoader, episodesLoader, episodeDetailLoader, locationsLoader, locationDetailLoader } from './loaders.ts'

import Root from './routes/Root.tsx'
import Characters from './components/Characters.tsx'
import Characters from './routes/Characters.tsx'
import CharacterDetail from './components/CharacterDetail.tsx'
import EpisodeDetail from './components/EpisodeDetail.tsx'
import Episodes from './components/Episodes.tsx'
import Locations from './components/Locations.tsx'
import Episodes from './routes/Episodes.tsx'
import Locations from './routes/Locations.tsx'
import LocationDetail from './components/LocationDetail.tsx'
import './index.css'

Expand All @@ -29,7 +29,7 @@ const router = createBrowserRouter([
loader: charactersLoader,
},
{
path: '/character/:characterId',
path: '/characters/:characterId',
element: <CharacterDetail />,
loader: characterDetailLoader
},
Expand All @@ -39,7 +39,7 @@ const router = createBrowserRouter([
loader: locationsLoader,
},
{
path: '/location/:locationId',
path: '/locations/:locationId',
element: <LocationDetail />,
loader: locationDetailLoader
},
Expand Down
23 changes: 23 additions & 0 deletions src/routes/Characters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Character } from 'rickmortyapi';
import { Link, useLoaderData, useSearchParams } from 'react-router-dom';
import CharacterDetail from '../components/CharacterDetail';
import Pagination from '../components/Pagination';

export default function Characters() {
const [params, ] = useSearchParams()
const page = parseInt(params.get('page') || '1');
const { characters, pages } = useLoaderData() as { characters: Character[], pages: number };

return (
<section className="p-4 text-left">
<Pagination page={page} totalPages={pages} />
<div className='grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4'>
{characters.map((character) => (
<Link key={character.id} to={`/characters/${character.id}`}>
<CharacterDetail key={character.id} character={character} />
</Link>
))}
</div>
</section>
);
};
23 changes: 23 additions & 0 deletions src/routes/Episodes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Link, useLoaderData, useSearchParams } from "react-router-dom";
import { Episode } from "rickmortyapi";
import EpisodeDetail from "../components/EpisodeDetail";
import Pagination from "../components/Pagination";

export default function Episodes() {
const [params, ] = useSearchParams()
const page = parseInt(params.get('page') || '1');
const { episodes, pages } = useLoaderData() as { episodes: Episode[], pages: number };

return (
<section className="p-4 text-left">
<Pagination page={page} totalPages={pages} />
<div className='grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4'>
{episodes.map((episode) => (
<Link key={episode.id} to={`/episodes/${episode.id}`}>
<EpisodeDetail key={episode.id} episode={episode} />
</Link>
))}
</div>
</section>
);
}
23 changes: 23 additions & 0 deletions src/routes/Locations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Link, useLoaderData, useSearchParams } from "react-router-dom";
import { Location } from "rickmortyapi";
import LocationDetail from "../components/LocationDetail";
import Pagination from "../components/Pagination";

export default function Locations() {
const [params, ] = useSearchParams()
const page = parseInt(params.get('page') || '1');
const { locations, pages } = useLoaderData() as { locations: Location[], pages: number };

return (
<section className="p-4 text-left">
<Pagination page={page} totalPages={pages} />
<div className='grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4'>
{locations.map((location) => (
<Link key={location.id} to={`/locations/${location.id}`}>
<LocationDetail key={location.id} location={location} />
</Link>
))}
</div>
</section>
);
}
50 changes: 49 additions & 1 deletion src/routes/Root.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,59 @@
@font-face {
font-family: 'Get Schwifty';
src: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/3089507/get-schwifty.woff') format('woff');
}

.schwifty {
font-family: 'Get Schwifty', sans-serif;
font-size: 10em;
font-display: swap;
color: #08BAE3;
text-shadow: -2px 0 0px rgba(0, 0, 0, 1), 0 -2px 0px rgba(0, 0, 0, 1), 0 2px 0px rgba(0, 0, 0, 1), 2px 0 0px rgba(0, 0, 0, 1), 0 0 10px rgba(50, 255, 0, 1);
}

#root {
max-width: 1280px;
margin: 0 auto;
text-align: center;
}

.portal-hover {
position: relative;
overflow: hidden;
}

.portal-hover img {
z-index: 1;
}

@media (prefers-color-scheme: dark) {
.portal-hover:hover {
text-shadow: 0 0 2px rgba(0, 0, 0, 1);
}
}

.portal-hover::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(0,255,0,0.5) 0%, rgba(173,255,47,0.5) 25%, rgba(255,255,0,0.5) 50%, rgba(0,128,0,0.5) 75%, rgba(0,0,0,0) 90%);
border-radius: 50%;
transform: translate(-50%, -50%) scale(0);
transition: transform 0.3s ease-in-out;
z-index: 0;
}

.portal-hover:hover::before {
transform: translate(-50%, -50%) scale(1);
animation: pulse 0.5s infinite;
}

.logo {
height: 6em;
height: 8em;
min-width: 128px;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
Expand Down
4 changes: 2 additions & 2 deletions src/routes/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function capitalizeString(str: string) {
}

function formatLocation(location: string) {
const path = location.split("/").pop();
const path = location.split("/")[1]

if (typeof path === "undefined" || path.length < 2) {
return "Characters";
Expand All @@ -31,7 +31,7 @@ export default function Root() {
selectedTab={formatLocation(location.pathname)}
onSelectTab={handleSelectTab}
/>
<main>
<main className='bg-gray-100 dark:bg-gray-700'>
<Outlet />
</main>
<footer>
Expand Down
Loading

0 comments on commit 4cd9987

Please sign in to comment.