Skip to content
Merged
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
17 changes: 17 additions & 0 deletions apps/client/src/components/AuthWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ReactNode } from "react";
import { useGlobalContext } from "@/contexts/GlobalContext";

interface AuthWrapperProps {
children?: ReactNode;
fallback?: ReactNode;
}

export const AuthWrapper = ({ children, fallback }: AuthWrapperProps) => {
const { isLoggedIn } = useGlobalContext();

if (!isLoggedIn) {
return fallback ?? null;
}

return <>{children}</>;
};
15 changes: 7 additions & 8 deletions apps/client/src/components/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,17 @@ export const Avatar: FC<AvatarProps> = ({
className,
...props
}) => {
const fallbackBackground = hasRandomBackground
? RandomBackgroundColors[
Math.floor(Math.random() * RandomBackgroundColors.length)
]
: "bg-muted";
const fallbackBackground =
hasRandomBackground && username
? RandomBackgroundColors[
username.charCodeAt(0) % RandomBackgroundColors.length
]
: "bg-base-muted";

return (
<AvatarBase {...props} className={cn(className)}>
<AvatarImage src={src} />
<AvatarFallback className={fallbackBackground}>
{username?.[0].toLocaleUpperCase() || ""}
</AvatarFallback>
<AvatarFallback className={fallbackBackground} />
</AvatarBase>
);
};
108 changes: 97 additions & 11 deletions apps/client/src/components/Content.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,113 @@
// import "katex/dist/katex.min.css"
import { detectFormat, Format } from "@/lib/format"
import type { FC } from "react"
import Latex from "react-latex-next"
import ReactMarkdown from "react-markdown"
import rehypeHighlight from "rehype-highlight"
import remarkGfm from "remark-gfm"
import { detectFormat, Format } from "@/lib/format";
import { cn } from "@/lib/utils";
import type { FC } from "react";
import Latex from "react-latex-next";
import ReactMarkdown from "react-markdown";
import rehypeHighlight from "rehype-highlight";
import remarkGfm from "remark-gfm";

export const Content: FC<{ content: string }> = ({ content }) => {
switch (detectFormat(content)) {
case Format.Markdown:
return (
<div className="prose">
<div>
<ReactMarkdown
remarkPlugins={[remarkGfm]}
rehypePlugins={[rehypeHighlight]}
components={{
h1: ({ children, className }) => (
<h1 className={cn("text-base-foreground", className)}>
{children}
</h1>
),
h2: ({ children, className }) => (
<h2 className={cn("text-base-foreground", className)}>
{children}
</h2>
),
h3: ({ children, className }) => (
<h3 className={cn("text-base-foreground", className)}>
{children}
</h3>
),
h4: ({ children, className }) => (
<h4 className={cn("text-base-foreground", className)}>
{children}
</h4>
),
h5: ({ children, className }) => (
<h5 className={cn("text-base-foreground", className)}>
{children}
</h5>
),
h6: ({ children, className }) => (
<h6 className={cn("text-base-foreground", className)}>
{children}
</h6>
),
strong: ({ children, className }) => (
<strong className={cn("text-base-foreground", className)}>
{children}
</strong>
),
em: ({ children, className }) => (
<em className={cn("text-base-foreground", className)}>
{children}
</em>
),
code: ({ children, className }) => (
<code className={cn("text-base-foreground", className)}>
{children}
</code>
),
blockquote: ({ children, className }) => (
<blockquote className={cn("text-base-foreground", className)}>
{children}
</blockquote>
),
ul: ({ children, className }) => (
<ul className={cn("text-base-foreground", className)}>
{children}
</ul>
),
ol: ({ children, className }) => (
<ol className={cn("text-base-foreground", className)}>
{children}
</ol>
),
p: ({ children, className }) => (
<p className={cn("text-base-foreground", className)}>
{children}
</p>
),
a: ({ children, href, className }) => (
<a
className={cn("text-base-foreground", className)}
href={href}
>
{children}
</a>
),
span: ({ children, className }) => (
<span className={cn("text-base-foreground", className)}>
{children}
</span>
),
div: ({ children, className }) => (
<div className={cn("text-base-foreground", className)}>
{children}
</div>
),
}}
>
{content}
</ReactMarkdown>
</div>
)
);
case Format.Latex:
return <Latex>{content}</Latex>
return <Latex>{content}</Latex>;
case Format.Raw:
return content
return content;
}
}
};
14 changes: 7 additions & 7 deletions apps/client/src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import { LeftSidebar } from "@/components/LeftSidebar";

const DesktopNav = () => {
return (
<div className="hidden lg:flex items-center justify-between gap-5 lg:gap-0 px-4 py-3">
<div className="hidden lg:flex items-center justify-between gap-5 lg:gap-0 px-5 py-3">
<Link to="/" className="hidden lg:flex">
<h1>
<span className="font-space-grotesk font-bold text-black text-[26px] leading-[25px]">
<span className="font-space-grotesk font-bold text-base-logo text-[26px] leading-[25px]">
PSE
</span>
<span className="font-space-grotesk text-black font-normal text-[26px] leading-[25px] tracking-[-1px]">
<span className="font-space-grotesk text-base-logo font-normal text-[26px] leading-[25px] tracking-[-1px]">
forum
</span>
</h1>
Expand Down Expand Up @@ -48,18 +48,18 @@ const MobileNav = () => {
/>
<div
className={cn(
"fixed inset-y-0 p-6 left-0 z-50 w-[320px] bg-white transform transition-transform duration-300 ease-in-out lg:hidden",
"fixed inset-y-0 p-6 left-0 z-50 w-[320px] bg-base-background transform transition-transform duration-300 ease-in-out lg:hidden",
isMenuOpen ? "translate-x-0" : "-translate-x-full",
)}
>
<div className="flex flex-col gap-4">
<div className="flex items-center justify-between">
<Link to="/">
<h1 className="flex gap-1">
<span className="font-space-grotesk font-bold text-black text-xl leading-[20px]">
<span className="font-space-grotesk font-bold text-logo-base text-xl leading-[20px]">
PSE
</span>
<span className="font-space-grotesk text-black font-normal text-base leading-[18px] tracking-[-1px] mt-auto">
<span className="font-space-grotesk text-logo-base font-normal text-base leading-[18px] tracking-[-1px] mt-auto">
forum
</span>
</h1>
Expand Down Expand Up @@ -99,7 +99,7 @@ const MobileNav = () => {

export function Header() {
return (
<nav className="bg-white border-b-[1px] border-b-gray sticky top-0 z-50">
<nav className="bg-base-background border-b-[1px] border-b-base-border sticky top-0 z-50">
<DesktopNav />
<MobileNav />
</nav>
Expand Down
83 changes: 47 additions & 36 deletions apps/client/src/components/LeftSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import { Accordion } from "@/components/Accordion";
import { membershipMocks } from "mocks/membershipMocks";
import { Avatar } from "@/components/Avatar";
import { Badge } from "@/components/ui/Badge";
import { Switch } from "./inputs/Switch";
import { useGlobalContext } from "@/contexts/GlobalContext";
import { AuthWrapper } from "./AuthWrapper";
const renderNavItems = (
_items: (typeof MAIN_NAV_ITEMS)[keyof typeof MAIN_NAV_ITEMS],
) =>
Expand Down Expand Up @@ -45,13 +48,13 @@ const NavItem = ({
to={to}
key={title}
className={cn(
"text-sm font-inter font-medium leading-5 text-black-secondary cursor-pointer outline-none focus:outline-none focus:ring-0 focus:ring-offset-0",
"duration-200 hover:bg-white-light hover:text-black",
"text-sm font-inter font-medium leading-5 text-base-muted-foreground cursor-pointer outline-none focus:outline-none focus:ring-0 focus:ring-offset-0",
"duration-200 hover:bg-muted hover:text-base-primary",
"flex items-center gap-2 rounded-md h-9 py-2 w-full p-2",
)}
>
<div className="flex items-center gap-2">
<Icon className="text-black text-base" size={16} />
<Icon className=" text-base" size={16} />
<span>{title}</span>
</div>
{badge && (
Expand All @@ -75,14 +78,13 @@ const SidebarContent = () => {
return (
<nav
aria-label="Sidebar Navigation"
className="flex flex-col divide-y-[1px] divide-[#E5E7EB]"
className="flex flex-col divide-y-[1px] divide-sidebar-border"
>
<div className="space-y-1 py-6">
<NavItem title="Home" to="/" icon={HomeIcon} />
{renderStartItems()}
{auth?.mapSync(renderStartItems)}
</div>

<Accordion
className="py-6"
items={[
Expand All @@ -98,8 +100,8 @@ const SidebarContent = () => {
params={{ id: `${id}` }}
>
<Avatar className="!size-[32px] !rounded-lg" src={logo} />
<span className="font-semibold font-inter text-sm text-[#3F3F46] line-clamp-1">
{name}
<span className="font-semibold font-inter text-sm text-sidebar-foreground line-clamp-1">
{name} ss
</span>
</Link>
))}
Expand All @@ -108,6 +110,7 @@ const SidebarContent = () => {
},
]}
/>

{user !== undefined && (
<div className="space-y-2 py-6">
<div className="w-full justify-start flex items-center space-x-3 text-sm">
Expand Down Expand Up @@ -147,44 +150,52 @@ const LeftSidebar = () => {
const { data: user } = useQuery(["user.read", auth?.inner?.username], {
enabled: auth?.isSome(),
});
const { isDarkMode, setIsDarkMode } = useGlobalContext();

return (
<aside className="w-[264px] p-6 bg-white-dark hidden flex-col sticky top-[60px] z-[49] lg:flex ">
<aside className="w-[264px] p-6 bg-sidebar-background hidden flex-col sticky top-[60px] z-[49] lg:flex ">
<nav
aria-label="Sidebar Navigation"
className="flex flex-col divide-y-[1px] divide-[#E5E7EB]"
className="flex flex-col divide-y-[1px] divide-sidebar-border"
>
<div className="space-y-1 py-6">
<NavItem title="Home" to="/" icon={HomeIcon} />
{renderStartItems()}
{auth?.mapSync(renderStartItems)}
<AuthWrapper>
{renderStartItems()}
{/* auth?.mapSync(renderStartItems) */}
</AuthWrapper>
</div>

<Accordion
className="py-6"
items={[
{
label: "MY COMMUNITIES",
children: (
<div className="flex flex-col">
{membershipMocks.map(({ id, name, logo }) => (
<Link
key={id}
to="/communities/$id"
className="flex gap-2 items-center py-2 px-3"
params={{ id: `${id}` }}
>
<Avatar className="!size-[32px] !rounded-lg" src={logo} />
<span className="font-semibold font-inter text-sm text-[#3F3F46] line-clamp-1">
{name}
</span>
</Link>
))}
</div>
),
},
]}
/>
<AuthWrapper>
<Accordion
className="py-6"
items={[
{
label: "MY COMMUNITIES",
children: (
<div className="flex flex-col">
{membershipMocks.map(({ id, name, logo }) => (
<Link
key={id}
to="/communities/$id"
className="flex gap-2 items-center py-2 px-3"
params={{ id: `${id}` }}
>
<Avatar
className="!size-[32px] !rounded-lg"
src={logo}
/>
<span className="font-semibold font-inter text-sm text-sidebar-foreground line-clamp-1">
{name}
</span>
</Link>
))}
</div>
),
},
]}
/>
</AuthWrapper>
{user !== undefined && (
<div className="space-y-2 py-6">
<div className="w-full justify-start flex items-center space-x-3 text-sm">
Expand Down
7 changes: 3 additions & 4 deletions apps/client/src/components/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,20 @@ export const MainLayout = ({
showLeftSidebar = false,
showRightSidebar = false,
}: MainLayoutProps) => {
const { isMenuOpen, setIsMenuOpen } = useGlobalContext();
const { isMenuOpen, setIsMenuOpen, isDarkMode } = useGlobalContext();

const router = useRouter();

const pathname = router?.latestLocation?.href;
console.log("router", pathname);

useEffect(() => {
setIsMenuOpen(false);
}, [pathname]);

return (
<div className="h-screen">
<div className={cn("h-screen", isDarkMode ? "dark" : "")}>
{showHeader && <Header />}
<main className="bg-white h-[calc(100vh-65px)] flex justify-between overflow-hidden">
<main className="bg-base-background h-[calc(100vh-65px)] flex justify-between overflow-hidden">
{showLeftSidebar && <LeftSidebar />}
{children && (
<div
Expand Down
2 changes: 1 addition & 1 deletion apps/client/src/components/PageContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const PageContent = ({
"h-full": showEmptyState,
})}
>
{title && <Labels.PageTitle>{title}</Labels.PageTitle>}
{title && <Labels.PageTitle className="">{title}</Labels.PageTitle>}
{children}
{showEmptyState && emptyState && (
<EmptyState
Expand Down
Loading
Loading