Skip to content
Closed
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
151 changes: 151 additions & 0 deletions app/components/Learn/DocLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import { ReactNode } from "react";
import { Box } from "@mui/material";
import { styled } from "@mui/material/styles";
import { SectionHero } from "../Layout/components/AppLayout/components/Section/components/SectionHero/sectionHero";
import { DocSidebar } from "./components/DocSidebar/docSidebar";
import {
BREADCRUMBS,
DOCUMENTATION_CATEGORIES,
} from "../../views/LearnView/common/constants";
import {
Section,
SectionLayout,
SectionContent,
} from "../content/content.styles";

// Styled components for content layout
const ContentContainer = styled(Box)(({ theme }) => ({
display: "flex",
flexDirection: "row",
gap: theme.spacing(4),
width: "100%",
}));

// Main content styling
const MainContentWrapper = styled(Box)(({ theme }) => ({
"& code": {
backgroundColor: theme.palette.grey[100],
borderRadius: 3,
fontSize: "0.9em",
padding: theme.spacing(0.5, 1),
wordBreak: "break-word",
},
"& h1": {
[theme.breakpoints.down("md")]: {
fontSize: "1.75rem",
},
[theme.breakpoints.down("sm")]: {
fontSize: "1.5rem",
},
fontSize: "2rem",
fontWeight: 600,
marginBottom: theme.spacing(2),
},
"& h2": {
[theme.breakpoints.down("md")]: {
fontSize: "1.35rem",
},
[theme.breakpoints.down("sm")]: {
fontSize: "1.25rem",
},
fontSize: "1.5rem",
fontWeight: 600,
marginBottom: theme.spacing(2),
marginTop: theme.spacing(4),
},
"& h3": {
[theme.breakpoints.down("md")]: {
fontSize: "1.15rem",
},
[theme.breakpoints.down("sm")]: {
fontSize: "1.1rem",
},
fontSize: "1.25rem",
fontWeight: 600,
marginBottom: theme.spacing(1.5),
marginTop: theme.spacing(3),
},
"& img": {
height: "auto",
maxWidth: "100%",
},
"& pre": {
[theme.breakpoints.down("sm")]: {
padding: theme.spacing(1.5),
},
backgroundColor: theme.palette.grey[100],
borderRadius: theme.shape.borderRadius,
marginBottom: theme.spacing(2),
overflow: "auto",
padding: theme.spacing(2),
},
"& table": {
borderCollapse: "collapse",
display: "block",
marginBottom: theme.spacing(2),
overflowX: "auto",
width: "100%",
},
"& th": {
backgroundColor: theme.palette.grey[100],
fontWeight: 600,
},
"& th, & td": {
border: `1px solid ${theme.palette.divider}`,
padding: theme.spacing(1, 2),
textAlign: "left",
},
flex: 1,
maxWidth: "800px",
}));

// Sidebar container
const SidebarContainer = styled(Box)(({ theme }) => ({
[theme.breakpoints.down("md")]: {
display: "none",
},
alignSelf: "flex-start",
position: "sticky",
top: theme.spacing(3),
width: "260px",
}));

export interface DocLayoutProps {
children: ReactNode;
description?: string;
title?: string;
}

export const DocLayout = ({
children,
description = "Documentation, tutorials, and resources to help you get the most out of BRC Analytics.",
title = "Learn BRC Analytics",
}: DocLayoutProps): JSX.Element => {
return (
<>
{/* Hero Section with Title and Breadcrumbs */}
<SectionHero
breadcrumbs={BREADCRUMBS}
head={title}
subHead={description}
/>

{/* Main Content Section */}
<Section border>
<SectionLayout>
<SectionContent>
<ContentContainer>
{/* Main Documentation Content */}
<MainContentWrapper>{children}</MainContentWrapper>

{/* Sidebar */}
<SidebarContainer>
<DocSidebar categories={DOCUMENTATION_CATEGORIES} />
</SidebarContainer>
</ContentContainer>
</SectionContent>
</SectionLayout>
</Section>
</>
);
};
44 changes: 44 additions & 0 deletions app/components/Learn/components/CodeBlock/codeBlock.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { styled } from "@mui/material";

export const StyledCodeBlock = styled("pre")(({ theme }) => ({
"& code": {
display: "block",
fontFamily: "inherit",
whiteSpace: "pre",
},
"&::-webkit-scrollbar": {
height: 8,
width: 8,
},
"&::-webkit-scrollbar-thumb": {
backgroundColor: theme.palette.grey[700],
borderRadius: 4,
},
"&::-webkit-scrollbar-track": {
backgroundColor: theme.palette.grey[800],
},
backgroundColor: theme.palette.grey[900],
borderRadius: theme.shape.borderRadius,
color: theme.palette.common.white,
fontFamily: "monospace",
fontSize: "0.875rem",
lineHeight: 1.5,
margin: theme.spacing(2, 0),
overflow: "auto",
padding: theme.spacing(2),
position: "relative",
}));

export const StyledLanguageTag = styled("div")(({ theme }) => ({
backgroundColor: theme.palette.primary.main,
borderRadius: `${theme.shape.borderRadius}px ${theme.shape.borderRadius}px 0 0`,
color: theme.palette.primary.contrastText,
fontSize: "0.75rem",
fontWeight: 600,
letterSpacing: 0.5,
padding: theme.spacing(0.5, 1),
position: "absolute",
right: 10,
textTransform: "uppercase",
top: 0,
}));
34 changes: 34 additions & 0 deletions app/components/Learn/components/CodeBlock/codeBlock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ReactNode } from "react";
import { StyledCodeBlock, StyledLanguageTag } from "./codeBlock.styles";
import DOMPurify from "isomorphic-dompurify";

export interface CodeBlockProps {
children: ReactNode;
className?: string;
language?: string;
}

export const CodeBlock = ({
children,
className,
language,
}: CodeBlockProps): JSX.Element => {
// Extract language from className (if using ```javascript syntax)
const languageFromClass = className
? className.replace("language-", "")
: null;
const displayLanguage = language || languageFromClass || null;

// Sanitize code content
const codeContent =
typeof children === "string" ? DOMPurify.sanitize(children) : children;

return (
<StyledCodeBlock>
{displayLanguage && (
<StyledLanguageTag>{displayLanguage}</StyledLanguageTag>
)}
<code>{codeContent}</code>
</StyledCodeBlock>
);
};
1 change: 1 addition & 0 deletions app/components/Learn/components/CodeBlock/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./codeBlock";
82 changes: 82 additions & 0 deletions app/components/Learn/components/DocSidebar/docSidebar.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { styled } from "@mui/material";

export const StyledDocSidebar = styled("aside")(({ theme }) => ({
"& .category-title": {
"&:first-of-type": {
marginTop: 0,
},
color: theme.palette.text.secondary,
fontSize: "0.875rem",
fontWeight: 600,
letterSpacing: "0.5px",
marginBottom: theme.spacing(1.5),
marginTop: theme.spacing(3),
padding: theme.spacing(0, 1),
textTransform: "uppercase",
},
"& .item": {
"&.active": {
"& .item-icon": {
color: theme.palette.primary.main,
},
"&::before": {
backgroundColor: theme.palette.primary.main,
borderBottomLeftRadius: theme.shape.borderRadius,
borderTopLeftRadius: theme.shape.borderRadius,
bottom: 0,
content: '""',
left: 0,
position: "absolute",
top: 0,
width: 4,
},
backgroundColor: `${theme.palette.primary.main}10`, // 10% opacity version of primary color
color: theme.palette.primary.main,
fontWeight: 500,
},
"&:hover": {
"& .item-icon": {
color: theme.palette.primary.main,
},
backgroundColor: `${theme.palette.action.hover}`,
color: theme.palette.primary.main,
},
alignItems: "center",
borderRadius: theme.shape.borderRadius,
color: theme.palette.text.primary,
display: "flex",
fontSize: "0.9375rem",
padding: theme.spacing(0.75, 1.5),
position: "relative",
textDecoration: "none",
transition: "all 0.2s ease",
},
"& .item-icon": {
alignItems: "center",
color: theme.palette.text.secondary,
display: "flex",
height: 24,
justifyContent: "center",
minWidth: 24,
transition: "color 0.2s ease",
width: 24,
},
"& li": {
margin: theme.spacing(0.75, 0),
},
"& nav": {
width: "100%",
},
"& ul": {
listStyle: "none",
margin: 0,
padding: 0,
},
backgroundColor: theme.palette.background.paper,
borderRadius: theme.shape.borderRadius,
boxShadow: "0 2px 6px rgba(0, 0, 0, 0.05)",
height: "100%",
minWidth: "240px",
overflowY: "auto",
padding: theme.spacing(3),
}));
Loading
Loading