Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added dark mode #12

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
31 changes: 26 additions & 5 deletions components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import Link from "next/link";
import Image from "next/image";

export default function Footer() {
return (
<footer className="text-center h-16 sm:h-20 w-full sm:pt-2 pt-4 border-t mt-5 flex sm:flex-row flex-col justify-between items-center px-3 space-y-3 sm:mb-0 mb-3">
<footer className="text-center h-16 sm:h-20 w-full sm:pt-2 pt-4 border-t mt-5 flex sm:flex-row flex-col justify-between items-center px-3 space-y-3 sm:mb-0 mb-3 text-black dark:text-zinc-300">
<div>
Powered by{" "}
<a
href="https://replicate.com/"
target="_blank"
rel="noreferrer"
className="font-bold hover:underline transition underline-offset-2"
className="font-bold hover:underline transition underline-offset-2 text-black dark:text-zinc-100"
>
Replicate{" "}
</a>
Expand All @@ -18,20 +19,40 @@ export default function Footer() {
href="https://vercel.com/"
target="_blank"
rel="noreferrer"
className="font-bold hover:underline transition underline-offset-2"
className="font-bold hover:underline transition underline-offset-2 text-black dark:text-zinc-100"
>
Vercel.
</a>
</div>
<div className="flex space-x-4 pb-4 sm:pb-0">
<a
className="cursor-pointer group"
onClick={() => {
const html = document.querySelector("html");
html?.classList.toggle("dark");
if (localStorage.getItem("dark") === "true") {
localStorage.setItem("dark", "false");
} else {
localStorage.setItem("dark", "true");
}
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 384 512"
className="h-6 w-6 p-[2px] fill-slate-500 dark:fill-zinc-300 group-hover:fill-slate-700 dark:group-hover:fill-zinc-500"
>
<path d="M112.1 454.3c0 6.297 1.816 12.44 5.284 17.69l17.14 25.69c5.25 7.875 17.17 14.28 26.64 14.28h61.67c9.438 0 21.36-6.401 26.61-14.28l17.08-25.68c2.938-4.438 5.348-12.37 5.348-17.7L272 415.1h-160L112.1 454.3zM192 0C90.02 .3203 16 82.97 16 175.1c0 44.38 16.44 84.84 43.56 115.8c16.53 18.84 42.34 58.23 52.22 91.45c.0313 .25 .0938 .5166 .125 .7823h160.2c.0313-.2656 .0938-.5166 .125-.7823c9.875-33.22 35.69-72.61 52.22-91.45C351.6 260.8 368 220.4 368 175.1C368 78.8 289.2 .0039 192 0zM288.4 260.1c-15.66 17.85-35.04 46.3-49.05 75.89h-94.61c-14.01-29.59-33.39-58.04-49.04-75.88C75.24 236.8 64 206.1 64 175.1C64 113.3 112.1 48.25 191.1 48C262.6 48 320 105.4 320 175.1C320 206.1 308.8 236.8 288.4 260.1zM176 80C131.9 80 96 115.9 96 160c0 8.844 7.156 16 16 16S128 168.8 128 160c0-26.47 21.53-48 48-48c8.844 0 16-7.148 16-15.99S184.8 80 176 80z" />
</svg>
</a>
<Link
href="https://twitter.com/nutlope"
className="group"
aria-label="TaxPal on Twitter"
>
<svg
aria-hidden="true"
className="h-6 w-6 fill-slate-500 group-hover:fill-slate-700"
className="h-6 w-6 fill-slate-500 dark:fill-zinc-300 group-hover:fill-slate-700 dark:group-hover:fill-zinc-500"
>
<path d="M8.29 20.251c7.547 0 11.675-6.253 11.675-11.675 0-.178 0-.355-.012-.53A8.348 8.348 0 0 0 22 5.92a8.19 8.19 0 0 1-2.357.646 4.118 4.118 0 0 0 1.804-2.27 8.224 8.224 0 0 1-2.605.996 4.107 4.107 0 0 0-6.993 3.743 11.65 11.65 0 0 1-8.457-4.287 4.106 4.106 0 0 0 1.27 5.477A4.073 4.073 0 0 1 2.8 9.713v.052a4.105 4.105 0 0 0 3.292 4.022 4.093 4.093 0 0 1-1.853.07 4.108 4.108 0 0 0 3.834 2.85A8.233 8.233 0 0 1 2 18.407a11.615 11.615 0 0 0 6.29 1.84" />
</svg>
Expand All @@ -43,7 +64,7 @@ export default function Footer() {
>
<svg
aria-hidden="true"
className="h-6 w-6 fill-slate-500 group-hover:fill-slate-700"
className="h-6 w-6 fill-slate-500 dark:fill-zinc-300 group-hover:fill-slate-700 dark:group-hover:fill-zinc-500"
>
<path d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0 1 12 6.844a9.59 9.59 0 0 1 2.504.337c1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.02 10.02 0 0 0 22 12.017C22 6.484 17.522 2 12 2Z" />
</svg>
Expand Down
4 changes: 2 additions & 2 deletions components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function Header() {
width={36}
height={36}
/>
<h1 className="sm:text-5xl text-3xl font-bold ml-2 tracking-tight">
<h1 className="sm:text-5xl text-3xl font-bold ml-2 text-black dark:text-white tracking-tight">
restorePhotos.io
</h1>
</Link>
Expand All @@ -24,7 +24,7 @@ export default function Header() {
<Image
alt="Vercel Icon"
src="/vercelLogo.png"
className="sm:w-10 sm:h-[34px] w-8 h-[28px]"
className="sm:w-10 sm:h-[34px] w-8 h-[28px] dark:invert"
width={32}
height={28}
/>
Expand Down
4 changes: 3 additions & 1 deletion components/LoadingDots.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import styles from "../styles/loading-dots.module.css";

const LoadingDots = ({
color = "#000",
color = document.querySelector("html")?.classList.contains("dark")
? "#ddf"
: "#000",
style = "small",
}: {
color: string;
Expand Down
14 changes: 7 additions & 7 deletions components/Testimonials.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ export function Testimonials() {
>
<div className="mx-auto px-4 sm:px-6 lg:px-8">
<div className="mx-auto md:text-center">
<h1 className="mx-auto max-w-4xl font-display text-4xl font-bold tracking-normal text-slate-900 sm:text-6xl">
<h1 className="mx-auto max-w-4xl font-display text-4xl font-bold tracking-normal text-slate-900 dark:text-zinc-200 sm:text-6xl">
Loved by many worldwide.
</h1>
<p className="mx-auto mt-6 max-w-xl text-lg text-slate-700 leading-7">
<p className="mx-auto mt-6 max-w-xl text-lg text-slate-700 leading-7 dark:text-zinc-400">
See what our 100,000+ users are saying about the product.
</p>
</div>
Expand All @@ -98,18 +98,18 @@ export function Testimonials() {
className="hover:scale-105 transition duration-300 ease-in-out"
>
<a href={testimonial.link} target="_blank" rel="noreferrer">
<figure className="relative rounded-2xl bg-white p-6 shadow-xl shadow-slate-900/10">
<figure className="relative rounded-2xl bg-white dark:bg-zinc-800 p-6 shadow-xl shadow-zinc-900/10 dark:shadow-black/10">
<blockquote className="relative">
<p className="text-lg tracking-tight text-slate-900">
<p className="text-lg tracking-tight text-slate-900 dark:text-slate-100">
"{testimonial.content}"
</p>
</blockquote>
<figcaption className="relative mt-6 flex items-center justify-between border-t border-slate-100 pt-6">
<figcaption className="relative mt-6 flex items-center justify-between border-t border-slate-100 dark:border-zinc-100/10 pt-6">
<div>
<div className="font-display text-base text-slate-900">
<div className="font-display text-base text-slate-900 dark:text-zinc-100">
{testimonial.author.name}
</div>
<div className="mt-1 text-sm text-slate-500">
<div className="mt-1 text-sm text-slate-500 dark:text-zinc-300">
{testimonial.author.role}
</div>
</div>
Expand Down
12 changes: 9 additions & 3 deletions components/Toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ export default function Toggle({
<div className="flex items-center">
<span
className={`text-sm mr-3 font-medium ${
!sideBySide ? "text-gray-900" : "text-gray-500"
!sideBySide
? "text-gray-900 dark:text-zinc-600"
: "text-gray-400 dark:text-zinc-200"
}`}
>
Side by Side
Expand All @@ -28,7 +30,9 @@ export default function Toggle({
checked={sideBySide}
onChange={setSideBySide}
className={classNames(
sideBySide ? "bg-black" : "bg-gray-200",
sideBySide
? "bg-black dark:bg-zinc-700"
: "bg-gray-200 dark:bg-zinc-200",
"relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none "
)}
>
Expand All @@ -43,7 +47,9 @@ export default function Toggle({
<Switch.Label as="span" className="ml-3">
<span
className={`text-sm font-medium ${
sideBySide ? "text-gray-900" : "text-gray-500"
sideBySide
? "text-gray-900 dark:text-zinc-600"
: "text-gray-400 dark:text-zinc-200"
} `}
>
Compare
Expand Down
30 changes: 22 additions & 8 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,34 @@ import SquigglyLines from "../components/SquigglyLines";
import { Testimonials } from "../components/Testimonials";

const Home: NextPage = () => {
if (
typeof window === "object" &&
(localStorage.getItem("dark") === "true" ||
(window.matchMedia("(prefers-color-scheme: dark)").matches &&
!localStorage.getItem("dark")))
) {
document.querySelector("html")?.classList.add("dark");
} else if (typeof window === "object") {
document.querySelector("html")?.classList.remove("dark");
}
return (
<div className="flex max-w-6xl mx-auto flex-col items-center justify-center py-2 min-h-screen">
<Head>
<title>Face Photo Restorer</title>
</Head>

<Header />
<main className="flex flex-1 w-full flex-col items-center justify-center text-center px-4 sm:mt-28 mt-20">
<main className="flex flex-1 w-full flex-col items-center justify-center text-center px-4 sm:mt-28 mt-2">
<a
href="https://twitter.com/nutlope/status/1620493265865957376"
target="_blank"
rel="noreferrer"
className="border rounded-2xl py-1 px-4 text-slate-500 text-sm mb-5 hover:scale-105 transition duration-300 ease-in-out"
className="border rounded-2xl py-1 px-4 text-slate-500 dark:text-zinc-300 text-sm mb-5 hover:scale-105 transition duration-300 ease-in-out"
>
Used by over <span className="font-semibold">100,000</span> happy
customers
</a>
<h1 className="mx-auto max-w-4xl font-display text-5xl font-bold tracking-normal text-slate-900 sm:text-7xl">
<h1 className="mx-auto max-w-4xl font-display text-5xl font-bold tracking-normal text-slate-900 dark:text-zinc-100 sm:text-7xl">
Restoring old photos{" "}
<span className="relative whitespace-nowrap text-[#3290EE]">
<SquigglyLines />
Expand All @@ -34,13 +44,13 @@ const Home: NextPage = () => {
for everyone.
</h1>

<p className="mx-auto mt-12 max-w-xl text-lg text-slate-700 leading-7">
<p className="mx-auto mt-12 max-w-xl text-lg text-slate-700 dark:text-slate-200 leading-7">
Have old and blurry face photos? Let our AI restore them so those
memories can live on. 100% free – restore your photos today.
</p>
<div className="flex justify-center space-x-4">
<a
className="bg-white rounded-xl text-black font-medium px-4 py-3 sm:mt-10 mt-8 hover:bg-gray-100 border"
className="bg-white rounded-xl text-black dark:bg-zinc-900 dark:text-zinc-300 dark:hover:bg-zinc-800 font-medium px-4 py-3 sm:mt-10 mt-8 hover:bg-gray-100 border"
href="https://youtu.be/FRQtFDDrUXQ"
target="_blank"
rel="noreferrer"
Expand All @@ -49,7 +59,7 @@ const Home: NextPage = () => {
</a>

<Link
className="bg-black rounded-xl text-white font-medium px-4 py-3 sm:mt-10 mt-8 hover:bg-black/80"
className="bg-black dark:bg-zinc-200 rounded-xl text-white dark:text-black font-medium px-4 py-3 sm:mt-10 mt-8 hover:bg-black/80 dark:hover:bg-zinc-200/80"
href="/restore"
>
Restore your photos
Expand All @@ -59,7 +69,9 @@ const Home: NextPage = () => {
<div className="flex flex-col space-y-10 mt-4 mb-16">
<div className="flex sm:space-x-2 sm:flex-row flex-col">
<div>
<h2 className="mb-1 font-medium text-lg">Original Photo</h2>
<h2 className="mb-1 font-medium text-lg dark:text-zinc-200">
Original Photo
</h2>
<Image
alt="Original photo of my bro"
src="/michael.jpg"
Expand All @@ -69,7 +81,9 @@ const Home: NextPage = () => {
/>
</div>
<div className="sm:mt-0 mt-8">
<h2 className="mb-1 font-medium text-lg">Restored Photo</h2>
<h2 className="mb-1 font-medium text-lg dark:text-zinc-200">
Restored Photo
</h2>
<Image
alt="Restored photo of my bro"
width={400}
Expand Down
47 changes: 35 additions & 12 deletions pages/restore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,20 @@ const options = {
maxFileCount: 1,
mimeTypes: ["image/jpeg", "image/png", "image/jpg"],
editor: { images: { crop: false } },
styles: { colors: { primary: "#000" } },
styles: {
colors: {
primary: "#000",
},
},
};

const Home: NextPage = () => {
if (typeof window === "object" && localStorage.getItem("dark") === "true") {
window.document.querySelector("html")?.classList.add("dark");
} else if (typeof window === "object") {
window.document.querySelector("html")?.classList.remove("dark");
}

const [originalPhoto, setOriginalPhoto] = useState<string | null>(null);
const [restoredImage, setRestoredImage] = useState<string | null>(null);
const [loading, setLoading] = useState<boolean>(false);
Expand Down Expand Up @@ -86,22 +96,22 @@ const Home: NextPage = () => {
href="https://youtu.be/FRQtFDDrUXQ"
target="_blank"
rel="noreferrer"
className="border rounded-2xl py-1 px-4 text-slate-500 text-sm mb-5 hover:scale-105 transition duration-300 ease-in-out"
className="border rounded-2xl py-1 px-4 text-slate-500 dark:text-zinc-300 text-sm mb-5 hover:scale-105 transition duration-300 ease-in-out"
>
Are you a developer and want to learn how I built this? Watch the{" "}
<span className="font-bold">YouTube tutorial</span>.
</a>
<h1 className="mx-auto max-w-4xl font-display text-4xl font-bold tracking-normal text-slate-900 sm:text-6xl mb-5">
<h1 className="mx-auto max-w-4xl font-display text-4xl font-bold tracking-normal text-slate-900 dark:text-zinc-100 sm:text-6xl mb-5">
Restore any face photo
</h1>
<p className="text-slate-500">
<p className="text-slate-500 dark:text-zinc-300">
{" "}
{/* Obtained this number from Vercel: based on how many serverless invocations happened. */}
<CountUp start={50000} end={174851} duration={2} separator="," />{" "}
photos generated and counting.
</p>
<ResizablePanel>
<AnimatePresence exitBeforeEnter>
<AnimatePresence mode="wait">
<motion.div className="flex justify-between items-center w-full flex-col mt-4">
<Toggle
className={`${restoredLoaded ? "visible" : "invisible"} mb-6`}
Expand All @@ -127,7 +137,9 @@ const Home: NextPage = () => {
{restoredImage && originalPhoto && !sideBySide && (
<div className="flex sm:space-x-4 sm:flex-row flex-col">
<div>
<h2 className="mb-1 font-medium text-lg">Original Photo</h2>
<h2 className="mb-1 font-medium text-lg text-black dark:text-zinc-100">
Original Photo
</h2>
<Image
alt="original photo"
src={originalPhoto}
Expand All @@ -137,7 +149,9 @@ const Home: NextPage = () => {
/>
</div>
<div className="sm:mt-0 mt-8">
<h2 className="mb-1 font-medium text-lg">Restored Photo</h2>
<h2 className="mb-1 font-medium text-lg text-black dark:text-zinc-100">
Restored Photo
</h2>
<a href={restoredImage} target="_blank" rel="noreferrer">
<Image
alt="restored photo"
Expand All @@ -154,16 +168,25 @@ const Home: NextPage = () => {
{loading && (
<button
disabled
className="bg-black rounded-full text-white font-medium px-4 pt-2 pb-3 mt-8 hover:bg-black/80 w-40"
className="bg-black dark:bg-zinc-700 rounded-full text-white font-medium px-4 pt-2 pb-3 mt-8 hover:bg-black/80 dark:hover:bg-zinc-700/80 w-40"
>
<span className="pt-4">
<LoadingDots color="white" style="large" />
<LoadingDots
color={
document
.querySelector("html")
?.classList.contains("dark")
? "black"
: "white"
}
style="large"
/>
</span>
</button>
)}
{error && (
<div
className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-xl mt-8"
className="bg-red-100 dark:bg-zinc-800 border border-red-400 dark:border-red-900 text-red-700 dark:text-red-200 px-4 py-3 rounded-xl mt-8"
role="alert"
>
<span className="block sm:inline">{error}</span>
Expand All @@ -178,7 +201,7 @@ const Home: NextPage = () => {
setRestoredLoaded(false);
setError(null);
}}
className="bg-black rounded-full text-white font-medium px-4 py-2 mt-8 hover:bg-black/80 transition"
className="bg-black dark:bg-zinc-700 rounded-full text-white font-medium px-4 py-2 mt-8 hover:bg-black/80 dark:hover:bg-zinc-700/80 transition"
>
Upload New Photo
</button>
Expand All @@ -191,7 +214,7 @@ const Home: NextPage = () => {
appendNewToName(photoName!)
);
}}
className="bg-white rounded-full text-black border font-medium px-4 py-2 mt-8 hover:bg-gray-100 transition"
className="bg-white dark:bg-zinc-300 rounded-full text-black dark:text-zinc-900 border border-white dark:border-zinc-300 font-medium px-4 py-2 mt-8 hover:bg-gray-100 dark:hover:bg-zinc-400 transition"
>
Download Restored Photo
</button>
Expand Down
9 changes: 9 additions & 0 deletions styles/globals.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

html {
transition-property: background-color;
transition-duration: 0.5s;
transition-timing-function: ease;
}
.dark {
@apply bg-zinc-900;
}
Loading