Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 24 additions & 18 deletions src/Root.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,42 @@
// import { useState, useEffect } from 'react'
import { useState, useEffect } from 'react'
import { Outlet } from 'react-router'

// import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
// import { faMoon, faSun } from '@fortawesome/free-regular-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faMoon, faSun } from '@fortawesome/free-regular-svg-icons'

function Root() {
// const [darkMode, setDarkMode] = useState(false)
const [darkMode, setDarkMode] = useState(() => {
const saved = localStorage.getItem('darkMode')
return saved ? JSON.parse(saved) : false
})

// useEffect(() => {
// if (darkMode) {
// document.documentElement.classList.add('dark')
// } else {
// document.documentElement.classList.remove('dark')
// }
// }, [darkMode])
useEffect(() => {
if (darkMode) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
localStorage.setItem('darkMode', JSON.stringify(darkMode))
}, [darkMode])

return (
<>
<div className="font-nunito min-h-screen w-full bg-gray-50">
<header className="flex h-24 w-full items-center justify-between bg-white p-4 shadow-md/2 md:px-12 xl:px-20">
<h1 className="text-md font-bold text-gray-800">
<div className="font-nunito min-h-screen w-full bg-gray-50 transition-colors duration-200 dark:bg-blue-950">
<header className="flex h-24 w-full items-center justify-between bg-white p-4 shadow-md transition-colors duration-200 dark:bg-blue-900 md:px-12 xl:px-20">
<h1 className="text-md font-bold text-gray-800 dark:text-white">
Where in the world?
</h1>
{/* <button
<button
onClick={() => setDarkMode(!darkMode)}
className="cursor-pointer"
className="flex cursor-pointer items-center gap-2 text-gray-800 transition-colors hover:text-gray-600 dark:text-white dark:hover:text-gray-300"
aria-label="Toggle dark mode"
type="button"
>
<FontAwesomeIcon icon={darkMode ? faSun : faMoon} />
<span className="text-sm">{darkMode ? 'Light' : 'Dark'} mode</span>
</button> */}
<span className="text-sm font-semibold">
{darkMode ? 'Light' : 'Dark'} Mode
</span>
</button>
</header>
<Outlet />
</div>
Expand Down
16 changes: 10 additions & 6 deletions src/components/CountryCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@ const CountryCard = memo(function CountryCard({
data: CountriesResponse[0]
}) {
return (
<div className="flex w-full flex-col items-center justify-center rounded-sm bg-white shadow-[0_5px_15px_rgba(0,0,0,0.05)]">
<div className="flex w-full flex-col items-center justify-center overflow-hidden rounded-lg bg-white shadow-[0_5px_15px_rgba(0,0,0,0.05)] transition-all duration-300 hover:-translate-y-2 hover:shadow-[0_10px_30px_rgba(0,0,0,0.15)] dark:bg-blue-900 dark:shadow-[0_5px_15px_rgba(0,0,0,0.3)] dark:hover:shadow-[0_10px_30px_rgba(0,0,0,0.4)]">
<Link
to={`/${data.cca3.toLowerCase()}`}
className="aspect-3/2 w-full cursor-pointer rounded-t-sm bg-gray-200"
className="aspect-3/2 w-full cursor-pointer bg-gray-200"
>
<img
src={data.flags.png}
alt={data.name.common + ' flag'}
className="h-full w-full rounded-t-sm object-cover"
className="h-full w-full object-cover transition-transform duration-300 hover:scale-105"
/>
</Link>
<div className="flex w-full flex-col items-start p-6">
<h2 className="mb-4 text-lg font-bold">{data.name.common}</h2>
<h2 className="mb-4 text-lg font-bold text-gray-900 dark:text-white">
{data.name.common}
</h2>
<Detail
title="Population"
content={data.population.toLocaleString('en-US')}
Expand All @@ -41,8 +43,10 @@ function Detail({
}) {
return (
<div>
<p className="inline text-gray-950">{title}:</p>
<span className="ml-1 text-sm font-light">{content}</span>
<p className="inline text-gray-950 dark:text-white">{title}:</p>
<span className="ml-1 text-sm font-light text-gray-700 dark:text-gray-300">
{content}
</span>
</div>
)
}
Expand Down
12 changes: 6 additions & 6 deletions src/components/CountryCardSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
function CountryCardSkeleton() {
return (
<div className="mb-10 flex w-full flex-col items-center justify-center rounded-sm bg-white shadow-[0_5px_15px_rgba(0,0,0,0.05)]">
<div className="aspect-3/2 w-full rounded-t-sm bg-gray-200"></div>
<div className="mb-10 flex w-full flex-col items-center justify-center overflow-hidden rounded-lg bg-white shadow-[0_5px_15px_rgba(0,0,0,0.05)] dark:bg-blue-900 dark:shadow-[0_5px_15px_rgba(0,0,0,0.3)]">
<div className="aspect-3/2 w-full animate-pulse bg-gray-200 dark:bg-gray-700"></div>
<div className="flex w-full flex-col p-6">
<div className="mb-6 h-5 w-1/2 animate-pulse rounded bg-gray-300"></div>
<div className="mb-4 h-3 w-2/3 animate-pulse rounded bg-gray-300"></div>
<div className="mb-4 h-3 w-2/3 animate-pulse rounded bg-gray-300"></div>
<div className="mb-4 h-3 w-1/3 animate-pulse rounded bg-gray-300"></div>
<div className="mb-6 h-5 w-1/2 animate-pulse rounded bg-gray-300 dark:bg-gray-700"></div>
<div className="mb-4 h-3 w-2/3 animate-pulse rounded bg-gray-300 dark:bg-gray-700"></div>
<div className="mb-4 h-3 w-2/3 animate-pulse rounded bg-gray-300 dark:bg-gray-700"></div>
<div className="mb-4 h-3 w-1/3 animate-pulse rounded bg-gray-300 dark:bg-gray-700"></div>
</div>
</div>
)
Expand Down
6 changes: 5 additions & 1 deletion src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { BrowserRouter, Route, Routes } from 'react-router'
import CountryPage from './pages/CountryPage.tsx'
import HomePage from './pages/HomePage.tsx'
import WelcomePage from './pages/WelcomePage.tsx'
import GamePage from './pages/GamePage.tsx'

import countries from 'i18n-iso-countries'
import en from 'i18n-iso-countries/langs/en.json'
Expand Down Expand Up @@ -36,7 +38,9 @@ createRoot(document.getElementById('root')!).render(
<BrowserRouter>
<Routes>
<Route path="/" element={<Root />}>
<Route index element={<HomePage />} />
<Route index element={<WelcomePage />} />
<Route path="browse" element={<HomePage />} />
<Route path="game" element={<GamePage />} />
<Route path=":countryCode" element={<CountryPage />} />
</Route>
</Routes>
Expand Down
58 changes: 33 additions & 25 deletions src/pages/CountryPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,22 @@ function CountryPage() {
<div className="flex w-full flex-col items-center p-6 py-12 lg:p-20 lg:py-16">
<div className="mb-16 w-full">
<Link
to="/"
className="flex w-30 items-center justify-center rounded-md py-2 shadow-[0_0px_20px_rgba(0,0,0,0.2)]"
to="/browse"
className="flex w-30 items-center justify-center gap-2 rounded-lg bg-white px-6 py-3 shadow-[0_0px_20px_rgba(0,0,0,0.1)] transition-all duration-300 hover:shadow-[0_0px_25px_rgba(0,0,0,0.15)] dark:bg-blue-900 dark:text-white dark:shadow-[0_0px_20px_rgba(0,0,0,0.3)] dark:hover:shadow-[0_0px_25px_rgba(0,0,0,0.4)]"
>
<FontAwesomeIcon icon={faArrowLeft} className="text-md mr-2" />
<FontAwesomeIcon icon={faArrowLeft} className="text-md" />
<p>Back</p>
</Link>
</div>
{theCountry && <CountryInformation country={theCountry} />}

{isLoadingCountry && <CountryInformationSkeleton />}

{isErrorCountry && <p className="text-red-500">Error</p>}
{isErrorCountry && (
<p className="text-red-500 dark:text-red-400">
Error loading country
</p>
)}
</div>
</>
)
Expand All @@ -50,11 +54,11 @@ function CountryInformation({ country }: { country: AlphaResponse }) {
<img
src={country.flags.png}
alt={country.name.common + ' flag'}
className="h-full w-full rounded-t-sm object-cover"
className="h-full w-full rounded-lg object-cover shadow-xl"
/>
<div className="flex w-full flex-col gap-12 lg:gap-4">
<div className="flex flex-col gap-8 lg:py-12">
<h2 className="text-2xl font-extrabold lg:text-3xl">
<h2 className="text-2xl font-extrabold text-gray-900 dark:text-white lg:text-3xl">
{country.name.common}
</h2>
<div className="flex flex-col gap-8 md:flex-row md:justify-between">
Expand Down Expand Up @@ -94,7 +98,7 @@ function CountryInformation({ country }: { country: AlphaResponse }) {
</div>
</div>
<div className="lg:flex lg:w-full lg:gap-8">
<h3 className="mb-4 text-lg font-medium lg:w-1/3">
<h3 className="mb-4 text-lg font-medium text-gray-900 dark:text-white lg:w-1/3">
Border countries:
</h3>
<div className="grid w-full grid-cols-3 gap-5">
Expand Down Expand Up @@ -129,8 +133,10 @@ function Detail({
if (Array.isArray(content)) {
return (
<div>
<p className="inline text-black md:text-sm lg:text-lg">{title}:</p>
<span className="ml-1 text-sm font-light md:text-xs lg:text-base">
<p className="inline text-gray-900 dark:text-white md:text-sm lg:text-lg">
{title}:
</p>
<span className="ml-1 text-sm font-light text-gray-700 dark:text-gray-300 md:text-xs lg:text-base">
{content.join(', ')}
</span>
</div>
Expand All @@ -139,8 +145,10 @@ function Detail({

return (
<div>
<p className="inline text-gray-950 md:text-sm lg:text-lg">{title}:</p>
<span className="md:text-x ml-1 text-sm font-light lg:text-base">
<p className="inline text-gray-900 dark:text-white md:text-sm lg:text-lg">
{title}:
</p>
<span className="ml-1 text-sm font-light text-gray-700 dark:text-gray-300 md:text-xs lg:text-base">
{content}
</span>
</div>
Expand All @@ -151,7 +159,7 @@ function BorderCountry({ country, alpha }: { country: string; alpha: string }) {
return (
<Link
to={`/${alpha.toLowerCase()}`}
className="flex items-center justify-center rounded-md py-2 shadow-[0_0px_20px_rgba(0,0,0,0.1)]"
className="flex items-center justify-center rounded-lg bg-white py-2 shadow-[0_0px_20px_rgba(0,0,0,0.1)] transition-all duration-300 hover:-translate-y-1 hover:shadow-[0_0px_25px_rgba(0,0,0,0.15)] dark:bg-blue-900 dark:text-white dark:shadow-[0_0px_20px_rgba(0,0,0,0.3)] dark:hover:shadow-[0_0px_25px_rgba(0,0,0,0.4)]"
>
<p className="text-center">{country}</p>
</Link>
Expand All @@ -162,33 +170,33 @@ function CountryInformationSkeleton() {
return (
<div className="flex w-full animate-pulse flex-col items-start gap-10 md:grid md:grid-cols-2 md:gap-16">
{/* Flag */}
<div className="h-64 w-full rounded-md bg-gray-300 lg:h-96" />
<div className="h-64 w-full rounded-lg bg-gray-300 dark:bg-gray-700 lg:h-96" />

{/* Info */}
<div className="flex w-full flex-col gap-10 lg:py-10">
{/* Name + 1st block */}
<div className="mb-1 h-8 w-48 rounded bg-gray-300" />
<div className="mb-1 h-8 w-48 rounded bg-gray-300 dark:bg-gray-700" />
<div className="flex w-full flex-col gap-8 md:flex-row">
<div className="flex w-full flex-col">
<div className="mb-2 h-4 w-40 rounded bg-gray-200 md:w-30 lg:w-40" />
<div className="mb-2 h-4 w-32 rounded bg-gray-200 md:w-22 lg:w-32" />
<div className="mb-2 h-4 w-36 rounded bg-gray-200 md:w-26 lg:w-36" />
<div className="mb-2 h-4 w-28 rounded bg-gray-200 md:w-18 lg:w-28" />
<div className="mb-2 h-4 w-40 rounded bg-gray-200 dark:bg-gray-700 md:w-30 lg:w-40" />
<div className="mb-2 h-4 w-32 rounded bg-gray-200 dark:bg-gray-700 md:w-22 lg:w-32" />
<div className="mb-2 h-4 w-36 rounded bg-gray-200 dark:bg-gray-700 md:w-26 lg:w-36" />
<div className="mb-2 h-4 w-28 rounded bg-gray-200 dark:bg-gray-700 md:w-18 lg:w-28" />
</div>
{/* 2nd Block */}
<div className="flex w-full flex-col">
<div className="mb-2 h-4 w-28 rounded bg-gray-200 md:w-18 lg:w-28" />
<div className="mb-2 h-4 w-40 rounded bg-gray-200 md:w-30 lg:w-40" />
<div className="mb-2 h-4 w-36 rounded bg-gray-200 md:w-26 lg:w-36" />
<div className="mb-2 h-4 w-28 rounded bg-gray-200 dark:bg-gray-700 md:w-18 lg:w-28" />
<div className="mb-2 h-4 w-40 rounded bg-gray-200 dark:bg-gray-700 md:w-30 lg:w-40" />
<div className="mb-2 h-4 w-36 rounded bg-gray-200 dark:bg-gray-700 md:w-26 lg:w-36" />
</div>
</div>
{/* Border countries */}
<div className="flex w-full flex-col lg:w-full lg:flex-row lg:gap-5">
<div className="mb-6 h-6 w-48 rounded bg-gray-300" />
<div className="mb-6 h-6 w-48 rounded bg-gray-300 dark:bg-gray-700" />
<div className="grid w-full grid-cols-3 gap-5">
<div className="h-10 rounded bg-gray-200" />
<div className="h-10 rounded bg-gray-200" />
<div className="h-10 rounded bg-gray-200" />
<div className="h-10 rounded bg-gray-200 dark:bg-gray-700" />
<div className="h-10 rounded bg-gray-200 dark:bg-gray-700" />
<div className="h-10 rounded bg-gray-200 dark:bg-gray-700" />
</div>
</div>
</div>
Expand Down
Loading