Skip to content

Commit

Permalink
feat: added data page
Browse files Browse the repository at this point in the history
- made pages more consistent
  • Loading branch information
cecilia-sanare committed Jan 26, 2024
1 parent 4956dd6 commit d8b3678
Show file tree
Hide file tree
Showing 15 changed files with 366 additions and 134 deletions.
Binary file modified bun.lockb
Binary file not shown.
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"dependencies": {
"@paralleldrive/cuid2": "^2.2.2",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@rain-cafe/react-utils": "^1.2.3",
Expand All @@ -20,14 +21,17 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.21.3",
"react-syntax-highlighter": "^15.5.0",
"tailwind-merge": "^2.2.1",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@types/bun": "^1.0.4",
"@types/node": "^20.11.6",
"@types/parcel-env": "^0.0.5",
"@types/react": "^18.2.48",
"@types/react-dom": "^18.2.18",
"@types/react-syntax-highlighter": "^15.5.11",
"autoprefixer": "^10.4.17",
"parcel": "^2.11.0",
"postcss": "^8.4.33",
Expand Down
10 changes: 7 additions & 3 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ const additionalItems: Header.Item[] = [

export function Header({ children }: HeaderProps) {
return (
<div className="flex min-h-screen">
<div className={'rounded-lg flex flex-col bg-background shadow-sm shadow-indigo-950 p-4 gap-2 min-w-60'}>
<div className="flex min-h-screen max-h-screen">
<div
className={
'rounded-lg flex flex-col bg-background border-r border-r-border shadow-sm shadow-indigo-950 p-4 gap-2 min-w-60'
}
>
<Link className={'font-extrabold text-2xl hover:text-white/80 transition-colors'} to="/">
Devkit
</Link>
Expand All @@ -52,7 +56,7 @@ export function Header({ children }: HeaderProps) {
);
})}
</div>
<div className="flex flex-1 flex-col p-4">{children}</div>
<div className="flex flex-1 flex-col overflow-auto">{children}</div>
</div>
);
}
Expand Down
11 changes: 11 additions & 0 deletions src/components/PageContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { cn } from '@/lib/utils';
import type { ReactNode } from 'react';

export type PageContentProps = {
children: ReactNode;
className?: string;
};

export function PageContent({ children, className }: PageContentProps) {
return <div className={cn('flex flex-col gap-2 p-4', className)}>{children}</div>;
}
20 changes: 20 additions & 0 deletions src/components/PageHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { cn } from '@/lib/utils';
import type { ReactNode } from 'react';

export type PageHeaderProps = {
children: ReactNode;
className?: string;
};

export function PageHeader({ children, className }: PageHeaderProps) {
return (
<div
className={cn(
'sticky px-4 min-h-16 bg-background/80 shadow-sm shadow-indigo-950 top-0 leading-none flex items-center gap-2',
className
)}
>
{children}
</div>
);
}
79 changes: 79 additions & 0 deletions src/components/ui/card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import * as React from "react"

import { cn } from "@/lib/utils"

const Card = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn(
"rounded-lg border bg-card text-card-foreground shadow-sm",
className
)}
{...props}
/>
))
Card.displayName = "Card"

const CardHeader = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col space-y-1.5 p-6", className)}
{...props}
/>
))
CardHeader.displayName = "CardHeader"

const CardTitle = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLHeadingElement>
>(({ className, ...props }, ref) => (
<h3
ref={ref}
className={cn(
"text-2xl font-semibold leading-none tracking-tight",
className
)}
{...props}
/>
))
CardTitle.displayName = "CardTitle"

const CardDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => (
<p
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
CardDescription.displayName = "CardDescription"

const CardContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
))
CardContent.displayName = "CardContent"

const CardFooter = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex items-center p-6 pt-0", className)}
{...props}
/>
))
CardFooter.displayName = "CardFooter"

export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
24 changes: 24 additions & 0 deletions src/components/ui/label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { cva, type VariantProps } from "class-variance-authority"

import { cn } from "@/lib/utils"

const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
)

const Label = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
VariantProps<typeof labelVariants>
>(({ className, ...props }, ref) => (
<LabelPrimitive.Root
ref={ref}
className={cn(labelVariants(), className)}
{...props}
/>
))
Label.displayName = LabelPrimitive.Root.displayName

export { Label }
24 changes: 24 additions & 0 deletions src/components/ui/textarea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as React from "react"

import { cn } from "@/lib/utils"

export interface TextareaProps
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}

const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
({ className, ...props }, ref) => {
return (
<textarea
className={cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
{...props}
/>
)
}
)
Textarea.displayName = "Textarea"

export { Textarea }
10 changes: 10 additions & 0 deletions src/hook.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import { RouterProvider, createHashRouter } from 'react-router-dom';
import { DataPage } from './routes/DataPage';
import { ErrorPage } from './routes/ErrorPage';
import { Root } from './routes/Root';
import { TodoList } from './routes/TodoList';
import { TodoLists } from './routes/TodoLists';
import { IStorage, Storage } from './storage';

if (module.hot) {
module.hot.accept();
}

export function hook(storage: IStorage) {
console.log(`📡 Initializing storage...`);
Storage.init(storage);
Expand All @@ -28,6 +33,11 @@ export function hook(storage: IStorage) {
element: <TodoList />,
loader: TodoList.loader,
},
{
path: '/data',
element: <DataPage />,
loader: DataPage.loader,
},
],
},
]);
Expand Down
39 changes: 39 additions & 0 deletions src/routes/DataPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { PageContent } from '@/components/PageContent';
import { PageHeader } from '@/components/PageHeader';
import { Label } from '@/components/ui/label';
import { Storage } from '@/storage';
import { useMemo } from 'react';
import { useLoaderData } from 'react-router-dom';
import { PrismLight as SyntaxHighlighter } from 'react-syntax-highlighter';
import json from 'react-syntax-highlighter/dist/esm/languages/prism/json';
import { a11yDark } from 'react-syntax-highlighter/dist/esm/styles/prism';

SyntaxHighlighter.registerLanguage('json', json);

export function DataPage() {
const rawData = useLoaderData() as Storage.Data;
const data = useMemo<Record<keyof Storage.Data, string>>(
() => ({
lists: JSON.stringify(rawData.lists, null, 4),
}),
[rawData]
);

return (
<>
<PageHeader className="text-2xl leading-none">Data</PageHeader>
<PageContent>
<Label htmlFor="lists">Todo Lists</Label>
<SyntaxHighlighter language="json" style={a11yDark}>
{data.lists}
</SyntaxHighlighter>
</PageContent>
</>
);
}

export namespace DataPage {
export async function loader(): Promise<Storage.Data> {
return await Storage.everything();
}
}
28 changes: 21 additions & 7 deletions src/routes/ErrorPage.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
import { useRouteError } from 'react-router-dom';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
import { Home } from 'lucide-react';
import { Link, useRouteError } from 'react-router-dom';

export function ErrorPage() {
const error = useRouteError() as any;
console.error(error);

return (
<div id="error-page">
<h1>Oops!</h1>
<p>Sorry, an unexpected error has occurred.</p>
<p>
<i>{error.statusText || error.message}</i>
</p>
<div id="error-page" className="flex flex-col items-center pt-20">
<Card>
<CardHeader>
<CardTitle>Oops!</CardTitle>
</CardHeader>
<CardContent className="flex flex-col gap-2">
<p>Sorry, an unexpected error has occurred.</p>
<code className="flex p-2 rounded-md bg-secondary/50 w-full italic">{error.statusText || error.message}</code>
</CardContent>
<CardFooter>
<Button className="w-full" asChild variant="secondary">
<Link to="/">
<Home className="mr-2 size-4" /> Go Home
</Link>
</Button>
</CardFooter>
</Card>
</div>
);
}
Loading

0 comments on commit d8b3678

Please sign in to comment.