Skip to content

Commit

Permalink
pagination component
Browse files Browse the repository at this point in the history
  • Loading branch information
karambarakat committed Oct 17, 2023
1 parent 6e3d97c commit c2d7fcf
Show file tree
Hide file tree
Showing 11 changed files with 421 additions and 45 deletions.
9 changes: 5 additions & 4 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,28 @@
"editor.tabSize": 2,
"cSpell.minWordLength": 5,
"cSpell.words": [
"actix",
"autodocs",
"Barakat",
"chrono",
"cmnd",
"codegen",
"elems",
"hoverable",
"karam",
"karambarakat",
"localstorage",
"luxon",
"openapi",
"signup",
"tabler",
"tailwindcss",
"tanstack",
"TCICD",
"TIMESTAMPTZ",
"Turborepo",
"typecheck",
"viewports",
"actix",
"chrono",
"TIMESTAMPTZ"
"viewports"
],
"eslint.options": {
"extensions": [".js", ".jsx", ".md", ".mdx", ".ts", ".tsx"]
Expand Down
19 changes: 16 additions & 3 deletions apps/frontend/src/api/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ export const create_entry = async (_input: MutationCreateOneEntryArgs) => {

create_entry.shouldInvalidate = (
c: QueryClient,
p: QueryGetAllEntriesArgs['pagination'],
p: null | QueryGetAllEntriesArgs['pagination'],
) => {
c.invalidateQueries(['find_log', p] satisfies queryKeys)
p !== null
? c.invalidateQueries(['find_log', p] satisfies queryKeys)
: c.invalidateQueries(['find_log'])
}

export const update_entry = async ({
Expand All @@ -58,10 +60,21 @@ export const update_entry = async ({
return (await handler(res)).updateOneEntry as Mutation['updateOneEntry']
}

update_entry.shouldInvalidate = (
c: QueryClient,
pagination: QueryGetAllEntriesArgs['pagination'] | null,
id: { id: string },
) => {
pagination !== null
? c.invalidateQueries(['find_log', pagination] satisfies queryKeys)
: c.invalidateQueries(['find_log'])
c.invalidateQueries(['find_one_log', id] satisfies queryKeys)
}

export const delete_entry = async ({ id }: MutationDeleteOneEntryArgs) => {
const res = await gql(
`mutation mutate($id: ID!) {
deleteOneEntry(idMutationDeleteOneEntryArgs: $id)
deleteOneEntry(id: $id)
}`,
{ id },
)
Expand Down
49 changes: 46 additions & 3 deletions apps/frontend/src/components/EntryForm.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import 'twin.macro'
import { EntryInput } from 'types/gql/graphql'
import { EntryInput, Mutation } from 'types/gql/graphql'
import { EntryBody, FormBody, FormFooter, FormRoot } from './_FormUtils'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { create_entry } from '../api/mutations'
import Button from 'ui/src/components/Button'
import Dialog from 'ui/src/components/Dialog'
import { Dispatch, SetStateAction } from 'react'
import { FormInterface } from 'ui/src/components/forms/_Form'

type Input = EntryInput

export function CreateEntryFormPortal() {
export function CreateEntryFormPortal({
setState,
}: {
setState: Dispatch<SetStateAction<boolean>>
}) {
const client = useQueryClient()
const create = useMutation({
mutationFn: create_entry,
onSettled: () => {
create_entry.shouldInvalidate(client, undefined as any) // all pages
create_entry.shouldInvalidate(client, null) // all pages
setState(false)
},
})

Expand Down Expand Up @@ -57,3 +64,39 @@ export function CreateEntryFormPortal() {
</div>
)
}

export function UpdateEntryFormActionPortal({
action,
initialValues,
}: {
initialValues: Input
action: FormInterface<
{ entry: EntryInput },
Mutation['updateOneEntry']
>['action']
}) {
return (
<Dialog.Floating>
<FormRoot
action={async entry => action({ entry })}
values={initialValues}
then={(ctx, vals) => {
vals === true && ctx.setStatus({ success: 'updated successfully' })
}}
asChild
required={['title']}
>
<div aria-label="Update Category">
<FormBody
form={<EntryBody />}
footer={
<FormFooter
Button={props => <Button {...props}>Update</Button>}
/>
}
/>
</div>
</FormRoot>
</Dialog.Floating>
)
}
17 changes: 14 additions & 3 deletions apps/frontend/src/components/EntryFrom.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import 'twin.macro'
import React from 'react'
import { useQueryClient } from '@tanstack/react-query'
import { CategoryFragment, EntryInput } from 'types/gql/graphql'
import { GraphqlMsw, rejectGraphql } from 'ui/src/storybook_utils/msw'
import { EntryInput } from 'types/gql/graphql'
import { GraphqlMsw } from 'ui/src/storybook_utils/msw'
import { EntryBody, FormBody, FormFooter, FormRoot } from './_FormUtils'
import Button from 'ui/src/components/Button'
import { within } from '@storybook/testing-library'
Expand Down Expand Up @@ -85,7 +84,19 @@ export const ThemeIcon = {
args: BasicForm.args,
play: async ({ canvasElement }) => {
const root = within(canvasElement)

const noAnimation = document.createElement('style')
noAnimation.append('* {transition-duration: 0s !important;}')
document.head.appendChild(noAnimation)

const elem1 = await root.findByLabelText('Change Category')
elem1.click()

await new Promise(res =>
setTimeout(() => {
noAnimation.remove()
res(null)
}, 500),
)
},
} satisfies SB.Story<typeof Component>
8 changes: 7 additions & 1 deletion apps/frontend/src/routes/_Auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import SecretField from 'ui/src/components/forms/SecretField'
import EmailField from 'ui/src/components/forms/EmailField'
import { useMutation } from '@tanstack/react-query'
import { login, register } from '../api/mutations'
import { FormInterface, FormBody, Form } from 'ui/src/components/forms/_Form'
import { FormBody, Form } from 'ui/src/components/forms/_Form'

import { Slot } from '@radix-ui/react-slot'
import SubmitButton from 'ui/src/components/forms/SubmitButton'
Expand All @@ -28,6 +28,12 @@ import TextField from 'ui/src/components/forms/TextField'
import { User } from 'types/gql/graphql'

export function Authentication() {
const _token = token.use()

if (_token.getItem()) {
return <Navigate to="/" />
}

return (
<div>
<div
Expand Down
25 changes: 20 additions & 5 deletions apps/frontend/src/routes/_Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,26 @@ export default function Main_Layout_Component() {
</div>
</AppShell.SideBar>
<AppShell.Overlay />
<AppShell.Content>
<ScrollArea tw="h-screen px-4 max-w-[700px] m-auto relative">
<Header tw="pt-4" />
<Outlet />
</ScrollArea>
<AppShell.Content asChild>
<main
css={{
'*, &': {
'--home-padding': '12px',
},
}}
>
<ScrollArea asChild tw="px-4 max-w-[700px] m-auto relative">
<div tw="flex flex-col min-h-screen">
<Header
tw="py-4"
css={{
marginLeft: 'var(--home-padding)',
}}
/>
<Outlet />
</div>
</ScrollArea>
</main>
</AppShell.Content>
</AppShell.Root>
)
Expand Down
17 changes: 9 additions & 8 deletions apps/frontend/src/routes/categories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
CreateCategoryForm,
UpdateCategoryFormActionPortal,
} from '../components/CategoryForm'
import { iconBlue, iconRed } from '../utils/tw'

function Entries() {
const entries = useQuery({
Expand Down Expand Up @@ -79,6 +80,12 @@ function CategoryEntry({

<TextEllipsis tw="flex-1">{category.title}</TextEllipsis>

{(delete_.isLoading || update.isLoading) && (
<span>
<Spinning />
</span>
)}

{hovered && (
<Hoverable asChild>
<button
Expand All @@ -87,7 +94,7 @@ function CategoryEntry({
aria-label="delete category"
tw="cursor-pointer rounded p-1"
>
<AiFillDelete tw="fill-red-800 dark:fill-red-400" />
<AiFillDelete css={iconRed} />
</button>
</Hoverable>
)}
Expand All @@ -111,20 +118,14 @@ function CategoryEntry({
aria-label="edit category"
tw="cursor-pointer rounded p-1"
>
<AiTwotoneEdit tw="fill-blue-800 dark:fill-blue-400" />
<AiTwotoneEdit css={iconBlue} />
</button>
</Hoverable>
)}
</span>
}
></Dialog>

{(delete_.isLoading || update.isLoading) && (
<span>
<Spinning />
</span>
)}

{delete_.error && (
<Tooltip content={'error deleting'}>
<AiFillWarning tw="fill-red-400" />
Expand Down
Loading

0 comments on commit c2d7fcf

Please sign in to comment.