render textinputcell only on large screens

This commit is contained in:
andrzej 2024-09-24 12:25:31 +02:00
parent f6c9ac9015
commit a1708002f9
11 changed files with 78 additions and 97 deletions

1
package-lock.json generated
View File

@ -6570,7 +6570,6 @@
"version": "14.2.13", "version": "14.2.13",
"resolved": "https://registry.npmjs.org/next/-/next-14.2.13.tgz", "resolved": "https://registry.npmjs.org/next/-/next-14.2.13.tgz",
"integrity": "sha512-BseY9YNw8QJSwLYD7hlZzl6QVDoSFHL/URN5K64kVEVpCsSOWeyjbIGK+dZUaRViHTaMQX8aqmnn0PHBbGZezg==", "integrity": "sha512-BseY9YNw8QJSwLYD7hlZzl6QVDoSFHL/URN5K64kVEVpCsSOWeyjbIGK+dZUaRViHTaMQX8aqmnn0PHBbGZezg==",
"license": "MIT",
"dependencies": { "dependencies": {
"@next/env": "14.2.13", "@next/env": "14.2.13",
"@swc/helpers": "0.5.5", "@swc/helpers": "0.5.5",

View File

@ -33,7 +33,7 @@ export default function RootLayout({
> >
<div id="layout-container" className="md:p-4 w-screen h-screen mt-2 md:mt-6 flex justify-center"> <div id="layout-container" className="md:p-4 w-screen h-screen mt-2 md:mt-6 flex justify-center">
<div className="w-full md:w-5/6 flex flex-col md:flex-row"> <div className="w-full md:w-5/6 flex flex-col md:flex-row">
<div id="sidebar" className="h-5/6 flex flex-row md:flex-col justify-between"> <header className=""> <div id="sidebar" className=" flex flex-row md:flex-col justify-between"> <header className="">
<h1 className="font-black text-4xl text-primary-foreground bg-primary antialiased w-full p-2 rounded-tl-3xl pl-6 pr-4 hidden md:block">SubMan</h1> <h1 className="font-black text-4xl text-primary-foreground bg-primary antialiased w-full p-2 rounded-tl-3xl pl-6 pr-4 hidden md:block">SubMan</h1>
<p className="mt-2 mx-1 text-sm antialiased w-40 hidden md:block">The self-hosted literary submission tracker.</p> <p className="mt-2 mx-1 text-sm antialiased w-40 hidden md:block">The self-hosted literary submission tracker.</p>
</header> </header>

View File

@ -30,7 +30,12 @@ export const columns: ColumnDef<PubsWithGenres>[] = [
</Button> </Button>
) )
}, },
cell: TextInputCell, cell: cell => (
<>
<p className="block text-xs md:hidden">{cell.getValue()}</p>
<TextInputCell cellContext={cell} className="hidden md:block" />
</>
),
meta: { formSchema: pubSchema } meta: { formSchema: pubSchema }
}, },
@ -42,7 +47,12 @@ export const columns: ColumnDef<PubsWithGenres>[] = [
<span className="block sm:hidden"><SquareArrowOutUpRight /></span> <span className="block sm:hidden"><SquareArrowOutUpRight /></span>
</div> </div>
), ),
cell: TextInputCell, cell: cell => (
<>
<p className="block text-xs md:hidden">{cell.getValue()}</p>
<TextInputCell cellContext={cell} className="hidden md:block" />
</>
),
meta: { formSchema: pubSchema } meta: { formSchema: pubSchema }
}, },
@ -66,7 +76,12 @@ export const columns: ColumnDef<PubsWithGenres>[] = [
<span className="sm:hidden"><Clock /></span> <span className="sm:hidden"><Clock /></span>
</div> </div>
), ),
cell: NumberInputCell, cell: cell => (
<>
<p className="block md:hidden text-center">{cell.getValue()}</p>
<NumberInputCell cellContext={cell} className="hidden md:block" />
</>
),
meta: { meta: {
step: 10, step: 10,
formSchema: pubSchema formSchema: pubSchema

View File

@ -5,6 +5,7 @@ import { ComponentProps } from "react";
import { Genre } from "@prisma/client"; import { Genre } from "@prisma/client";
import { createPub } from "app/lib/create"; import { createPub } from "app/lib/create";
import PubForm from "app/ui/forms/pub"; import PubForm from "app/ui/forms/pub";
import { Plus } from "lucide-react";
export default function CreatePubDialog({ genres }: ComponentProps<"div"> & { genres: Genre[] }) { export default function CreatePubDialog({ genres }: ComponentProps<"div"> & { genres: Genre[] }) {
@ -12,7 +13,10 @@ export default function CreatePubDialog({ genres }: ComponentProps<"div"> & { ge
<Dialog> <Dialog>
<DialogTrigger asChild> <DialogTrigger asChild>
<Button>Create new publication</Button> <Button>
<span className="hidden md:block">Create new publication</span>
<Plus className="block md:hidden" />
</Button>
</DialogTrigger> </DialogTrigger>
<DialogContent> <DialogContent>
<DialogHeader> <DialogHeader>

View File

@ -12,7 +12,7 @@ export default async function Page() {
const genres = await getGenres() const genres = await getGenres()
const pubs = await getPubsWithGenres() const pubs = await getPubsWithGenres()
return ( return (
<div className="container px-0 md:px-4 mx-auto"> <div className="container px-1 md:px-4 mx-auto">
<DataTable data={pubs} columns={columns} tableName="pub" genres={genres}> <DataTable data={pubs} columns={columns} tableName="pub" genres={genres}>
<CreatePubDialog genres={genres} /> <CreatePubDialog genres={genres} />
</DataTable> </DataTable>

View File

@ -29,9 +29,13 @@ export const columns: ColumnDef<StoryWithGenres>[] = [
</Button> </Button>
) )
}, },
cell: TextInputCell, cell: cell => (
<>
<p className="block md:hidden text-xs">{cell.getValue()}</p>
<TextInputCell cellContext={cell} className="hidden md:block" />
</>
),
meta: { formSchema: storySchema } meta: { formSchema: storySchema }
}, },
{ {
accessorKey: "word_count", accessorKey: "word_count",
@ -53,7 +57,12 @@ export const columns: ColumnDef<StoryWithGenres>[] = [
) )
}, },
enableColumnFilter: false, enableColumnFilter: false,
cell: NumberInputCell, cell: cell => (
<>
<p className="block md:hidden text-center text-xs">{cell.getValue()}</p>
<NumberInputCell cellContext={cell} className="hidden md:block" />
</>
),
meta: { meta: {
step: 50, step: 50,
formSchema: storySchema formSchema: storySchema

View File

@ -19,7 +19,7 @@ export default async function Page() {
return ( return (
<div className="container px-0 md:px-4 mx-auto"> <div className="container px-1 md:px-4 mx-auto">
<DataTable columns={columns} data={storiesWithGenres} tableName="story" <DataTable columns={columns} data={storiesWithGenres} tableName="story"
genres={genres} genres={genres}
> >

View File

@ -753,6 +753,10 @@ body {
margin-left: auto; margin-left: auto;
} }
.mr-4 {
margin-right: 1rem;
}
.mt-2 { .mt-2 {
margin-top: 0.5rem; margin-top: 0.5rem;
} }
@ -769,14 +773,6 @@ body {
margin-top: 1.5rem; margin-top: 1.5rem;
} }
.mt-auto {
margin-top: auto;
}
.mr-4 {
margin-right: 1rem;
}
.block { .block {
display: block; display: block;
} }
@ -846,10 +842,6 @@ body {
height: 1.25rem; height: 1.25rem;
} }
.h-5\/6 {
height: 83.333333%;
}
.h-7 { .h-7 {
height: 1.75rem; height: 1.75rem;
} }
@ -927,10 +919,6 @@ body {
width: 10rem; width: 10rem;
} }
.w-5\/6 {
width: 83.333333%;
}
.w-7 { .w-7 {
width: 1.75rem; width: 1.75rem;
} }
@ -972,10 +960,6 @@ body {
width: 100vw; width: 100vw;
} }
.w-11\/12 {
width: 91.666667%;
}
.min-w-\[8rem\] { .min-w-\[8rem\] {
min-width: 8rem; min-width: 8rem;
} }
@ -1089,14 +1073,6 @@ body {
flex-wrap: wrap; flex-wrap: wrap;
} }
.content-center {
align-content: center;
}
.content-between {
align-content: space-between;
}
.items-start { .items-start {
align-items: flex-start; align-items: flex-start;
} }
@ -1109,10 +1085,6 @@ body {
align-items: baseline; align-items: baseline;
} }
.justify-start {
justify-content: flex-start;
}
.justify-end { .justify-end {
justify-content: flex-end; justify-content: flex-end;
} }
@ -1125,14 +1097,6 @@ body {
justify-content: space-between; justify-content: space-between;
} }
.justify-around {
justify-content: space-around;
}
.justify-evenly {
justify-content: space-evenly;
}
.gap-1 { .gap-1 {
gap: 0.25rem; gap: 0.25rem;
} }
@ -1230,10 +1194,6 @@ body {
overflow: hidden; overflow: hidden;
} }
.overflow-clip {
overflow: clip;
}
.whitespace-nowrap { .whitespace-nowrap {
white-space: nowrap; white-space: nowrap;
} }
@ -1353,11 +1313,6 @@ body {
background-color: transparent; background-color: transparent;
} }
.bg-red-800 {
--tw-bg-opacity: 1;
background-color: rgb(153 27 27 / var(--tw-bg-opacity));
}
.fill-current { .fill-current {
fill: currentColor; fill: currentColor;
} }
@ -1390,6 +1345,11 @@ body {
padding: 1.5rem; padding: 1.5rem;
} }
.px-1 {
padding-left: 0.25rem;
padding-right: 0.25rem;
}
.px-2 { .px-2 {
padding-left: 0.5rem; padding-left: 0.5rem;
padding-right: 0.5rem; padding-right: 0.5rem;
@ -1445,16 +1405,6 @@ body {
padding-bottom: 1rem; padding-bottom: 1rem;
} }
.px-1 {
padding-left: 0.25rem;
padding-right: 0.25rem;
}
.px-0 {
padding-left: 0px;
padding-right: 0px;
}
.pl-3 { .pl-3 {
padding-left: 0.75rem; padding-left: 0.75rem;
} }
@ -1745,10 +1695,6 @@ body {
animation-duration: 200ms; animation-duration: 200ms;
} }
.direction-reverse {
animation-direction: reverse;
}
/**/ /**/
/* @layer base { */ /* @layer base { */
@ -2464,6 +2410,11 @@ body {
padding-top: 1rem; padding-top: 1rem;
padding-bottom: 1rem; padding-bottom: 1rem;
} }
.md\:text-sm {
font-size: 0.875rem;
line-height: 1.25rem;
}
} }
.\[\&\:has\(\[aria-selected\]\)\]\:bg-accent:has([aria-selected]) { .\[\&\:has\(\[aria-selected\]\)\]\:bg-accent:has([aria-selected]) {

View File

@ -78,7 +78,7 @@ export default function GenrePickerInputCell(props: CellContext<any, any>) {
render={({ field }) => ( render={({ field }) => (
<FormItem className="w-full max-w-xs flex flex-col"> <FormItem className="w-full max-w-xs flex flex-col">
<PopoverTrigger asChild> <PopoverTrigger asChild>
{value.length > 0 ? <Button variant="ghost" className="h-fit"><GenreBadges genres={value} className="w-full" /></Button> : <Button variant="outline" type="button" className="w-fit m-auto">Add genres</Button> {value.length > 0 ? <Button variant="ghost" className="h-fit p-1"><GenreBadges genres={value} className="w-full" /></Button> : <Button variant="outline" type="button" className="text-xs md:text-sm w-fit m-auto">Add genres</Button>
} }
</PopoverTrigger> </PopoverTrigger>

View File

@ -9,20 +9,20 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { toast } from "@/components/ui/use-toast"; import { toast } from "@/components/ui/use-toast";
import { Form, FormControl, FormField, FormItem, FormMessage } from "@/components/ui/form"; import { Form, FormControl, FormField, FormItem, FormMessage } from "@/components/ui/form";
export default function NumberInputCell(props: CellContext<any, any>) { export default function NumberInputCell({ cellContext, className }: { cellContext: CellContext<any, any>, className: string }) {
const [isActive, setIsActive] = useState(false) const [isActive, setIsActive] = useState(false)
const table = props.table.options.meta.tableName const table = cellContext.table.options.meta.tableName
const id = props.row.original.id const id = cellContext.row.original.id
const column = props.column.id const column = cellContext.column.id
const pathname = props.table.options.meta.pathname const pathname = cellContext.table.options.meta.pathname
const value = props.cell.getValue() const value = cellContext.cell.getValue()
const formSchema = props.column.columnDef.meta.formSchema.pick({ [column]: true }) const formSchema = cellContext.column.columnDef.meta.formSchema.pick({ [column]: true })
const form = useForm<z.infer<typeof formSchema>>({ const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema), resolver: zodResolver(formSchema),
defaultValues: { defaultValues: {
[column]: props.cell.getValue() [column]: cellContext.cell.getValue()
}, },
}) })
@ -55,7 +55,7 @@ export default function NumberInputCell(props: CellContext<any, any>) {
return ( return (
<div <div
onDoubleClick={() => setIsActive(true)} onDoubleClick={() => setIsActive(true)}
className="w-full h-fit flex items-center justify-center" className={className + " w-full h-fit flex items-center justify-center"}
tabIndex={0} tabIndex={0}
onKeyDown={e => { onKeyDown={e => {
if (e.code === "Enter" && !isActive) { if (e.code === "Enter" && !isActive) {
@ -81,7 +81,7 @@ export default function NumberInputCell(props: CellContext<any, any>) {
className="md:w-24" className="md:w-24"
type="number" type="number"
autoFocus={true} autoFocus={true}
step={props.column.columnDef.meta?.step} step={cellContext.column.columnDef.meta?.step}
{...field} {...field}
/> />
</FormControl> </FormControl>
@ -92,7 +92,7 @@ export default function NumberInputCell(props: CellContext<any, any>) {
</form> </form>
</Form> </Form>
: <p>{props.cell.getValue()}</p> : <p>{cellContext.cell.getValue()}</p>
} }
</div > </div >
) )

View File

@ -10,20 +10,23 @@ import { toast } from "@/components/ui/use-toast";
import { Form, FormControl, FormField, FormItem, FormMessage } from "@/components/ui/form"; import { Form, FormControl, FormField, FormItem, FormMessage } from "@/components/ui/form";
import TitleContainer from "app/ui/titleContainer"; import TitleContainer from "app/ui/titleContainer";
export function TextInputCell(props: CellContext<any, any>) { export function TextInputCell({ cellContext, className }: { className: string, cellContext: CellContext<any, any> }) {
const [isActive, setIsActive] = useState(false) const [isActive, setIsActive] = useState(false)
if (cellContext === undefined) {
const table = props.table.options.meta.tableName console.error("CELL CONTEXT UNDEFINED!")
const id = props.row.original.id return false
const column = props.column.id }
const pathname = props.table.options.meta.pathname const table = cellContext.table.options.meta.tableName
const value = props.cell.getValue() const id = cellContext.row.original.id
const formSchema = props.column.columnDef.meta.formSchema.pick({ [column]: true }) const column = cellContext.column.id
const pathname = cellContext.table.options.meta.pathname
const value = cellContext.cell.getValue()
const formSchema = cellContext.column.columnDef.meta.formSchema.pick({ [column]: true })
const form = useForm<z.infer<typeof formSchema>>({ const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema), resolver: zodResolver(formSchema),
defaultValues: { defaultValues: {
[column]: props.cell.getValue() [column]: cellContext.cell.getValue()
}, },
}) })
@ -60,7 +63,7 @@ export function TextInputCell(props: CellContext<any, any>) {
return ( return (
<div <div
onDoubleClick={() => setIsActive(prev => !prev)} onDoubleClick={() => setIsActive(prev => !prev)}
className="w-full h-fit flex items-center justify-left" className={className + " w-full h-fit flex items-center justify-left"}
tabIndex={0} tabIndex={0}
onKeyDown={e => { onKeyDown={e => {
if (e.code === "Enter" && !isActive) { if (e.code === "Enter" && !isActive) {
@ -96,7 +99,7 @@ export function TextInputCell(props: CellContext<any, any>) {
</form> </form>
</Form> </Form>
: <TitleContainer>{props.cell.getValue()}</TitleContainer> : <TitleContainer>{cellContext.cell.getValue()}</TitleContainer>
} }
</div > </div >
) )