Skip to content

Commit

Permalink
add category
Browse files Browse the repository at this point in the history
  • Loading branch information
karambarakat committed Sep 24, 2023
1 parent cab9697 commit e514697
Show file tree
Hide file tree
Showing 18 changed files with 316 additions and 155 deletions.
44 changes: 24 additions & 20 deletions apps/frontend/src/.storybook/storybook-decorator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import MetaContext from '../routes/_MetaContext'
import { BrowserRouter, Router } from 'react-router-dom'
import Loading from '../routes/_Loading'
import ErrorComponent from '../routes/_Error'
import { QueryClientProvider } from '@tanstack/react-query'
import { QueryClientProvider, useQueryClient } from '@tanstack/react-query'
import { queryClient } from '../api/client'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'

Expand All @@ -32,25 +32,29 @@ export function ProvidersDeprecated({ Story }: { Story: () => JSX.Element }) {
)
}

export function Providers({ Story }: { Story: () => JSX.Element }) {
return (
<>
<QueryClientProvider client={queryClient}>
{
Story() // prettier 😠
}
<ReactQueryDevtools initialIsOpen={false} position="bottom-right" />
</QueryClientProvider>
</>
)
}
// import { } from '@storybook/react'
// import {} from 'SB'

import { Decorator } from '@storybook/react'
export const frontend_decorator: SB.Decorator[] = [
(Story, ctx) => {
return (
<>
<QueryClientProvider client={queryClient}>
{
Story() // prettier 😠
}
<ReactQueryDevtools initialIsOpen={false} position="bottom-right" />
</QueryClientProvider>
</>
)
},

export const frontend_decorator: Decorator = (Story: any, ctx: any) => {
if ((ctx as SB.Story<any>).parameters?.query) {
return Providers({ Story })
}
(Story, ctx) => {
if (ctx.parameters?.query) {
useQueryClient().clear()
return <Story />
}

return <Story />
}
return <Story />
},
]
130 changes: 130 additions & 0 deletions apps/frontend/src/components/CategoryForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { PropsOf } from '@emotion/react'
import Button from 'ui/src/components/Button'
import Dialog from 'ui/src/components/Dialog'
import Divider from 'ui/src/components/Divider'
import SimpleNumberField from 'ui/src/components/forms/SimpleNumberField'
import SimpleTextField from 'ui/src/components/forms/SimpleTextField'
import { Form } from 'ui/src/components/forms/_Form'
import Tooltip from 'ui/src/components/Tooltip'
import 'twin.macro'
import { BsFillCircleFill } from 'react-icons/bs'
import { useQuery } from '@tanstack/react-query'

const colors = [
{ name: 'Grey', color: 'rgb(85, 83, 78)' },
{ name: 'Silver', color: 'rgb(166, 162, 153)' },
{ name: 'Brown', color: 'rgb(159, 107, 83)' },
{ name: 'Gold', color: 'rgb(203, 145, 47)' },
{ name: 'Orange', color: 'rgb(217, 115, 13)' },
{ name: 'Blue', color: 'rgb(51, 126, 169)' },
{ name: 'Purple', color: 'rgb(144, 101, 176)' },
{ name: 'Magenta', color: 'rgb(193, 76, 138)' },
{ name: 'Red', color: 'rgb(212, 76, 71)' },
]

import { AiOutlineLoading3Quarters } from 'react-icons/ai'
import ScrollArea from 'ui/src/components/ScrollArea'
import { WithAsChild } from 'ui/src/utils/WithChildren'
import { Slot } from '@radix-ui/react-slot'
import { Suspense } from 'react'

function IconPicker() {
const { data } = useQuery({
queryFn: async () => {
// @ts-expect-error
const res = await import('./icons')
return res.default.split('\n') as string[]
},
queryKey: ['icons'],
})

if (!data) return <div>error</div>

// if (status === 'loading')
// return (
// <div>
// <AiOutlineLoading3Quarters />
// </div>
// )

return (
<ScrollArea>
<div tw="flex flex-wrap gap-2 mr-3">
{data?.map((value, key) => {
return (
<div tw="min-w-[24px] min-h-[24px] fill-green-700">
<svg
viewBox="0 0 64 64"
key={key}
xmlns="http://www.w3.org/2000/svg"
>
<path d={value} />
</svg>
</div>
)
})}
</div>
</ScrollArea>
)
}

function Hoverable(props: WithAsChild) {
const Component = props.asChild ? Slot : 'div'
return (
<Component
tw="hover:bg-slate-200 active:bg-slate-300 dark:hover:bg-slate-700 dark:active:bg-slate-600"
{...props}
/>
)
}

function ColorPicker() {
return (
<div tw="flex gap-2">
{colors.map(e => {
return (
<Hoverable tw="rounded p-1">
<BsFillCircleFill color={e.color} size={16} />
</Hoverable>
)
})}
<span></span>
</div>
)
}

export default function CategoryForm(
props: Omit<PropsOf<typeof Form>, 'required'>,
) {
return (
<div
aria-label="Add new Entry"
tw="p-4 rounded-md dark:bg-slate-800 dark:border-slate-500 bg-slate-100 border-slate-400 border"
>
<Form required={['title', 'amount']} {...props}>
<div tw="flex flex-col gap-2">
<SimpleTextField tw="text-2xl" name="title" title="Category Title" />
<div tw="h-48 grid gap-2 place-content-center">
<Suspense
fallback={
<div>
<AiOutlineLoading3Quarters />
</div>
}
>
<ColorPicker />
<IconPicker />
</Suspense>
</div>
<SimpleTextField name="note" />
<Divider tw="-mx-4 my-4 dark:bg-slate-500 bg-slate-400" />
<div tw="flex gap-3 justify-end">
<Button variant="filled" size="null" tw="py-1 px-2">
Create New Category
</Button>
</div>
</div>
</Form>
</div>
)
}
32 changes: 32 additions & 0 deletions apps/frontend/src/components/CategoryFrom.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'twin.macro'
import CategoryForm from './CategoryForm'

import { Root, Portal, Content } from '@radix-ui/react-dialog'

export default {
title: 'app/CategoryForm',
parameters: {
layout: 'centered',
},
args: {
action: async values => console.log(values),
},
component: CategoryForm,
render: props => (
<Root open>
<Portal>
<div tw="fixed inset-0 z-50 bg-gray-950/20" />
<Content asChild>
<div tw="z-50 fixed inset-0 h-screen grid place-content-center">
<div tw="w-[400px]">
<CategoryForm {...props} />
</div>
</div>
</Content>
</Portal>
</Root>
),
} satisfies SB.Meta<typeof CategoryForm>

export const Dark = {} satisfies SB.Story<typeof CategoryForm>
export const Light = {} satisfies SB.Story<typeof CategoryForm>
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { Form } from 'ui/src/components/forms/_Form'
import Tooltip from 'ui/src/components/Tooltip'
import 'twin.macro'

export default function AddEntry(
props: Omit<PropsOf<typeof Form>, 'required' | 'values'>,
export default function EntryForm(
props: Omit<PropsOf<typeof Form>, 'required'>,
) {
return (
<div
Expand All @@ -33,7 +33,7 @@ export default function AddEntry(
</div>
<SimpleNumberField name="amount" />
<SimpleTextField name="note" />
<Divider tw="-mx-4 my-4" />
<Divider tw="-mx-4 my-4 dark:bg-slate-500 bg-slate-400" />
<div tw="flex gap-3 justify-end">
<Dialog.Close asChild>
<Button variant="subtle" color="slate" size="null" tw="py-1 px-2">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
import 'twin.macro'
import AddEntry from './AddEntry'
import EntryForm from './EntryForm'

import { Root, Portal, Content } from '@radix-ui/react-dialog'

export default {
title: 'app/AddEntry',
title: 'app/EntryForm',
parameters: {
layout: 'centered',
},
args: {
action: async values => console.log(values),
},
component: AddEntry,
component: EntryForm,
render: props => (
<Root open>
<Portal>
<div tw="fixed inset-0 z-50 bg-gray-950/20" />
<Content asChild>
<div tw="z-50 fixed inset-0 h-screen grid place-content-center">
<AddEntry {...props} />
<EntryForm {...props} />
</div>
</Content>
</Portal>
</Root>
),
} satisfies SB.Meta<typeof AddEntry>
} satisfies SB.Meta<typeof EntryForm>

export const Dark = {} satisfies SB.Story<typeof AddEntry>
export const Light = {} satisfies SB.Story<typeof AddEntry>
export const Dark = {} satisfies SB.Story<typeof EntryForm>
export const Light = {} satisfies SB.Story<typeof EntryForm>
22 changes: 9 additions & 13 deletions apps/frontend/src/components/Icons.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,18 @@ export default {
component: Component,
parameters: {
query: true,
},
} satisfies SB.Meta<typeof Component>

export const Base = {} satisfies SB.Story<typeof Component>
export const Sleep = {
parameters: {
msw: [
rest.get('/icons', async (req, res, ctx) => {
await new Promise(() => {
rest.get('/icons', (req, res, ctx) => {
return new Promise(() => {
/* sleep */
})
return res(ctx.json({ data: 'hello' }))
}),
],
},
decorators: [
(Story: any, ctx: any) => {
useQueryClient().clear()

return <Story />
},
],
} satisfies SB.Meta<typeof Component>

export const Base = {} satisfies SB.Story<typeof Component>
} satisfies SB.Story<typeof Component>
59 changes: 0 additions & 59 deletions apps/frontend/src/components/forms/AddEntry.tsx

This file was deleted.

Loading

0 comments on commit e514697

Please sign in to comment.