Skip to content

Commit

Permalink
✨ implement dark mode
Browse files Browse the repository at this point in the history
automatically check for system mode
manual control via animated thingy
  • Loading branch information
hyusap committed Nov 12, 2023
1 parent 53430b1 commit 677f4d0
Show file tree
Hide file tree
Showing 7 changed files with 219 additions and 77 deletions.
47 changes: 34 additions & 13 deletions www/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import Image from "next/image";

import banner from "@/public/bloom2x1.svg";
import darkBanner from "@/public/bloom2x1dark.svg";
import Message from "@/components/message";
import Thoughts from "@/components/thoughts";
import Sidebar from "@/components/sidebar";
Expand Down Expand Up @@ -32,6 +33,7 @@ import { Session } from "@supabase/supabase-js";
import { createClientComponentClient } from "@supabase/auth-helpers-nextjs";
import Link from "next/link";
import MarkdownWrapper from "@/components/markdownWrapper";
import { DarkModeSwitch } from "react-toggle-dark-mode";

interface Message {
text: string;
Expand Down Expand Up @@ -181,6 +183,13 @@ export default function Home() {
};
}, []);

const [isDarkMode, setIsDarkMode] = useState(
window.matchMedia("(prefers-color-scheme: dark)").matches
);
const toggleDarkMode = (checked: boolean) => {
setIsDarkMode(checked);
};

// async function newChat() {
// return await fetch(`${URL}/api/conversations/insert?user_id=${userId}`)
// .then((res) => res.json())
Expand Down Expand Up @@ -292,7 +301,11 @@ export default function Home() {
}

return (
<main className="flex h-[100dvh] w-screen flex-col pb-[env(keyboard-inset-height)] text-sm lg:text-base overflow-hidden relative">
<main
className={`flex h-[100dvh] w-screen flex-col pb-[env(keyboard-inset-height)] text-sm lg:text-base overflow-hidden relative ${
isDarkMode ? "dark" : ""
}`}
>
<Sidebar
conversations={conversations}
authSession={authSession}
Expand All @@ -304,20 +317,28 @@ export default function Home() {
isSidebarOpen={isSidebarOpen}
setIsSidebarOpen={setIsSidebarOpen}
/>
<div className="flex flex-col w-full h-[100dvh] lg:pl-60 xl:pl-72">
<nav className="flex justify-between items-center p-4 border-b border-gray-300">
<div className="flex flex-col w-full h-[100dvh] lg:pl-60 xl:pl-72 dark:bg-gray-900">
<nav className="flex justify-between items-center p-4 border-b border-gray-300 dark:border-gray-700">
<FaBars
className="inline lg:hidden"
onClick={() => setIsSidebarOpen(!isSidebarOpen)}
/>
<Image src={banner} alt="banner" className="h-10 w-auto" />
<button
className="bg-neon-green rounded-lg px-4 py-2 flex justify-center items-center gap-2"
onClick={() => setIsThoughtsOpen(true)}
>
See Thoughts
<FaLightbulb className="inline" />
</button>

<Image
src={isDarkMode ? darkBanner : banner}
alt="banner"
className="h-10 w-auto"
/>
<div className="flex justify-between items-center gap-4">
<DarkModeSwitch checked={isDarkMode} onChange={toggleDarkMode} />
<button
className="bg-neon-green rounded-lg px-4 py-2 flex justify-center items-center gap-2"
onClick={() => setIsThoughtsOpen(true)}
>
See Thoughts
<FaLightbulb className="inline" />
</button>
</div>
</nav>
{!authSession && (
<section className="bg-neon-green text-black text-center py-4">
Expand All @@ -333,7 +354,7 @@ export default function Home() {
</section>
)}
<section
className="flex flex-col flex-1 overflow-y-auto lg:px-5"
className="flex flex-col flex-1 overflow-y-auto lg:px-5 dark:text-white"
ref={messageContainerRef}
>
{messages.map((message, i) => (
Expand All @@ -357,7 +378,7 @@ export default function Home() {
type="text"
ref={input}
placeholder="Type a message..."
className={`flex-1 px-3 py-1 lg:px-5 lg:py-3 bg-gray-100 text-gray-400 rounded-2xl border-2 ${
className={`flex-1 px-3 py-1 lg:px-5 lg:py-3 bg-gray-100 dark:bg-gray-800 text-gray-400 rounded-2xl border-2 ${
canSend ? " border-green-200" : "border-red-200 opacity-50"
}`}
disabled={!canSend}
Expand Down
8 changes: 5 additions & 3 deletions www/components/message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ import Image from "next/image";
import icon from "@/public/bloomicon.jpg";
import usericon from "@/public/usericon.svg";

export default function Message({ children, isUser }: {
export default function Message({
children,
isUser,
}: {
children: React.ReactNode;
isUser?: boolean;
}) {

return (
<article
className={
"flex p-5 lg:p-8 gap-2 lg:gap-5 lg:rounded-2xl " +
(isUser ? "bg-gray-100" : "")
(isUser ? "bg-gray-100 dark:bg-gray-800" : "")
}
>
<Image
Expand Down
125 changes: 64 additions & 61 deletions www/components/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,83 +133,86 @@ export default function Sidebar({

return (
<div
className={`fixed lg:static z-20 inset-0 flex-none h-full w-full lg:absolute lg:h-auto lg:overflow-visible lg:pt-0 lg:w-60 xl:w-72 lg:block lg:shadow-lg border-r border-gray-300 ${isSidebarOpen ? "" : "hidden"
}`}
className={`fixed lg:static z-20 inset-0 flex-none h-full w-full lg:absolute lg:h-auto lg:overflow-visible lg:pt-0 lg:w-60 xl:w-72 lg:block lg:shadow-lg border-r border-gray-300 dark:border-gray-700 ${
isSidebarOpen ? "" : "hidden"
}`}
>
<div
className={`h-full scrollbar-trigger overflow-hidden bg-white sm:w-3/5 w-4/5 lg:w-full flex flex-col ${isSidebarOpen ? "fixed lg:static" : "sticky"
} top-0 left-0`}
className={`h-full scrollbar-trigger overflow-hidden bg-white dark:bg-gray-950 dark:text-white sm:w-3/5 w-4/5 lg:w-full flex flex-col ${
isSidebarOpen ? "fixed lg:static" : "sticky"
} top-0 left-0`}
>
{/* Section 1: Top buttons */}
<div className="flex justify-between items-center p-4 gap-2 border-b border-gray-300">
<div className="flex justify-between items-center p-4 gap-2 border-b border-gray-300 dark:border-gray-700">
<button
className="bg-neon-green rounded-lg px-4 py-2 w-full lg:w-full h-10"
className="bg-neon-green text-black rounded-lg px-4 py-2 w-full lg:w-full h-10"
onClick={addChat}
>
New Chat
</button>
<button
className="lg:hidden bg-neon-green rounded-lg px-4 py-2 h-10"
className="lg:hidden bg-neon-green text-black rounded-lg px-4 py-2 h-10"
onClick={() => setIsSidebarOpen(false)}
>
<GrClose />
</button>
</div>
</div>

{/* Section 2: Scrollable items */}
<div className="flex flex-col flex-1 overflow-y-auto divide-y divide-gray-300">
{conversations.map((cur, i) => (
<div
key={i}
className={`flex justify-between items-center p-4 cursor-pointer hover:bg-gray-200 ${currentConversation === cur ? "bg-gray-200" : ""
}`}
onClick={() => setCurrentConversation(cur)}
>
<div>
<h2 className="font-bold overflow-ellipsis overflow-hidden">
{cur.name || "Untitled"}
</h2>
</div>
<div className="flex flex-row justify-end gap-2 items-center w-1/5">
<button
className="text-gray-500"
onClick={() => editConversation(cur)}
>
<FaEdit />
</button>
<button
className="text-red-500"
onClick={() => deleteConversation(cur)}
>
<FaTrash />
</button>
</div>
</div>
{/* Section 2: Scrollable items */}
<div className="flex flex-col flex-1 overflow-y-auto divide-y divide-gray-300 dark:divide-gray-700">
{conversations.map((cur, i) => (
<div
key={i}
className={`flex justify-between items-center p-4 cursor-pointer hover:bg-gray-200 hover:dark:bg-gray-800 ${
currentConversation === cur
? "bg-gray-200 dark:bg-gray-800"
: ""
}`}
onClick={() => setCurrentConversation(cur)}
>
<div>
<h2 className="font-bold overflow-ellipsis overflow-hidden">
{cur.name || "Untitled"}
</h2>
</div>
<div className="flex flex-row justify-end gap-2 items-center w-1/5">
<button
className="text-gray-500"
onClick={() => editConversation(cur)}
>
<FaEdit />
</button>
<button
className="text-red-500"
onClick={() => deleteConversation(cur)}
>
<FaTrash />
</button>
</div>
</div>
))}
</div>
</div>

{/* Section 3: Authentication information */}
<div className="border-t border-gray-300 p-4 w-full">
{/* Replace this with your authentication information */}
{
authSession ? (
<button
className="bg-neon-green rounded-lg px-4 py-2 w-full"
onClick={handleSignOut}
>
Sign Out
</button>
) : (
<button
className="bg-neon-green rounded-lg px-4 py-2 w-full"
onClick={() => router.push("/auth")}
>
Sign In
</button>
)
}
</div >
</div >
</div >
{/* Section 3: Authentication information */}
<div className="border-t border-gray-300 dark:border-gray-700 p-4 w-full">
{/* Replace this with your authentication information */}
{authSession ? (
<button
className="bg-neon-green text-black rounded-lg px-4 py-2 w-full"
onClick={handleSignOut}
>
Sign Out
</button>
) : (
<button
className="bg-neon-green text-black rounded-lg px-4 py-2 w-full"
onClick={() => router.push("/auth")}
>
Sign In
</button>
)}
</div>
</div>
</div>
);
}
1 change: 1 addition & 0 deletions www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"react-icons": "^4.10.1",
"react-markdown": "^8.0.7",
"react-syntax-highlighter": "^15.5.0",
"react-toggle-dark-mode": "^1.1.1",
"rehype-katex": "^7.0.0",
"remark-math": "^6.0.0",
"sharp": "^0.32.5",
Expand Down
16 changes: 16 additions & 0 deletions www/public/bloom2x1dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions www/tailwind.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Config } from "tailwindcss";

const config: Config = {
darkMode: "class",
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
Expand Down
Loading

0 comments on commit 677f4d0

Please sign in to comment.