Skip to content

Commit

Permalink
Added snapshot -> capture
Browse files Browse the repository at this point in the history
  • Loading branch information
changesbyjames committed Sep 4, 2024
1 parent 4f6668d commit ae316f8
Show file tree
Hide file tree
Showing 33 changed files with 1,265 additions and 169 deletions.
20 changes: 20 additions & 0 deletions apps/ui/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "src/index.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
}
}
9 changes: 9 additions & 0 deletions apps/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,18 @@
"@hookform/resolvers": "^3.9.0",
"@microsoft/applicationinsights-react-js": "^17.3.1",
"@microsoft/applicationinsights-web": "^3.3.1",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-tooltip": "^1.1.2",
"@tanstack/react-query": "^5.52.2",
"@trpc/client": "11.0.0-rc.490",
"@trpc/server": "11.0.0-rc.490",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"date-fns": "^3.6.0",
"date-fns-tz": "^3.1.3",
"framer-motion": "^11.3.29",
"lucide-react": "^0.438.0",
"next-themes": "^0.3.0",
"oslo": "^1.2.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand All @@ -31,6 +37,9 @@
"react-markdown": "^9.0.1",
"react-router": "^6.26.1",
"react-router-dom": "^6.26.1",
"sonner": "^1.5.0",
"tailwind-merge": "^2.5.2",
"tailwindcss-animate": "^1.0.7",
"vite-plugin-info": "^0.4.1",
"zod": "^3.23.8",
"zustand": "^4.5.5"
Expand Down
2 changes: 2 additions & 0 deletions apps/ui/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Loading } from '@critter/react/loaders/Loading';
import { Suspense } from 'react';
import { RouterProvider } from 'react-router-dom';
import { Toaster } from './components/feedback/Toaster';
import { router } from './router';
import { CritterAuthenticationProvider } from './services/authentication/CritterAuthenticationProvider';
import { BackstageProvider } from './services/backstage/BackstageProvider';
Expand All @@ -18,6 +19,7 @@ export const App = () => {
<CritterAuthenticationProvider>
<AppInsightsProvider>
<APIProvider>
<Toaster />
<RouterProvider router={router} />
</APIProvider>
</AppInsightsProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Button } from '@critter/react/button/juicy';
import { Spinner } from '@critter/react/loaders/Spinner';
import { AnimatePresence } from 'framer-motion';
import { FC, Suspense, useEffect } from 'react';
import { Thumbnail } from '../images/Thumbnail';
import { Thumbnail } from '../../pages/snapshots/images/Thumbnail';

interface DockProps {
images: string[];
Expand Down Expand Up @@ -96,7 +96,7 @@ export const Dock: FC<DockProps> = ({
</Button>
</div>
)}
<div className="flex items-center gap-2 h-24 bg-accent-300 rounded-2xl px-4 py-4 w-fit max-w-full">
<div className="flex items-center gap-2 h-20 bg-accent-300 rounded-2xl px-4 py-4 w-fit max-w-full">
<AnimatePresence initial={false}>
{images.sort().map((image, index) => {
return (
Expand Down
24 changes: 24 additions & 0 deletions apps/ui/src/components/feedback/Toaster.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Toaster as Sonner } from 'sonner';

type ToasterProps = React.ComponentProps<typeof Sonner>;

const Toaster = ({ ...props }: ToasterProps) => {
return (
<Sonner
className="toaster group"
position="bottom-right"
toastOptions={{
classNames: {
toast:
'group toast font-sans group-[.toaster]:bg-accent-50 border group-[.toaster]:text-accent-900 group-[.toaster]:border-accent-900 group-[.toaster]:border-opacity-10 group-[.toaster]:shadow-lg',
title: 'group-[.toast]:font-semibold',
description: 'group-[.toast]:text-accent-700 group-[.toast]:font-semibold',
actionButton: 'group-[.toast]:bg-accent-50 group-[.toast]:text-accent-900',
cancelButton: 'group-[.toast]:bg-accent-50 group-[.toast]:text-accent-900'
}
}}
{...props}
/>
);
};
export { Toaster };
27 changes: 27 additions & 0 deletions apps/ui/src/components/feedback/Tooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { cn } from '@critter/react/utils/cn';
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
import * as React from 'react';

const TooltipProvider = TooltipPrimitive.Provider;

const Tooltip = TooltipPrimitive.Root;

const TooltipTrigger = TooltipPrimitive.Trigger;

const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
'z-50 overflow-hidden rounded-lg bg-accent-300 pt-2 pb-2.5 shadow-[inset_0_-7px_0px_-0.25rem_rgba(0,0,0,0.15)] px-3 text-sm text-accent-950 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
className
)}
{...props}
/>
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;

export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
18 changes: 17 additions & 1 deletion apps/ui/src/components/text/Timestamp.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/feedback/Tooltip';
import { format } from 'date-fns';
import { formatInTimeZone } from 'date-fns-tz';
import { FC } from 'react';

interface TimestampProps {
date: Date;
}

export const Timestamp: FC<TimestampProps> = ({ date }) => {
return <span>{formatInTimeZone(date, 'America/Chicago', 'PP p')}</span>;
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger>
<span>{formatInTimeZone(date, 'America/Chicago', 'PP p')}</span>
</TooltipTrigger>
<TooltipContent>
<span className="flex gap-2 items-center">
<span>Your time: {format(date, 'PP p')}</span>
</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
};
65 changes: 65 additions & 0 deletions apps/ui/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,68 @@ html {
--accent-color-900: 120 55 12;
--accent-color-950: 75 39 12;
}

@layer base {
:root {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
--card: 0 0% 100%;
--card-foreground: 0 0% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 0 0% 3.9%;
--primary: 0 0% 9%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 96.1%;
--secondary-foreground: 0 0% 9%;
--muted: 0 0% 96.1%;
--muted-foreground: 0 0% 45.1%;
--accent: 0 0% 96.1%;
--accent-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 89.8%;
--input: 0 0% 89.8%;
--ring: 0 0% 3.9%;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
--radius: 0.5rem;
}
.dark {
--background: 0 0% 3.9%;
--foreground: 0 0% 98%;
--card: 0 0% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 0 0% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 0 0% 9%;
--secondary: 0 0% 14.9%;
--secondary-foreground: 0 0% 98%;
--muted: 0 0% 14.9%;
--muted-foreground: 0 0% 63.9%;
--accent: 0 0% 14.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--input: 0 0% 14.9%;
--ring: 0 0% 83.1%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
}

@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
24 changes: 14 additions & 10 deletions apps/ui/src/layouts/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ import { Menu, MenuItem } from '../components/menu/Menu';

import { Docs } from '@/components/assets/icons/Docs';
import { Wordmark } from '@/components/assets/logos/Wordmark';
import { Variables } from '@/services/backstage/config';
import { usePermissions } from '@/services/permissions/hooks';
import { useVariable } from '@critter/backstage';
import { Loading } from '@critter/react/loaders/Loading';
import { Suspense } from 'react';
import { Outlet } from 'react-router';

export const Main = () => {
const { editor } = usePermissions();

const docsUrl = useVariable<Variables>('docsUrl');
return (
<div className="h-screen min-h-screen max-h-screen w-screen flex flex-col">
{!editor && (
Expand All @@ -40,30 +42,32 @@ export const Main = () => {
<CritterCaptureClubLogo />
</MenuItem>
<MenuItem>
<Button className="w-full" disabled>
<Button className="w-full" disabled="Coming soon!">
<Binoculars />
All captures
</Button>
</MenuItem>
<MenuItem>
<Button className="w-full" disabled>
<Button className="w-full" disabled="Coming soon!">
<Binoculars />
My captures
</Button>
</MenuItem>
<MenuItem>
<Link to="/snapshots/pending" className="w-full">
<Link to="/snapshots/pending" className="w-full" disabled="Coming soon!">
<Picture />
Pending screenshots
</Link>
</MenuItem>
<div className="flex-1" />
<MenuItem>
<Link to="/docs" className="w-full">
<Docs />
Documentation
</Link>
</MenuItem>
{docsUrl && (
<MenuItem>
<Link to={docsUrl} className="w-full">
<Docs />
Documentation
</Link>
</MenuItem>
)}
<MenuItem>
<Link to="/auth/signout" className="w-full">
<SignOut />
Expand Down
50 changes: 50 additions & 0 deletions apps/ui/src/pages/captures/Capture.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Note } from '@/components/containers/Note';
import { Timestamp } from '@/components/text/Timestamp';
import { useCapture } from '@/services/api/capture';
import { FC, useMemo, useState } from 'react';
import { useParams } from 'react-router';
import { Dock } from '../../components/controls/Dock';
import { Main } from '../snapshots/images/Main';

export const Capture: FC = () => {
const params = useParams();
const id = useMemo(() => Number(params.id), [params.id]);
const snapshot = useCapture(id);

const [mainImageIndex, setMainImageIndex] = useState<number | undefined>(
snapshot.data.images.length > 0 ? 0 : undefined
);

return (
<div className="flex-1 bg-accent-100 p-8 flex flex-col gap-6 items-center">
<nav className="w-full relative flex items-center justify-end">
<Note className="w-fit z-10 absolute top-0 left-0 rounded-md min-w-96">
<h2 className="text-2xl font-medium px-3 outline-none bg-accent-50 placeholder:opacity-25 placeholder:text-accent-900">
{snapshot.data.name}
</h2>
<p className="px-3 py-1 text-sm">
Captured by <strong>{snapshot.data.createdBy}</strong>
</p>
<p className="px-3 py-1 text-sm">
Captured at{' '}
<strong>
<Timestamp date={new Date(snapshot.data.createdAt)} />
</strong>
</p>
</Note>
</nav>
<div className="w-full relative flex-1">
<div className="h-full flex items-center justify-center">
{mainImageIndex !== undefined && (
<Main key={snapshot.data.images[mainImageIndex].id} url={snapshot.data.images[mainImageIndex].url} />
)}
</div>
</div>
<Dock
images={snapshot.data.images.map(i => i.url)}
selectedIndex={mainImageIndex}
setSelectedIndex={setMainImageIndex}
/>
</div>
);
};
Loading

0 comments on commit ae316f8

Please sign in to comment.