Skip to content

Commit

Permalink
Merge pull request #2 from deepsingh132/development
Browse files Browse the repository at this point in the history
Fix: Resolve 'Entire page deopted into client-side rendering' error and address dark mode flashing issue in production build
  • Loading branch information
deepsingh132 authored Nov 28, 2023
2 parents 7f11b02 + 24d73dc commit ad804ad
Show file tree
Hide file tree
Showing 11 changed files with 7,604 additions and 2,141 deletions.
4 changes: 1 addition & 3 deletions app/RecoilContextProviders.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
'use client'

import { RecoilRoot, atom } from "recoil";
import Toggle from "@/components/Toggle";
import { Toaster } from "react-hot-toast";

export const recoilState = atom({
key: "recoilState",
default: {},
});

export default function RecoidContextProvider({children}: { children: React.ReactNode }) {
export default function RecoilContextProvider({children}: { children: React.ReactNode }) {
return (
<RecoilRoot>
<Toaster />
<Toggle />
{children}
</RecoilRoot>
);
Expand Down
13 changes: 13 additions & 0 deletions app/ThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"use client";

import * as React from "react";
import { ThemeProvider as NextThemesProvider } from "next-themes";
type ThemeProviderProps = Parameters<typeof NextThemesProvider>[0];

/**
* Your app's theme provider component.
* 'use client' is essential for next-themes to work with app-dir.
*/
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}
30 changes: 17 additions & 13 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
import "./styles/globals.css";
import React from "react";
import { NextAuthProvider } from './Providers';
import RecoidContextProvider from "./RecoilContextProviders";
import { NextAuthProvider } from "./Providers";
import RecoilContextProvider from "./RecoilContextProviders";
import { Metadata } from "next";
import { ThemeProvider } from "./ThemeProvider";

export const metadata : Metadata = {
title: 'Artsphere',
description: 'Artsphere is a platform for artists to share their work and connect with other artists.',
}
export const metadata: Metadata = {
title: "Artsphere",
description:
"Artsphere is a platform for artists to share their work and connect with other artists.",
};

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
children: React.ReactNode;
}) {
return (
<html suppressHydrationWarning={true} lang="en">
<body suppressHydrationWarning={true}>
<RecoidContextProvider>
<NextAuthProvider>{children}</NextAuthProvider>
</RecoidContextProvider>
<html suppressHydrationWarning lang="en">
<body suppressHydrationWarning>
<RecoilContextProvider>
<NextAuthProvider>
<ThemeProvider attribute="class">{children}</ThemeProvider>
</NextAuthProvider>
</RecoilContextProvider>
</body>
</html>
);
Expand Down
74 changes: 38 additions & 36 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,66 +1,68 @@
import Sidebar from "@/components/Sidebar";
import Widgets from "@/components/Widgets";
import RefreshFeed from "@/components/RefreshFeed";
import CommentModal from "@/components/CommentModal";
import { Suspense } from "react";
import Feed from "@/components/Feed";

export default async function Home() {
const { trendingPosts, randomUsersResults } = await getWidgetsData();

return (
<div>
<main className="flex dark:bg-darkBg dark:text-darkText overflow-clip min-h-screen mx-auto">

<main
role="main"
className="flex dark:bg-darkBg dark:text-darkText overflow-clip min-h-screen mx-auto"
>
{/* Sidebar */}
<Sidebar />

<div className="flex flex-grow w-full">
{/* Feed */}
<RefreshFeed />
<Suspense fallback={<Feed type={undefined} />}>
<RefreshFeed />
</Suspense>

{/* Widgets */}

<Widgets
trendingPosts={trendingPosts || []}
randomUsersResults={randomUsersResults?.results || []}
trendingPosts={trendingPosts}
randomUsersResults={randomUsersResults}
/>
</div>
</main>
</div>
);
}

async function getWidgetsData() {

if (!process.env.NEXT_PUBLIC_BACKEND_URL) {
return {
trendingPosts: [],
randomUsersResults: [],
};
}

// Trending posts section
// TODO: add backend route for trending posts
const trendingPosts =
await fetch(
`${process.env.NEXT_PUBLIC_BACKEND_URL}/widgets/trending/posts`
).then((res) => res.json());
async function getWidgetsData() {
const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL;

// Who to follow section
if (!backendUrl || backendUrl === "undefined") {
return {
trendingPosts: [],
randomUsersResults: [],
};
}

let randomUsersResults: any = [];
try {
const trendingPostsRes = await fetch(
`${backendUrl}/widgets/trending/posts`
);
const randomUsersRes = await fetch(
"https://randomuser.me/api/?results=10&inc=name,login,picture"
);

try {
const res = await fetch(
"https://randomuser.me/api/?results=10&inc=name,login,picture"
);
const trendingPosts = await trendingPostsRes.json();
const randomUsersResults = await randomUsersRes.json();

randomUsersResults = await res.json();
} catch (e) {
randomUsersResults = [];
return {
trendingPosts: trendingPosts.trendingPosts,
randomUsersResults: randomUsersResults.results,
};
} catch (error) {
return {
trendingPosts: [],
randomUsersResults: [],
};
}
}

return {
trendingPosts: trendingPosts?.trendingPosts,
randomUsersResults,
};
}
16 changes: 14 additions & 2 deletions app/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,26 @@
--light-icon-color: #ffde59;
}

*{
margin: 0;
padding: 0;
box-sizing: border-box;
scroll-behavior: smooth;
}

body{
margin: 0;
background-color: #fff;
box-sizing: border-box;
}

body * {
@apply transition-colors duration-700;
[data-theme="dark"]{
--color: #9176ff;
--dark-color: #000000;
--dark-icon-color: #fff;
--light-color: #f7f7f7;
--light-icon-color: #ffde59;
background-color: #000;
}

[contenteditable][placeholder]:empty:before {
Expand Down
24 changes: 13 additions & 11 deletions components/Feed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,18 @@ export default function Feed({ type }) {
}
};

if (!loading && posts.length === 0) {
if (!loading && posts?.length === 0) {
return (
<div className="xl:ml-[350px] h-full border-l border-r border-lightBorderColor dark:border-darkBorderColor xl:min-w-[680px] sm:ml-[82px] justify-center sm:w-[calc(100%-83px)] w-full content-center items-center flex-grow max-w-2xl">
<div className="xl:ml-[350px] h-full border-l border-r border-lightBorderColor dark:border-darkBorderColor xl:min-w-[680px] sm:ml-[82px] justify-center sm:w-[calc(100%-82px)] w-screen content-center items-center flex-grow max-w-2xl">
<Navbar title={undefined} />
<Input
updatePosts={updatePosts}
text={undefined}
id={undefined}
style={undefined}
phoneInputModal={undefined} setCommentModalState={undefined} />
phoneInputModal={undefined}
setCommentModalState={undefined}
/>
<div className="flex flex-col items-center justify-center h-[calc(100%-50%)]">
<h1 className="text-2xl font-bold text-gray-700 dark:text-darkText">
No posts found
Expand Down Expand Up @@ -203,14 +205,14 @@ export default function Feed({ type }) {
Create a post
</h1>
<div className="flex-1 ">
<Input
updatePosts={updatePosts}
style={`flex w-full mt-4 min-h-[50px] max-h-[100px] text-[15px] dark:bg-darkBg dark:text-darkText`}
phoneInputModal={closeModal}
text={undefined}
id={undefined}
setCommentModalState={undefined}
/>
<Input
updatePosts={updatePosts}
style={`flex w-full mt-4 min-h-[50px] max-h-[100px] text-[15px] dark:bg-darkBg dark:text-darkText`}
phoneInputModal={closeModal}
text={undefined}
id={undefined}
setCommentModalState={undefined}
/>
</div>
</div>
</Modal>
Expand Down
96 changes: 47 additions & 49 deletions components/ModeToggle.tsx
Original file line number Diff line number Diff line change
@@ -1,87 +1,85 @@
'use client';
import { useState, useEffect } from "react";
import { useEffect, useState } from "react";
import "./toggle_mode.css";
import { MoonIcon, SunIcon } from "@heroicons/react/24/outline";
import { toastSuccess } from "./Toast";
import { useTheme } from "next-themes";

export default function ModeToggle() {

const initialMode = localStorage.getItem("mode") || "light";
const [mode, setMode] = useState(initialMode);
const { setTheme, resolvedTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);

useEffect(() => {
if (mode === "dark") {
document.documentElement.classList.add("dark");
localStorage.setItem("mode", "dark");
// set the toggle state based on the resolved theme
if (resolvedTheme === "dark") {
document?.getElementById("darkModeToggle")?.classList.add("dark");
document?.getElementById("icon")?.classList.toggle("moon");
} else {
document.documentElement.classList.remove("dark");
localStorage.setItem("mode", "light");
document?.getElementById("darkModeToggle")?.classList.remove("dark");
document?.getElementById("icon")?.classList.toggle("sun");
}
}, [mode, initialMode]);

}, [resolvedTheme]);

const toggleMode = () => {
if (mode === "dark") {
localStorage.setItem("mode", "light");
setMode("light");
document?.getElementById("icon")?.classList.toggle("moon");
toastSuccess("Light mode enabled", {
if (!mounted) return;

const toggleClasses = (id: string, newClass: string, oldClass: string) => {
const element = document?.getElementById(id);
element?.classList.remove(oldClass);
element?.classList.add(newClass);
};

const showToast = (message: string, color: string) => {
toastSuccess(message, {
style: {
background: "#fff",
color: "#333",
background: color,
color: color === "#fff" ? "#333" : "#fff",
zIndex: 1,
boxShadow: "0 1px 4px rgba(0, 0, 0, 0.1)",
},
duration: 3000,
});
};
if (resolvedTheme === "dark") {
setTheme("light");
toggleClasses("icon", "sun", "moon");
document?.getElementById("darkModeToggle")?.classList.remove("dark");
showToast("Light mode enabled", "#fff");
} else {
localStorage.setItem("mode", "dark");
setMode("dark");
toastSuccess("Dark mode enabled", {
style: {
background: "#333",
color: "#fff",
zIndex: 1,
boxShadow: "0 1px 4px rgba(0, 0, 0, 0.1)",
},
}
);
setTheme("dark");
toggleClasses("icon", "sun", "sun");
document?.getElementById("darkModeToggle")?.classList.add("dark");
showToast("Dark mode enabled", "#333");
}
};
}

return (
<div className="flex items-center justify-center">
<div className="toggle-container">
<div
className={mode === "dark" ? "toggle dark" : "toggle"}
data-testid="dark-mode-toggle"
className={
resolvedTheme === "dark"
? "toggle dark"
: "toggle"
}
onClick={toggleMode}
id="darkModeToggle"
>
<div className="icon sun" id="icon">
{mode === "dark" ? (
<MoonIcon className="text-black" id="moon" />
) : (
<SunIcon className="text-black" id="sun" />
)
{
resolvedTheme === "dark" ? (
<MoonIcon className="text-black" id="sun" />
) : (
<SunIcon className="text-black" id="moony" />
)
}
</div>
</div>
</div>
</div>
);
}
// {
// // if mode is dark then show moon else show sun
// mode === "dark" ? (
// <MoonIcon
// className="icon moon transition-transform duration-500"
// id="moon"
// />
// ) : (
// <SunIcon
// className="icon sun transition-transform duration-500"
// id="sun"
// />
// );
// }
}
Loading

0 comments on commit ad804ad

Please sign in to comment.