Skip to content

Commit

Permalink
clean up submission ux
Browse files Browse the repository at this point in the history
Signed-off-by: Rohan Nair <[email protected]>
  • Loading branch information
Rohan Nair authored and rohannair committed Aug 2, 2024
1 parent 1bb2092 commit 9484f83
Show file tree
Hide file tree
Showing 17 changed files with 96 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
Expand Down
2 changes: 1 addition & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@scalar/hono-api-reference": "^0.5.100",
"@tensorflow-models/universal-sentence-encoder": "^1.3.3",
"@tensorflow/tfjs-node": "^4.20.0",
"@trigger.dev/sdk": "3.0.0-beta.51",
"@trigger.dev/sdk": "3.0.0-beta.52",
"ai": "^3.2.19",
"cheerio": "^1.0.0-rc.12",
"drizzle-orm": "^0.32.0",
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/lib/ai/llm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const summarizeDocument = async (document: string) => {
const { text } = await generateText({
model: openai(LATEST_MODEL),
system: "",
prompt: `summarize the following document in 1-2 paragraphs:\n${document}`,
prompt: `summarize the following document in 2-3 paragraphs of 1-2 sentences:\n${document}`,
});

return text;
Expand Down
1 change: 0 additions & 1 deletion apps/api/src/lib/scraper/fetchSite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { env } from '@/env'

export async function fetchSite(url: string) {
try {
console.log('fetching', url)
const resp = await fetch(`https://r.jina.ai/${url}`, {
headers: {
Accept: 'application/json',
Expand Down
9 changes: 6 additions & 3 deletions apps/api/src/modules/api/handlers/queueScrape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ export const queueScrape = new OpenAPIHono<Env>().openapi(
method: 'post',
path: '/',
request: {
query: z.object({
retry: z.boolean().optional().default(false),
}),
body: {
content: {
'application/json': {
Expand Down Expand Up @@ -84,6 +87,7 @@ export const queueScrape = new OpenAPIHono<Env>().openapi(
// @ts-ignore
async (c) => {
const { url } = c.req.valid('json')
const { retry } = c.req.valid('query')

if (!c.var.user?.id) {
return c.json({ message: 'Not logged in' }, 401)
Expand All @@ -93,8 +97,7 @@ export const queueScrape = new OpenAPIHono<Env>().openapi(
return c.json({ message: 'This site is not yet supported' }, 400)
}

const links = await createLinkRepository()

const links = createLinkRepository()
const link = await links.createLink({
url,
userId: c.var.user?.id,
Expand All @@ -104,7 +107,7 @@ export const queueScrape = new OpenAPIHono<Env>().openapi(
return c.json({ message: 'Something went wrong' }, 400)
}

if (!link.summary) {
if (retry || !link.summary) {
await scrapeWebsite.trigger({
url,
link: link.id,
Expand Down
1 change: 1 addition & 0 deletions apps/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"sanitize-html": "^2.13.0",
"set-cookie-parser": "^2.6.0",
"sonner": "^1.5.0",
"swr": "^2.2.5",
"tailwind-merge": "^2.4.0",
"tailwindcss-animate": "^1.0.7",
"ts-pattern": "^5.2.0",
Expand Down
2 changes: 1 addition & 1 deletion apps/ui/src/app/(app)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export default function Dashboard() {
return <h1>Dashboard</h1>
return <div className="p4"><h1>Dashboard</h1></div>
}
17 changes: 3 additions & 14 deletions apps/ui/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,13 @@ import { ThemeProvider } from '@/components/theme-provider'
import { Dialog } from '@/components/ui/dialog'
import { Toaster } from '@/components/ui/sonner'
import { TooltipProvider } from '@/components/ui/tooltip'
import { fontSans } from '@/lib/fonts'
import { cn } from '@/lib/utils'
import type { Metadata, Viewport } from 'next'
import { Fragment_Mono, Instrument_Sans } from 'next/font/google'

const fontSans = Instrument_Sans({
subsets: ['latin'],
variable: '--font-sans',
})

const _ = Fragment_Mono({
subsets: ['latin'],
variable: '--font-mono',
weight: ['400'],
})

export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
title: 'Read it Later',
description: 'Bookmark your favorite articles and read them later with AI.',
}

export const viewport: Viewport = {
Expand Down
24 changes: 14 additions & 10 deletions apps/ui/src/components/DialogLinkCreate/DialogLinkCreate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ import {
import { Input } from '@/components/ui/input'
import { createUrl } from '@/actions/create-url'
import { zodResolver } from '@hookform/resolvers/zod'
import { redirect } from 'next/navigation'
import { useRouter } from 'next/navigation'
import { useForm } from 'react-hook-form'
import { z } from 'zod'
import { useState } from 'react'

const linkCreateSchema = z.object({
url: z.preprocess(
Expand All @@ -32,6 +33,9 @@ const linkCreateSchema = z.object({
})

export const DialogLinkCreate = () => {
const router = useRouter()
const [isSubmitting, setIsSubmitting] = useState(false)

const form = useForm<z.infer<typeof linkCreateSchema>>({
resolver: zodResolver(linkCreateSchema),
defaultValues: {
Expand All @@ -40,26 +44,24 @@ export const DialogLinkCreate = () => {
})

const submit = async (values: z.infer<typeof linkCreateSchema>) => {
setIsSubmitting(true)
try {
await createUrl(values)
router.push('/bookmarks')
router.refresh()
} catch (_) {
console.error('Failed to create URL')
return
} finally {
close()
// const router = useRouter()

redirect('/bookmarks')
form.reset()
setIsSubmitting(false)
}
}

return (
<DialogContent>
<DialogHeader>
<DialogTitle>New Bookmark</DialogTitle>
<DialogDescription>
Add a new bookmark manually. You can also use the bookmarklet.
</DialogDescription>
<DialogDescription>Add a new bookmark manually.</DialogDescription>
</DialogHeader>
<Form {...form}>
<form className="grid gap-4 py-4" onSubmit={form.handleSubmit(submit)}>
Expand All @@ -84,7 +86,9 @@ export const DialogLinkCreate = () => {
<Button variant="link">Close</Button>
</DialogClose>
<DialogClose asChild>
<Button type="submit">Submit URL</Button>
<Button type="submit" disabled={isSubmitting}>
{isSubmitting ? 'Submitting...' : 'Submit URL'}
</Button>
</DialogClose>
</DialogFooter>
</form>
Expand Down
3 changes: 3 additions & 0 deletions apps/ui/src/components/LinkList/LinkList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { SearchIcon } from 'lucide-react'
import { createPaginationQueryString } from '@/lib/utils'
import type { LinkStatus } from '@/components/StatusIcon/StatusIcon'

interface Link {
id: string
title: string
url: string
summary: string
status: LinkStatus
tags: { key: string; label: string }[]
createdAt: string
}
Expand Down Expand Up @@ -66,6 +68,7 @@ export async function LinkList({ links, pagination }: LinkListProps) {
summary={link.summary}
tags={link.tags}
createdAt={link.createdAt}
status={link.status}
/>
))}
</div>
Expand Down
13 changes: 11 additions & 2 deletions apps/ui/src/components/LinkList/LinkListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { StatusIcon, type LinkStatus } from '@/components/StatusIcon/StatusIcon'
import { formatRelative } from 'date-fns'
import Link from 'next/link'
import type { MouseEventHandler } from 'react'
Expand All @@ -9,15 +10,23 @@ interface LinkListItemProps {
title: string
url: string
summary: string
status: LinkStatus
tags?: { key: string; label: string }[]
createdAt: string
}

export const LinkListItem = (props: LinkListItemProps) => {
return (
<Link href={props.href} className="block p-2" prefetch={props.prefetch}>
<h3 className="font-semibold text-lg truncate">{props.title}</h3>
<div className="text-sm text-muted-foreground">{props.url}</div>
<div className="flex flex-row gap-1 items-baseline">
<h3 className="font-semibold text-lg truncate">
{props.title ?? props.url}
</h3>
<StatusIcon status={props.status} />
</div>
<div className="text-sm text-muted-foreground">
{props.title ? props.url : null}
</div>
<div className="text-sm text-foreground">
Added {formatRelative(props.createdAt, new Date())}
</div>
Expand Down
32 changes: 32 additions & 0 deletions apps/ui/src/components/StatusIcon/StatusIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
CircleCheckIcon,
CircleDashedIcon,
CircleDotDashedIcon,
CircleXIcon,
} from 'lucide-react'
import { match } from 'ts-pattern'

export type LinkStatus = 'submitted' | 'processing' | 'completed' | 'error'
export function StatusIcon({ status }: { status: LinkStatus }) {
return match(status)
.with('submitted', () => (
<span className="text-yellow-500">
<CircleDashedIcon className="size-3" />
</span>
))
.with('processing', () => (
<span className="text-yellow-500">
<CircleDotDashedIcon className="size-3" />
</span>
))
.with('completed', () => (
<span className="text-green-500">
<CircleCheckIcon className="size-3" />
</span>
))
.otherwise(() => (
<span className="text-red-500">
<CircleXIcon className="size-3" />
</span>
))
}
1 change: 1 addition & 0 deletions apps/ui/src/components/StatusIcon/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './StatusIcon'
6 changes: 6 additions & 0 deletions apps/ui/src/lib/api/calls/getLinksForUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ export async function getLinksForUser(props: GetLinkProps) {

const response = await client.api.v1.links.$get({
query,
},{
init: {
next: {
revalidate: 100
}
}
})

if (!response.ok) {
Expand Down
12 changes: 12 additions & 0 deletions apps/ui/src/lib/fonts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Fragment_Mono, Instrument_Sans } from 'next/font/google'

export const fontSans = Instrument_Sans({
subsets: ['latin'],
variable: '--font-sans',
})

export const fontMono = Fragment_Mono({
subsets: ['latin'],
variable: '--font-mono',
weight: ['400'],
})
6 changes: 3 additions & 3 deletions apps/ui/src/lib/url.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export function getBaseDomain(url: string): string {
const hostname = new URL(url).hostname
const parts = hostname.split('.')
const hostname = new URL(url).hostname;
const parts = hostname.split(".");

return parts.length > 2 ? parts.slice(-2).join('.') : hostname
return parts.length > 2 ? parts.slice(-2).join(".") : hostname;
}
Binary file modified bun.lockb
Binary file not shown.

0 comments on commit 9484f83

Please sign in to comment.