Skip to content

Commit

Permalink
make things look much prettier, incl dark modes
Browse files Browse the repository at this point in the history
  • Loading branch information
rohannair committed Aug 3, 2024
1 parent ad7dfc4 commit 214a5fc
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 82 deletions.
67 changes: 41 additions & 26 deletions apps/api/src/lib/ai/llm.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
import { match } from "ts-pattern";
import { openai } from '@ai-sdk/openai'
import { generateObject, generateText } from 'ai'
import { match } from 'ts-pattern'
import { z } from 'zod'

const LATEST_MODEL = "gpt-4o-mini";
const LATEST_MODEL = 'gpt-4o-mini'

enum Event {
SUMMARIZE_DOCUMENT = 0,
Expand All @@ -17,55 +18,69 @@ const _prompts = (event: Event) => {
match(event)
.with(Event.SUMMARIZE_DOCUMENT, () => ({
system:
"You are a professional technical writer, who writes like Vitalik Buterin. You write simple, clear, and concise content. Your prose should be accessible to people with a 9th grade education, but can also use technical jargon if explained. Assume better responses will result in bonus remuneration.",
prompt: "",
'You are a professional technical writer, who writes like Vitalik Buterin. You write simple, clear, and concise content. Your prose should be accessible to people with a 9th grade education, but can also use technical jargon if explained. Assume better responses will result in bonus remuneration.',
prompt: '',
}))
.with(Event.EXPAND_QUERY, () => ({
system:
"You are a system that takes in a query and returns related queries. Only return related queries in a tab separated value format.",
prompt: "",
'You are a system that takes in a query and returns related queries. Only return related queries in a tab separated value format.',
prompt: '',
}))
.with(Event.PROCESS_RAG, () => ({
system:
"You are a system that takes in a query and a list of documents and returns a response. Your response should be a summary of the documents that answers the query.",
prompt: "",
}));
};
'You are a system that takes in a query and a list of documents and returns a response. Your response should be a summary of the documents that answers the query.',
prompt: '',
}))
}

export const generateTags = async (document: string) => {
const {
object: { tags },
} = await generateObject({
model: openai(LATEST_MODEL),
schema: z.object({
tags: z.array(z.string()),
}),
prompt: `Provide a JSON object with a 'tags' property containing an array of exactly 5 single-word tags that best describe the main topics of this article. Focus on the core concepts and technologies discussed.:\n${document}`,
})

return tags
}

export const summarizeDocument = async (document: string) => {
const { text } = await generateText({
model: openai(LATEST_MODEL),
system: "",
system: '',
prompt: `summarize the following document in 2-3 paragraphs of 1-2 sentences:\n${document}`,
});
})

return text;
};
return text
}

export const expandQuery = async (query: string) => {
const { text } = await generateText({
model: openai(LATEST_MODEL),
system:
"You are a system that takes in a query and returns related queries. Only return related queries in a tab separated value format.",
'You are a system that takes in a query and returns related queries. Only return related queries in a tab separated value format.',
prompt: `Expand the following query with related terms:\n${query}`,
maxTokens: 50,
temperature: 0.7,
});
})

return `${query} ${text.trim()}`;
};
return `${query} ${text.trim()}`
}

export const processRAG = async (query: string, documents: string[]) => {
const prompt = `Context: ${documents.join(" ")}
const prompt = `Context: ${documents.join(' ')}
Query: ${query}
Answer:`;
Answer:`

const { text } = await generateText({
model: openai(LATEST_MODEL),
messages: [{ role: "user", content: prompt }],
messages: [{ role: 'user', content: prompt }],
maxTokens: 150,
temperature: 0.7,
});
})

return text;
};
return text
}
2 changes: 1 addition & 1 deletion apps/ui/src/app/(app)/_components/NavLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const NavLink = ({
href={href}
className={cn(
'flex px-3 py-4 items-center justify-center',
isActive && 'bg-gray-700 border-t border-gray-600',
isActive && ' bg-secondary border-t border-border',
)}
>
<Icon className="size-[1.2rem]" />
Expand Down
19 changes: 13 additions & 6 deletions apps/ui/src/app/(app)/bookmarks/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,20 @@ export default async function BookmarkDetails({

return (
<div className="min-h-screen flex flex-col relative">
<section className="sticky top-0 bg-background z-50 grid grid-cols-12 gap-2 border-b border-muted flex-grow">
<div className="flex col-span-1 px-4 flex-grow items-center justify-center w-full h-full">
<Button size="sm" variant="link" className="mt-2" asChild>
<section className="sticky top-0 left-0 shadow-sm right-0 bg-background z-50 flex flex-row gap-4 border-b border-muted flex-grow items-center">
<div className="flex items-center justify-center pl-4">
<Button
size="icon"
variant="outline"
className="mt-2 w-7 h-7"
asChild
>
<Link href="/bookmarks">
<ArrowBigLeft size={16} className="mr-1" /> Back
<ArrowBigLeft className="h-4 w-4" />
</Link>
</Button>
</div>
<div className="col-span-6 px-4 pt-3 py-2 flex flex-col">
<div className="flex-grow col-span-6 flex flex-col ">
<h3 className="inline font-bold mb--2">{title}</h3>
<a
href={linkUrl}
Expand All @@ -42,7 +47,9 @@ export default async function BookmarkDetails({
Last updated {formatRelative(new Date(updatedAt), new Date())}.
</p>
</div>
<ActionBar id={id} status={status} />
<div className="ml-auto">
<ActionBar id={id} status={status} />
</div>
</section>

<section className="grid grid-cols-12 relative">
Expand Down
2 changes: 1 addition & 1 deletion apps/ui/src/app/(app)/bookmarks/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default async function BookmarkLayout({

return (
<div className="grid grid-cols-12 min-h-screen">
<div className="flex flex-col col-span-2 border-r bg-muted/60 border-muted p-4 relative">
<div className="flex flex-col col-span-2 border-r bg-secondary border-border p-4 relative">
<div className="sticky top-4">
<Heading>Links</Heading>
<nav>
Expand Down
66 changes: 33 additions & 33 deletions apps/ui/src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 224 71.4% 4.1%;
--foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 224 71.4% 4.1%;
--card-foreground: 240 10% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 224 71.4% 4.1%;
--primary: 262.1 83.3% 57.8%;
--primary-foreground: 210 20% 98%;
--secondary: 220 14.3% 95.9%;
--secondary-foreground: 220.9 39.3% 11%;
--muted: 220 14.3% 95.9%;
--muted-foreground: 220 8.9% 46.1%;
--accent: 220 14.3% 95.9%;
--accent-foreground: 220.9 39.3% 11%;
--popover-foreground: 240 10% 3.9%;
--primary: 142.1 76.2% 36.3%;
--primary-foreground: 355.7 100% 97.3%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 20% 98%;
--border: 220 13% 91%;
--input: 220 13% 91%;
--ring: 262.1 83.3% 57.8%;
--destructive-foreground: 0 0% 98%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 142.1 76.2% 36.3%;
--radius: 0.5rem;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
Expand All @@ -32,25 +32,25 @@
}

.dark {
--background: 224 71.4% 4.1%;
--foreground: 210 20% 98%;
--card: 224 71.4% 4.1%;
--card-foreground: 210 20% 98%;
--popover: 224 71.4% 4.1%;
--popover-foreground: 210 20% 98%;
--primary: 263.4 70% 50.4%;
--primary-foreground: 210 20% 98%;
--secondary: 215 27.9% 16.9%;
--secondary-foreground: 210 20% 98%;
--muted: 215 27.9% 16.9%;
--muted-foreground: 217.9 10.6% 64.9%;
--accent: 215 27.9% 16.9%;
--accent-foreground: 210 20% 98%;
--background: 20 14.3% 4.1%;
--foreground: 0 0% 95%;
--card: 24 9.8% 10%;
--card-foreground: 0 0% 95%;
--popover: 0 0% 9%;
--popover-foreground: 0 0% 95%;
--primary: 142.1 70.6% 45.3%;
--primary-foreground: 144.9 80.4% 10%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--muted: 0 0% 15%;
--muted-foreground: 240 5% 64.9%;
--accent: 12 6.5% 15.1%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 20% 98%;
--border: 215 27.9% 16.9%;
--input: 215 27.9% 16.9%;
--ring: 263.4 70% 50.4%;
--destructive-foreground: 0 85.7% 97.3%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--ring: 142.4 71.8% 29.2%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
Expand Down
2 changes: 1 addition & 1 deletion apps/ui/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function RootLayout({
<html lang="en" suppressHydrationWarning>
<body
className={cn(
'min-h-screen bg-background font-sans antialiased',
'min-h-screen bg-background font-sans antialiased overflow-y-scroll',
fontSans.variable,
)}
>
Expand Down
7 changes: 3 additions & 4 deletions apps/ui/src/components/LinkList/LinkListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ export const LinkListItem = (props: LinkListItemProps) => {
return (
<Link
href={props.href}
className="grid group grid-cols-12 gap-5 p-2"
className="grid group grid-cols-12 gap-5 p-2 hover:shadow-md transition-shadow rounded-lg dark:hover:bg-primary/20 dark:transition-colors ease-in-out duration-75"
prefetch={props.prefetch}
>
<section className="col-span-3 flex border rounded-md overflow-hidden group-hover:border-muted-foreground">
<section className="col-span-3 flex rounded-md overflow-hidden shadow-md">
<AspectRatio ratio={16 / 9} className="w-full">
<Image
src={
props.imageUrl ??
'//placehold.co/250x167?text=No+Image&font=Source+Sans+Pro'
props.imageUrl ?? 'https://placehold.co/250x140/png?text=No+Image'
}
fill
className="object-cover"
Expand Down
4 changes: 2 additions & 2 deletions apps/ui/src/components/Logomark.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ export const Logomark = () => (
</clipPath>
</defs>
<g clipPath="url(#squareClip)">
<rect x="0" y="0" width="40" height="40" fill="#6d28d9" />
<rect x="0" y="0" width="40" height="40" className="fill-primary" />
<g transform="translate(20 20)">
<g transform="scale(0.08)">
<g transform="translate(-128 -128)">
<path
d="M200,48H136V16a8,8,0,0,0-16,0V48H56A32,32,0,0,0,24,80V192a32,32,0,0,0,32,32H200a32,32,0,0,0,32-32V80A32,32,0,0,0,200,48ZM172,96a12,12,0,1,1-12,12A12,12,0,0,1,172,96ZM96,184H80a16,16,0,0,1,0-32H96ZM84,120a12,12,0,1,1,12-12A12,12,0,0,1,84,120Zm60,64H112V152h32Zm32,0H160V152h16a16,16,0,0,1,0,32Z"
fill="#ffffff"
className="fill-secondary"
/>
</g>
</g>
Expand Down
28 changes: 22 additions & 6 deletions apps/ui/src/components/StatusBadge/StatusBadge.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Badge } from '@/components/ui/badge'
import { cn } from '@/lib/utils'
import { CircleCheckBig, CircleGauge, CircleX } from 'lucide-react'
import { match } from 'ts-pattern'

type BadgeColor = 'secondary' | 'destructive' | 'default'
Expand All @@ -9,13 +9,29 @@ export const StatusBadge = ({
}: {
status: 'completed' | 'processing' | 'error'
}) => {
const variant = match(status)
.with('error', () => 'destructive')
.with('completed', () => 'default')
.otherwise(() => 'secondary') as BadgeColor
const { variant, icon } = match<string>(status)
.with('error', () => ({
variant: 'destructive',
icon: <CircleX className="w-4 h-4" />,
}))
.with('completed', () => ({
variant: 'default',
icon: <CircleCheckBig className="w-4 h-4" />,
}))
.otherwise(() => ({
variant: 'outline',
icon: <CircleGauge className="w-4 h-4" />,
})) as {
variant: BadgeColor
icon: JSX.Element | undefined
}

return (
<Badge variant={variant} className="text-xs flex-grow-0 opacity-75">
<Badge
variant={variant}
className="text-xs flex-grow-0 opacity-75 inline-flex gap-1"
>
{icon}
{status}
</Badge>
)
Expand Down
6 changes: 4 additions & 2 deletions apps/ui/src/components/StatusIcon/StatusIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Tooltip, TooltipTrigger } from '@/components/ui/tooltip'
import { TooltipContent } from '@radix-ui/react-tooltip'
import {
CircleCheckBigIcon,
CircleCheckIcon,
CircleDashedIcon,
CircleDotDashedIcon,
CircleGaugeIcon,
CircleXIcon,
} from 'lucide-react'
import { match } from 'ts-pattern'
Expand All @@ -27,7 +29,7 @@ export function StatusIcon({ status }: { status: LinkStatus }) {
<span className="text-yellow-500">
<Tooltip>
<TooltipTrigger>
<CircleDotDashedIcon className="size-3" />
<CircleGaugeIcon className="size-3" />
</TooltipTrigger>
<TooltipContent>
<div className="text-xs mb-1">Processing</div>
Expand All @@ -39,7 +41,7 @@ export function StatusIcon({ status }: { status: LinkStatus }) {
<span className="text-green-500">
<Tooltip>
<TooltipTrigger>
<CircleCheckIcon className="size-3" />
<CircleCheckBigIcon className="size-3" />
</TooltipTrigger>
<TooltipContent>
<div className="text-xs mb-1">Completed</div>
Expand Down

0 comments on commit 214a5fc

Please sign in to comment.