Compare commits

..

No commits in common. "4ae9625653f111a2c0dcc380dfd4c154487180be" and "89e338a0ac930464f13b288f4425e4947cb02d0d" have entirely different histories.

8 changed files with 152 additions and 1175 deletions

955
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -24,14 +24,11 @@
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-toast": "^1.1.5",
"@tanstack/react-table": "^8.17.3",
"@types/bcrypt": "^5.0.2",
"bcrypt": "^5.1.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"date-fns": "^3.6.0",
"lucide-react": "^0.394.0",
"next": "14.2.3",
"next-auth": "^4.24.7",
"next-themes": "^0.3.0",
"react": "^18",
"react-day-picker": "^8.10.1",
@ -40,11 +37,10 @@
"recharts": "^2.12.7",
"tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7",
"ts-node": "^10.9.2",
"zod": "^3.23.8"
},
"devDependencies": {
"@types/node": "^20.16.5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.4.19",

Binary file not shown.

View File

@ -1,6 +0,0 @@
-- CreateTable
CREATE TABLE "User" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"email" TEXT NOT NULL,
"password" TEXT NOT NULL
);

View File

@ -10,12 +10,6 @@ datasource db {
url = "file:./dev.db"
}
model User {
id Int @id @default(autoincrement())
email String
password String
}
model Story {
id Int @id @default(autoincrement())
word_count Int

View File

@ -1,24 +0,0 @@
import prisma from "app/lib/db";
import bcrypt from 'bcrypt';
export type User = {
id?: number,
email: string,
password: string,
}
export default async function authenticate(clientUser: User) {
const dbUser: User = await prisma.user.findFirst({ where: { email: clientUser.email } })
if (!dbUser) return "user doesn't exist"
const passwordMatches = await
bcrypt.compare(clientUser.password, dbUser.password)
if (!passwordMatches) return "password doesn't match"
return "password matches!"
}
let res = await authenticate({ email: "nobody", password: "nothing" })
console.log("nonexistent user: " + res)
res = await authenticate({ email: "demo@demo.demo", password: "nothing" })
console.log("existent user, bad password: " + res)
res = await authenticate({ email: "demo@demo.demo", password: "password" })
console.log("existent user, good password: " + res)

View File

@ -1,68 +0,0 @@
"use client"
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { toast } from "@/components/ui/use-toast";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
const formSchema = z.object({
email: z.string().email(),
password: z.string().min(6)
})
export default function LoginForm() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
})
function onSubmit(values: z.infer<typeof formSchema>) {
toast({
title: "You submitted:",
description: JSON.stringify(values)
})
}
function onErrors(errors) {
toast({
title: "WHOOPS",
description: JSON.stringify(errors)
})
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit, onErrors)}>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email Address</FormLabel>
<FormControl>
<Input placeholder="email goes here" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
></FormField>
<FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>Password</FormLabel>
<FormControl>
<Input placeholder="password goes here" type="password"{...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
></FormField>
<Button type="submit">SUBMIT</Button>
</form>
</Form>
)
}

View File

@ -634,10 +634,6 @@ body {
border-width: 0;
}
.pointer-events-none {
pointer-events: none;
}
.pointer-events-auto {
pointer-events: auto;
}
@ -670,10 +666,6 @@ body {
left: 0.5rem;
}
.left-3 {
left: 0.75rem;
}
.left-\[50\%\] {
left: 50%;
}
@ -694,10 +686,6 @@ body {
top: 0px;
}
.top-1\/2 {
top: 50%;
}
.top-2 {
top: 0.5rem;
}
@ -752,10 +740,6 @@ body {
margin-bottom: 1.5rem;
}
.mb-3 {
margin-bottom: 0.75rem;
}
.mb-4 {
margin-bottom: 1rem;
}
@ -780,10 +764,6 @@ body {
margin-top: 1rem;
}
.mt-5 {
margin-top: 1.25rem;
}
.mt-6 {
margin-top: 1.5rem;
}
@ -792,10 +772,6 @@ body {
margin-top: auto;
}
.block {
display: block;
}
.flex {
display: flex;
}
@ -816,10 +792,6 @@ body {
display: grid;
}
.hidden {
display: none;
}
.size-full {
width: 100%;
height: 100%;
@ -841,10 +813,6 @@ body {
height: 0.5rem;
}
.h-20 {
height: 5rem;
}
.h-24 {
height: 6rem;
}
@ -885,14 +853,6 @@ body {
height: 1.2rem;
}
.h-\[18px\] {
height: 18px;
}
.h-\[48px\] {
height: 48px;
}
.h-\[var\(--radix-select-trigger-height\)\] {
height: var(--radix-select-trigger-height);
}
@ -946,10 +906,6 @@ body {
width: 0.875rem;
}
.w-32 {
width: 8rem;
}
.w-4 {
width: 1rem;
}
@ -958,18 +914,10 @@ body {
width: 10rem;
}
.w-5 {
width: 1.25rem;
}
.w-5\/6 {
width: 83.333333%;
}
.w-6 {
width: 1.5rem;
}
.w-7 {
width: 1.75rem;
}
@ -986,10 +934,6 @@ body {
width: 1.2rem;
}
.w-\[18px\] {
width: 18px;
}
.w-\[240px\] {
width: 240px;
}
@ -1028,10 +972,6 @@ body {
min-width: fit-content;
}
.max-w-\[400px\] {
max-width: 400px;
}
.max-w-full {
max-width: 100%;
}
@ -1048,22 +988,10 @@ body {
max-width: 20rem;
}
.max-w-6xl {
max-width: 72rem;
}
.flex-1 {
flex: 1 1 0%;
}
.shrink-0 {
flex-shrink: 0;
}
.grow {
flex-grow: 1;
}
.caption-bottom {
caption-side: bottom;
}
@ -1072,11 +1000,6 @@ body {
border-collapse: collapse;
}
.-translate-y-1\/2 {
--tw-translate-y: -50%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-x-\[-50\%\] {
--tw-translate-x: -50%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
@ -1153,10 +1076,6 @@ body {
align-items: flex-start;
}
.items-end {
align-items: flex-end;
}
.items-center {
align-items: center;
}
@ -1189,10 +1108,6 @@ body {
gap: 1rem;
}
.gap-12 {
gap: 3rem;
}
.gap-x-16 {
-moz-column-gap: 4rem;
column-gap: 4rem;
@ -1254,18 +1169,6 @@ body {
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
}
.space-y-2\.5 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(0.625rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0.625rem * var(--tw-space-y-reverse));
}
.space-y-3 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
}
.space-y-4 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
@ -1294,18 +1197,10 @@ body {
white-space: nowrap;
}
.text-balance {
text-wrap: balance;
}
.rounded-full {
border-radius: 9999px;
}
.rounded-lg {
border-radius: var(--radius);
}
.rounded-md {
border-radius: calc(var(--radius) - 2px);
}
@ -1348,11 +1243,6 @@ body {
border-color: hsl(var(--destructive));
}
.border-gray-200 {
--tw-border-opacity: 1;
border-color: rgb(229 231 235 / var(--tw-border-opacity));
}
.border-input {
border-color: hsl(var(--input));
}
@ -1377,11 +1267,6 @@ body {
background-color: rgb(0 0 0 / 0.8);
}
.bg-blue-500 {
--tw-bg-opacity: 1;
background-color: rgb(59 130 246 / var(--tw-bg-opacity));
}
.bg-border {
background-color: hsl(var(--border));
}
@ -1394,11 +1279,6 @@ body {
background-color: hsl(var(--destructive));
}
.bg-gray-50 {
--tw-bg-opacity: 1;
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
}
.bg-input {
background-color: hsl(var(--input));
}
@ -1484,11 +1364,6 @@ body {
padding-right: 1rem;
}
.px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.px-8 {
padding-left: 2rem;
padding-right: 2rem;
@ -1524,24 +1399,6 @@ body {
padding-bottom: 1rem;
}
.py-\[9px\] {
padding-top: 9px;
padding-bottom: 9px;
}
.py-12 {
padding-top: 3rem;
padding-bottom: 3rem;
}
.pb-4 {
padding-bottom: 1rem;
}
.pl-10 {
padding-left: 2.5rem;
}
.pl-3 {
padding-left: 0.75rem;
}
@ -1570,10 +1427,6 @@ body {
padding-top: 0.25rem;
}
.pt-8 {
padding-top: 2rem;
}
.text-left {
text-align: left;
}
@ -1586,11 +1439,6 @@ body {
vertical-align: middle;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-3xl {
font-size: 1.875rem;
line-height: 2.25rem;
@ -1690,21 +1538,6 @@ body {
color: hsl(var(--foreground) / 0.5);
}
.text-gray-50 {
--tw-text-opacity: 1;
color: rgb(249 250 251 / var(--tw-text-opacity));
}
.text-gray-500 {
--tw-text-opacity: 1;
color: rgb(107 114 128 / var(--tw-text-opacity));
}
.text-gray-900 {
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.text-muted-foreground {
color: hsl(var(--muted-foreground));
}
@ -1721,11 +1554,6 @@ body {
color: hsl(var(--primary-foreground));
}
.text-red-500 {
--tw-text-opacity: 1;
color: rgb(239 68 68 / var(--tw-text-opacity));
}
.text-secondary-foreground {
color: hsl(var(--secondary-foreground));
}
@ -1789,10 +1617,6 @@ body {
outline-style: solid;
}
.outline-2 {
outline-width: 2px;
}
.ring-offset-background {
--tw-ring-offset-color: hsl(var(--background));
}
@ -2070,16 +1894,6 @@ body {
font-weight: 500;
}
.placeholder\:text-gray-500::-moz-placeholder {
--tw-text-opacity: 1;
color: rgb(107 114 128 / var(--tw-text-opacity));
}
.placeholder\:text-gray-500::placeholder {
--tw-text-opacity: 1;
color: rgb(107 114 128 / var(--tw-text-opacity));
}
.placeholder\:text-muted-foreground::-moz-placeholder {
color: hsl(var(--muted-foreground));
}
@ -2128,20 +1942,10 @@ body {
background-color: hsl(var(--secondary) / 0.8);
}
.hover\:bg-sky-100:hover {
--tw-bg-opacity: 1;
background-color: rgb(224 242 254 / var(--tw-bg-opacity));
}
.hover\:text-accent-foreground:hover {
color: hsl(var(--accent-foreground));
}
.hover\:text-blue-600:hover {
--tw-text-opacity: 1;
color: rgb(37 99 235 / var(--tw-text-opacity));
}
.hover\:text-foreground:hover {
color: hsl(var(--foreground));
}
@ -2271,11 +2075,6 @@ body {
--tw-ring-offset-color: #dc2626;
}
.peer:focus ~ .peer-focus\:text-gray-900 {
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
}
.peer:disabled ~ .peer-disabled\:cursor-not-allowed {
cursor: not-allowed;
}
@ -2548,70 +2347,9 @@ body {
}
@media (min-width: 768px) {
.md\:-mt-32 {
margin-top: -8rem;
}
.md\:block {
display: block;
}
.md\:h-36 {
height: 9rem;
}
.md\:h-screen {
height: 100vh;
}
.md\:w-36 {
width: 9rem;
}
.md\:max-w-\[420px\] {
max-width: 420px;
}
.md\:flex-none {
flex: none;
}
.md\:justify-start {
justify-content: flex-start;
}
.md\:p-2 {
padding: 0.5rem;
}
.md\:px-3 {
padding-left: 0.75rem;
padding-right: 0.75rem;
}
}
@media (min-width: 1024px) {
.lg\:grid {
display: grid;
}
.lg\:min-h-\[100vh\] {
min-height: 100vh;
}
.lg\:w-96 {
width: 24rem;
}
.lg\:grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (min-width: 1280px) {
.xl\:min-h-\[100vh\] {
min-height: 100vh;
}
}
.\[\&\:has\(\[aria-selected\]\)\]\:bg-accent:has([aria-selected]) {