Skip to content

Commit

Permalink
Get logging in and out working; fix the header on the profile page (#7)
Browse files Browse the repository at this point in the history
* Add an auth context for managing the token.
* Get logging in/out working.
* Update the profile page to use `<Header/>`.
  • Loading branch information
joestump authored Oct 21, 2024
1 parent ada199e commit 81d5344
Show file tree
Hide file tree
Showing 13 changed files with 208 additions and 107 deletions.
4 changes: 2 additions & 2 deletions components/PostLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { NavMenu } from "./common";
import TitleHead from "./TitleHead";
import Logo from "./common/Logo";

const PostLayout = ({ children, title, permalink, thumbnail, token }: Props) => (
const PostLayout = ({ children, title, permalink, thumbnail }: Props) => (
<div>
<TitleHead title={title}>
<meta name="description" content={`Read on Reddium`} />
Expand All @@ -30,7 +30,7 @@ const PostLayout = ({ children, title, permalink, thumbnail, token }: Props) =>
<div className="flex-grow flex items-center">
<Logo />
</div>
<NavMenu token={token}/>
<NavMenu />
</nav>
</header>
{children}
Expand Down
3 changes: 1 addition & 2 deletions components/Subpage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const Subpage = ({
children,
title,
subreddit,
token,
backgroundColor = "white"
}: Props) => (
<div>
Expand All @@ -28,7 +27,7 @@ const Subpage = ({
<div className="flex-grow flex items-center">
<Logo />
</div>
<NavMenu token={token}/>
<NavMenu />
</nav>
</header>
{children}
Expand Down
4 changes: 2 additions & 2 deletions components/common/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface HeaderProps {
className?: string;
}

const Header: React.FC<HeaderProps> = ({ token, className = '' }) => {
const Header: React.FC<HeaderProps> = ({ className = '' }) => {
return (
<header className={className}>
<nav className="flex items-center justify-center max-width-main mx-auto z-50 h-16 my-6 lg:mx-12 sm:mx-6">
Expand All @@ -20,7 +20,7 @@ const Header: React.FC<HeaderProps> = ({ token, className = '' }) => {
</h1>
</div>
</div>
<NavMenu token={token} />
<NavMenu />
</nav>
</header>
);
Expand Down
61 changes: 40 additions & 21 deletions components/common/index.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,75 @@
import _ from 'lodash';
import React, { useEffect, useRef, useState } from "react";
import React, { useEffect, useRef, useState, useCallback } from "react";
import Image from 'next/image';
import Link from 'next/link';
import { getIntFromString, getTime, limitText } from "../../functions/common";
import { DESC_MAX } from "../../functions/constants";
import { DropdownProps, Props } from "../../interfaces";
import { useConfig } from '../../lib/ConfigContext';
import LoginButton from './LoginButton'; // Import the new LoginButton component
import { useConfig } from '../../functions/useConfig';
import LoginButton from './LoginButton';
import { useAuth } from '../../contexts/AuthContext'; // Add this import

export const MidContainer = ({ children }: Props) => (
<div className="mid-container px-4 sm:px-0">{children}</div>
);

const ProfileOptions = () => {
const [showDropdown, setShowDropdown] = useState(false);
const dropdown = useRef<HTMLDivElement>(null);
const dropdownRef = useRef<HTMLDivElement>(null);
const avatarRef = useRef<HTMLDivElement>(null);

console.log("ProfileOptions - showDropdown:", showDropdown);

const toggleDropdown = useCallback((e: React.MouseEvent) => {
e.stopPropagation();
setShowDropdown(prev => !prev);
}, []);

useEffect(() => {
if (!showDropdown) return;
function handleClick(e: any) {
if (dropdown.current && !dropdown.current.contains(e.target)) {
const handleOutsideClick = (e: MouseEvent) => {
if (
dropdownRef.current &&
!dropdownRef.current.contains(e.target as Node) &&
avatarRef.current &&
!avatarRef.current.contains(e.target as Node)
) {
setShowDropdown(false);
}
};

if (showDropdown) {
document.addEventListener('mousedown', handleOutsideClick);
}
window.addEventListener("click", handleClick);
return () => window.removeEventListener("click", handleClick);
});

return () => {
document.removeEventListener('mousedown', handleOutsideClick);
};
}, [showDropdown]);

return (
<div className="main-black relative">
<div
ref={avatarRef}
className="w-10 h-10 sm:h-8 sm:w-8 flex justify-between items-center rounded-full ml-4 cursor-pointer"
style={{
backgroundImage: `url("/avatar.svg")`,
backgroundSize: "cover",
backgroundPosition: "center",
}}
onClick={() => setShowDropdown(!showDropdown)}
onClick={toggleDropdown}
></div>
{showDropdown ? (
{showDropdown && (
<div
className="dropdown-select absolute w-48 mt-6 z-20 right-0 left-auto rounded sub-text"
ref={dropdown}
className="dropdown-select absolute w-48 mt-2 z-50 right-0 bg-white shadow-lg rounded-md overflow-hidden"
ref={dropdownRef}
>
<Link href="/me" className="my-1 px-5 p-2 cursor-pointer link-black-hover block">
<Link href="/me" className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
View Profile
</Link>
<Link href="/logout" className="my-1 px-5 p-2 cursor-pointer link-black-hover block">
<Link href="/logout" className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
Sign out
</Link>
</div>
) : (
<div></div>
)}
</div>
);
Expand Down Expand Up @@ -130,10 +148,11 @@ export const PostMetadata = ({
</div>
);

export const NavMenu = ({ token = "" }: any) => {
export const NavMenu = () => {
const [showSearch, setShowSearch] = useState(false);
const [searchTerm, setSearchTerm] = useState("");
const config = useConfig();
const { config } = useConfig(); // Destructure to get the config object
const { token } = useAuth();

const newSearch = () => (window.location.href = `/search/?q=${searchTerm}`);

Expand Down Expand Up @@ -189,7 +208,7 @@ export const NavMenu = ({ token = "" }: any) => {
</button>
</Link>
)}
{token != "" ? (
{token ? (
<ProfileOptions />
) : (
<LoginButton />
Expand Down
43 changes: 43 additions & 0 deletions contexts/AuthContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React, { createContext, useState, useContext, useEffect } from 'react';
import Cookies from 'js-cookie';

interface AuthContextType {
token: string | null;
setToken: (token: string | null) => void;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [token, setToken] = useState<string | null>(null);

useEffect(() => {
const storedToken = Cookies.get('token');
if (storedToken) {
setToken(storedToken);
}
}, []);

const updateToken = (newToken: string | null) => {
setToken(newToken);
if (newToken) {
Cookies.set('token', newToken, { expires: 7 });
} else {
Cookies.remove('token');
}
};

return (
<AuthContext.Provider value={{ token, setToken: updateToken }}>
{children}
</AuthContext.Provider>
);
};

export const useAuth = () => {
const context = useContext(AuthContext);
if (context === undefined) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
};
File renamed without changes.
1 change: 1 addition & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const nextConfig = {
publicRuntimeConfig: {
REDDIUM_DISABLE_ABOUT: true,
REDDIUM_DISABLE_KOFI_LINK: true,
REDDIUM_DISABLE_GITHUB_LINK: true,
REDDIUM_DISABLE_LOGIN: true,
REDDIUM_DOMAIN: 'http://localhost:3000',
...Object.fromEntries(
Expand Down
44 changes: 44 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
"cookies-js": "^1.2.3",
"glob": "^11.0.0",
"highlight.run": "^9.5.0",
"js-cookie": "^3.0.5",
"lodash": "^4.17.21",
"micromark": "^4.0.0",
"micromark-extension-gfm": "^3.0.0",
"next": "^14.0.0",
"nookies": "^2.5.2",
"postcss": "^8.4.47",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand All @@ -36,6 +38,7 @@
},
"devDependencies": {
"@eslint/object-schema": "^2.0.0",
"@types/js-cookie": "^3.0.6",
"@types/node": "^18.11.3",
"@types/react": "18.0.21",
"@types/react-dom": "18.0.6",
Expand Down
11 changes: 7 additions & 4 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import React, { useEffect } from "react";
import { AppProps } from "next/app";
import "../styles/styles.css";
import { H } from "highlight.run";
import { ConfigProvider } from '../lib/ConfigContext'
import { ConfigProvider } from '../contexts/ConfigContext'
import { useConfig } from '../functions/useConfig';
import { AuthProvider } from '../contexts/AuthContext';

if (typeof window !== "undefined") {
H.init("5ldw65eo");
Expand All @@ -20,9 +21,11 @@ const App = ({ Component, pageProps }: AppProps) => {

return (
<ConfigProvider>
<div>
<Component {...pageProps} />
</div>
<AuthProvider>
<div>
<Component {...pageProps} />
</div>
</AuthProvider>
</ConfigProvider>
);
};
Expand Down
Loading

0 comments on commit 81d5344

Please sign in to comment.