Merge branch 'auth-third-attempt-JWT' of 192.168.0.184:andrzej/subman-nextjs into auth-third-attempt-JWT

This commit is contained in:
andrzej 2024-09-23 17:36:36 +02:00
commit 2a2a994f90
13 changed files with 159 additions and 60 deletions

99
package-lock.json generated
View File

@ -29,7 +29,7 @@
"date-fns": "^3.6.0",
"jose": "^5.8.0",
"lucide-react": "^0.394.0",
"next": "14.2.3",
"next": "^14.2.13",
"next-themes": "^0.3.0",
"react": "^18",
"react-day-picker": "^8.10.1",
@ -226,17 +226,19 @@
}
},
"node_modules/@next/env": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.3.tgz",
"integrity": "sha512-W7fd7IbkfmeeY2gXrzJYDx8D2lWKbVoTIj1o1ScPHNzvp30s1AuoEFSdr39bC5sjxJaxTtq3OTCZboNp0lNWHA=="
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.13.tgz",
"integrity": "sha512-s3lh6K8cbW1h5Nga7NNeXrbe0+2jIIYK9YaA9T7IufDWnZpozdFUp6Hf0d5rNWUKu4fEuSX2rCKlGjCrtylfDw==",
"license": "MIT"
},
"node_modules/@next/swc-darwin-arm64": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.3.tgz",
"integrity": "sha512-3pEYo/RaGqPP0YzwnlmPN2puaF2WMLM3apt5jLW2fFdXD9+pqcoTzRk+iZsf8ta7+quAe4Q6Ms0nR0SFGFdS1A==",
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.13.tgz",
"integrity": "sha512-IkAmQEa2Htq+wHACBxOsslt+jMoV3msvxCn0WFSfJSkv/scy+i/EukBKNad36grRxywaXUYJc9mxEGkeIs8Bzg==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
@ -246,12 +248,13 @@
}
},
"node_modules/@next/swc-darwin-x64": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.3.tgz",
"integrity": "sha512-6adp7waE6P1TYFSXpY366xwsOnEXM+y1kgRpjSRVI2CBDOcbRjsJ67Z6EgKIqWIue52d2q/Mx8g9MszARj8IEA==",
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.13.tgz",
"integrity": "sha512-Dv1RBGs2TTjkwEnFMVL5XIfJEavnLqqwYSD6LXgTPdEy/u6FlSrLBSSfe1pcfqhFEXRAgVL3Wpjibe5wXJzWog==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
@ -261,12 +264,13 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.3.tgz",
"integrity": "sha512-cuzCE/1G0ZSnTAHJPUT1rPgQx1w5tzSX7POXSLaS7w2nIUJUD+e25QoXD/hMfxbsT9rslEXugWypJMILBj/QsA==",
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.13.tgz",
"integrity": "sha512-yB1tYEFFqo4ZNWkwrJultbsw7NPAAxlPXURXioRl9SdW6aIefOLS+0TEsKrWBtbJ9moTDgU3HRILL6QBQnMevg==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -276,12 +280,13 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.3.tgz",
"integrity": "sha512-0D4/oMM2Y9Ta3nGuCcQN8jjJjmDPYpHX9OJzqk42NZGJocU2MqhBq5tWkJrUQOQY9N+In9xOdymzapM09GeiZw==",
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.13.tgz",
"integrity": "sha512-v5jZ/FV/eHGoWhMKYrsAweQ7CWb8xsWGM/8m1mwwZQ/sutJjoFaXchwK4pX8NqwImILEvQmZWyb8pPTcP7htWg==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -291,12 +296,13 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.3.tgz",
"integrity": "sha512-ENPiNnBNDInBLyUU5ii8PMQh+4XLr4pG51tOp6aJ9xqFQ2iRI6IH0Ds2yJkAzNV1CfyagcyzPfROMViS2wOZ9w==",
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.13.tgz",
"integrity": "sha512-aVc7m4YL7ViiRv7SOXK3RplXzOEe/qQzRA5R2vpXboHABs3w8vtFslGTz+5tKiQzWUmTmBNVW0UQdhkKRORmGA==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -306,12 +312,13 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.3.tgz",
"integrity": "sha512-BTAbq0LnCbF5MtoM7I/9UeUu/8ZBY0i8SFjUMCbPDOLv+un67e2JgyN4pmgfXBwy/I+RHu8q+k+MCkDN6P9ViQ==",
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.13.tgz",
"integrity": "sha512-4wWY7/OsSaJOOKvMsu1Teylku7vKyTuocvDLTZQq0TYv9OjiYYWt63PiE1nTuZnqQ4RPvME7Xai+9enoiN0Wrg==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
@ -321,12 +328,13 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.3.tgz",
"integrity": "sha512-AEHIw/dhAMLNFJFJIJIyOFDzrzI5bAjI9J26gbO5xhAKHYTZ9Or04BesFPXiAYXDNdrwTP2dQceYA4dL1geu8A==",
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.13.tgz",
"integrity": "sha512-uP1XkqCqV2NVH9+g2sC7qIw+w2tRbcMiXFEbMihkQ8B1+V6m28sshBwAB0SDmOe0u44ne1vFU66+gx/28RsBVQ==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
@ -336,12 +344,13 @@
}
},
"node_modules/@next/swc-win32-ia32-msvc": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.3.tgz",
"integrity": "sha512-vga40n1q6aYb0CLrM+eEmisfKCR45ixQYXuBXxOOmmoV8sYST9k7E3US32FsY+CkkF7NtzdcebiFT4CHuMSyZw==",
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.13.tgz",
"integrity": "sha512-V26ezyjPqQpDBV4lcWIh8B/QICQ4v+M5Bo9ykLN+sqeKKBxJVDpEc6biDVyluTXTC40f5IqCU0ttth7Es2ZuMw==",
"cpu": [
"ia32"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
@ -351,12 +360,13 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.3.tgz",
"integrity": "sha512-Q1/zm43RWynxrO7lW4ehciQVj+5ePBhOK+/K2P7pLFX3JaJ/IZVC69SHidrmZSOkqz7ECIOhhy7XhAFG4JYyHA==",
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.13.tgz",
"integrity": "sha512-WwzOEAFBGhlDHE5Z73mNU8CO8mqMNLqaG+AO9ETmzdCQlJhVtWZnOl2+rqgVQS+YHunjOWptdFmNfbpwcUuEsw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
@ -6557,11 +6567,12 @@
"peer": true
},
"node_modules/next": {
"version": "14.2.3",
"resolved": "https://registry.npmjs.org/next/-/next-14.2.3.tgz",
"integrity": "sha512-dowFkFTR8v79NPJO4QsBUtxv0g9BrS/phluVpMAt2ku7H+cbcBJlopXjkWlwxrk/xGqMemr7JkGPGemPrLLX7A==",
"version": "14.2.13",
"resolved": "https://registry.npmjs.org/next/-/next-14.2.13.tgz",
"integrity": "sha512-BseY9YNw8QJSwLYD7hlZzl6QVDoSFHL/URN5K64kVEVpCsSOWeyjbIGK+dZUaRViHTaMQX8aqmnn0PHBbGZezg==",
"license": "MIT",
"dependencies": {
"@next/env": "14.2.3",
"@next/env": "14.2.13",
"@swc/helpers": "0.5.5",
"busboy": "1.6.0",
"caniuse-lite": "^1.0.30001579",
@ -6576,15 +6587,15 @@
"node": ">=18.17.0"
},
"optionalDependencies": {
"@next/swc-darwin-arm64": "14.2.3",
"@next/swc-darwin-x64": "14.2.3",
"@next/swc-linux-arm64-gnu": "14.2.3",
"@next/swc-linux-arm64-musl": "14.2.3",
"@next/swc-linux-x64-gnu": "14.2.3",
"@next/swc-linux-x64-musl": "14.2.3",
"@next/swc-win32-arm64-msvc": "14.2.3",
"@next/swc-win32-ia32-msvc": "14.2.3",
"@next/swc-win32-x64-msvc": "14.2.3"
"@next/swc-darwin-arm64": "14.2.13",
"@next/swc-darwin-x64": "14.2.13",
"@next/swc-linux-arm64-gnu": "14.2.13",
"@next/swc-linux-arm64-musl": "14.2.13",
"@next/swc-linux-x64-gnu": "14.2.13",
"@next/swc-linux-x64-musl": "14.2.13",
"@next/swc-win32-arm64-msvc": "14.2.13",
"@next/swc-win32-ia32-msvc": "14.2.13",
"@next/swc-win32-x64-msvc": "14.2.13"
},
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",

View File

@ -32,7 +32,7 @@
"date-fns": "^3.6.0",
"jose": "^5.8.0",
"lucide-react": "^0.394.0",
"next": "14.2.3",
"next": "^14.2.13",
"next-themes": "^0.3.0",
"react": "^18",
"react-day-picker": "^8.10.1",

View File

@ -73,7 +73,7 @@ const TableHead = React.forwardRef<
<th
ref={ref}
className={cn(
"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
"h-12 md:px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
className
)}
{...props}
@ -87,7 +87,7 @@ const TableCell = React.forwardRef<
>(({ className, ...props }, ref) => (
<td
ref={ref}
className={cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
className={cn("p-2 md:p-4 align-middle [&:has([role=checkbox])]:pr-0", className)}
{...props}
/>
))

View File

@ -95,6 +95,7 @@ export async function login(userLogin: LoginSchema) {
if (!passwordIsValid) throw new Error("password is not valid")
return { email: userLogin.email }
} catch (error) {
console.error("WHOOPS", error)
throw new Error('login failed')
}
}

View File

@ -37,8 +37,8 @@ export default function RootLayout({
<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>
</header>
<Navlinks className="mt-6" />
<footer className="mt-auto flex justify-center"><ModeToggle /><LogoutButton />
<Navlinks className="md:mt-6" />
<footer className="my-auto md:mt-auto flex justify-center"><ModeToggle /><LogoutButton />
</footer>
</div>
<div className="flex justify-center w-full">

View File

@ -1,7 +1,7 @@
"use client"
import { ColumnDef, createColumnHelper } from "@tanstack/react-table"
import { StoryWithGenres } from "./page"
import { ArrowUpDown } from "lucide-react"
import { ArrowUpDown, BookType, Drama, Tally5 } from "lucide-react"
import { Button } from "@/components/ui/button"
import GenreBadges from "app/ui/genreBadges"
import { selectCol } from "app/ui/tables/selectColumn"
@ -19,9 +19,13 @@ export const columns: ColumnDef<StoryWithGenres>[] = [
return (
<Button
variant="ghost"
className="px-1"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
Title
<span className="hidden sm:block">
Title
</span>
<span className="display-block sm:hidden"><BookType /></span>
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
)
@ -36,9 +40,15 @@ export const columns: ColumnDef<StoryWithGenres>[] = [
return (
<Button
variant="ghost"
className="px-1"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
Word Count
<span className="hidden sm:block">
Word Count
</span>
<span className="sm:hidden">
<Tally5 />
</span>
<ArrowUpDown className="ml-2 h-4 w-4" />
</Button>
)
@ -51,6 +61,12 @@ export const columns: ColumnDef<StoryWithGenres>[] = [
}
},
columnHelper.accessor("genres", {
header: () => (
<div className="w-fit mx-auto">
<span className="hidden sm:block">Genres</span>
<span className="sm:hidden"><Drama /></span>
</div>
),
cell: GenrePickerInputCell,
filterFn: "arrIncludes",
meta: {}

View File

@ -5,6 +5,7 @@ import { Button } from "@/components/ui/button";
import { ComponentProps } from "react";
import { Genre } from "@prisma/client";
import StoryForm from "app/ui/forms/story";
import { Plus } from "lucide-react";
export default function CreateStoryDialog({ genres }: ComponentProps<"div"> & { genres: Genre[] }) {
@ -12,7 +13,10 @@ export default function CreateStoryDialog({ genres }: ComponentProps<"div"> & {
return (
<Dialog>
<DialogTrigger asChild>
<Button>Create new story</Button>
<div>
<Button className="hidden md:display-block">Create new story</Button>
<Button className="display-block md:hidden"><Plus /> </Button>
</div>
</DialogTrigger>
<DialogContent>
<DialogHeader>

View File

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

View File

@ -740,6 +740,11 @@ body {
margin-bottom: 1.5rem;
}
.my-auto {
margin-top: auto;
margin-bottom: auto;
}
.ml-2 {
margin-left: 0.5rem;
}
@ -768,6 +773,10 @@ body {
margin-top: auto;
}
.mr-4 {
margin-right: 1rem;
}
.block {
display: block;
}
@ -963,6 +972,10 @@ body {
width: 100vw;
}
.w-11\/12 {
width: 91.666667%;
}
.min-w-\[8rem\] {
min-width: 8rem;
}
@ -1076,6 +1089,10 @@ body {
flex-wrap: wrap;
}
.content-center {
align-content: center;
}
.items-start {
align-items: flex-start;
}
@ -1100,6 +1117,10 @@ body {
justify-content: space-between;
}
.justify-evenly {
justify-content: space-evenly;
}
.gap-1 {
gap: 0.25rem;
}
@ -1403,6 +1424,11 @@ body {
padding-bottom: 1rem;
}
.px-1 {
padding-left: 0.25rem;
padding-right: 0.25rem;
}
.pl-3 {
padding-left: 0.75rem;
}
@ -2307,6 +2333,14 @@ body {
top: auto;
}
.sm\:block {
display: block;
}
.sm\:hidden {
display: none;
}
.sm\:flex-row {
flex-direction: row;
}
@ -2351,6 +2385,14 @@ body {
}
@media (min-width: 768px) {
.md\:mt-6 {
margin-top: 1.5rem;
}
.md\:mt-auto {
margin-top: auto;
}
.md\:block {
display: block;
}
@ -2359,6 +2401,14 @@ body {
display: none;
}
.md\:w-24 {
width: 6rem;
}
.md\:w-5\/6 {
width: 83.333333%;
}
.md\:max-w-\[420px\] {
max-width: 420px;
}
@ -2370,6 +2420,20 @@ body {
.md\:flex-col {
flex-direction: column;
}
.md\:p-4 {
padding: 1rem;
}
.md\:px-4 {
padding-left: 1rem;
padding-right: 1rem;
}
.md\:py-4 {
padding-top: 1rem;
padding-bottom: 1rem;
}
}
.\[\&\:has\(\[aria-selected\]\)\]\:bg-accent:has([aria-selected]) {

View File

@ -5,7 +5,7 @@ import { Badge } from "@/components/ui/badge";
export default function GenreBadges(props: ComponentProps<"div"> & { genres: Array<Genre> }) {
return (
<div className={"flex flex-wrap gap-1 justify-center " + props.className}>
{props.genres.map((e: Genre) => (<Badge key={e.name}>{e.name}</Badge>))}
{props.genres.map((e: Genre) => (<Badge className="" key={e.name}>{e.name}</Badge>))}
</div>
)
}

View File

@ -122,11 +122,11 @@ export function DataTable<TData, TValue>({
const [filterBy, setFilterBy] = useState(table.getAllColumns()[0])
const [isContextMenuOpen, setIsContextMenuOpen] = useState(false)
return (<>
<div className="flex justify-between items-center py-4">
<div className="flex justify-between items-center py-1 md:py-4">
<div className="flex gap-2">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="ml-auto">
<Button variant="outline" className="hidden md:display-blockml-auto">
Filter by
</Button>
</DropdownMenuTrigger>
@ -251,6 +251,7 @@ export function DataTable<TData, TValue>({
</div>
<div className="rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (

View File

@ -78,7 +78,7 @@ export default function NumberInputCell(props: CellContext<any, any>) {
<FormControl
>
<Input
className="w-24"
className="md:w-24"
type="number"
autoFocus={true}
step={props.column.columnDef.meta?.step}

View File

@ -5,8 +5,9 @@ export const selectCol = {
id: "select",
header: (props: HeaderContext<any, any>) => {
return (
<div className="flex items-center justify-center">
<div className="flex items-start justify-left mx-auto">
<Checkbox
className="mr-4 ml-2"
checked={props.table.getIsAllRowsSelected()}
onCheckedChange={props.table.toggleAllRowsSelected}
aria-label="select/deselect all rows"
@ -18,8 +19,9 @@ export const selectCol = {
cell: (props: CellContext<any, any>) => {
return (
<div className="flex items-center justify-center">
<div className="flex items-start justify-left">
<Checkbox
className="mr-4 ml-2"
checked={props.row.getIsSelected()}
onCheckedChange={props.row.toggleSelected}
aria-label="select/deselect row"