diff --git a/package-lock.json b/package-lock.json index b12df46..5ed3c9b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@fontsource/roboto": "^5.2.9", "@mui/material": "^7.3.7", "next": "16.1.1", + "pg": "^8.17.0", "react": "19.2.3", "react-dom": "19.2.3" }, @@ -5183,6 +5184,95 @@ "node": ">=8" } }, + "node_modules/pg": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.17.0.tgz", + "integrity": "sha512-SRl6PbO7zqhD5bZ6lVtEFWknVeWv6Eab+PKzowWTEAce5MFiHTcSdi2N9M9m7VYAv1Hc3OOCxSka3hPBYoXHJA==", + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.10.0", + "pg-pool": "^3.11.0", + "pg-protocol": "^1.11.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.3.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", + "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.10.0.tgz", + "integrity": "sha512-ur/eoPKzDx2IjPaYyXS6Y8NSblxM7X64deV2ObV57vhjsWiwLvUD6meukAzogiOsu60GO8m/3Cb6FdJsWNjwXg==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.11.0.tgz", + "integrity": "sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.11.0.tgz", + "integrity": "sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -5240,6 +5330,45 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5748,6 +5877,15 @@ "node": ">=0.10.0" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/stable-hash": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", @@ -6393,6 +6531,15 @@ "node": ">=0.10.0" } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/package.json b/package.json index 4890eb3..46570e0 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@fontsource/roboto": "^5.2.9", "@mui/material": "^7.3.7", "next": "16.1.1", + "pg": "^8.17.0", "react": "19.2.3", "react-dom": "19.2.3" }, diff --git a/public/hero-background.mp4 b/public/hero-background.mp4 new file mode 100644 index 0000000..3674ce6 Binary files /dev/null and b/public/hero-background.mp4 differ diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 42fc323..0545b1d 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,20 +1,10 @@ import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "Tartarus", + description: "you shouldn't be here" }; export default function RootLayout({ @@ -24,7 +14,7 @@ export default function RootLayout({ }>) { return ( - + {children} diff --git a/src/app/page.module.css b/src/app/page.module.css deleted file mode 100644 index 59dea42..0000000 --- a/src/app/page.module.css +++ /dev/null @@ -1,141 +0,0 @@ -.page { - --background: #fafafa; - --foreground: #fff; - - --text-primary: #000; - --text-secondary: #666; - - --button-primary-hover: #383838; - --button-secondary-hover: #f2f2f2; - --button-secondary-border: #ebebeb; - - display: flex; - min-height: 100vh; - align-items: center; - justify-content: center; - font-family: var(--font-geist-sans); - background-color: var(--background); -} - -.main { - display: flex; - min-height: 100vh; - width: 100%; - max-width: 800px; - flex-direction: column; - align-items: flex-start; - justify-content: space-between; - background-color: var(--foreground); - padding: 120px 60px; -} - -.intro { - display: flex; - flex-direction: column; - align-items: flex-start; - text-align: left; - gap: 24px; -} - -.intro h1 { - max-width: 320px; - font-size: 40px; - font-weight: 600; - line-height: 48px; - letter-spacing: -2.4px; - text-wrap: balance; - color: var(--text-primary); -} - -.intro p { - max-width: 440px; - font-size: 18px; - line-height: 32px; - text-wrap: balance; - color: var(--text-secondary); -} - -.intro a { - font-weight: 500; - color: var(--text-primary); -} - -.ctas { - display: flex; - flex-direction: row; - width: 100%; - max-width: 440px; - gap: 16px; - font-size: 14px; -} - -.ctas a { - display: flex; - justify-content: center; - align-items: center; - height: 40px; - padding: 0 16px; - border-radius: 128px; - border: 1px solid transparent; - transition: 0.2s; - cursor: pointer; - width: fit-content; - font-weight: 500; -} - -a.primary { - background: var(--text-primary); - color: var(--background); - gap: 8px; -} - -a.secondary { - border-color: var(--button-secondary-border); -} - -/* Enable hover only on non-touch devices */ -@media (hover: hover) and (pointer: fine) { - a.primary:hover { - background: var(--button-primary-hover); - border-color: transparent; - } - - a.secondary:hover { - background: var(--button-secondary-hover); - border-color: transparent; - } -} - -@media (max-width: 600px) { - .main { - padding: 48px 24px; - } - - .intro { - gap: 16px; - } - - .intro h1 { - font-size: 32px; - line-height: 40px; - letter-spacing: -1.92px; - } -} - -@media (prefers-color-scheme: dark) { - .logo { - filter: invert(); - } - - .page { - --background: #000; - --foreground: #000; - - --text-primary: #ededed; - --text-secondary: #999; - - --button-primary-hover: #ccc; - --button-secondary-hover: #1a1a1a; - --button-secondary-border: #1a1a1a; - } -} diff --git a/src/app/page.tsx b/src/app/page.tsx index 7b947a2..897025c 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,66 +1,136 @@ -import Image from "next/image"; -import styles from "./page.module.css"; +"use client"; + +import * as React from "react"; +import { useRouter } from "next/navigation"; +import { + Box, + Card, + Container, + List, + ListItemButton, + ListItemText, + Stack, + Typography, +} from "@mui/material"; + +const navItems = [ + { label: "Products", path: "/products" }, + { label: "Pricing", path: "/pricing" }, + { label: "About", path: "/about" }, + { label: "Contact", path: "/contact" }, +]; export default function Home() { + const router = useRouter(); + return ( -
-
- Next.js logo -
-

To get started, edit the page.tsx file.

-

- Looking for a starting point or more instructions? Head over to{" "} - + + + + + + + + + + Greetings + + + Choose a section to continue. + + + + - Templates - {" "} - or the{" "} - - Learning - {" "} - center. -

-
-
- - Vercel logomark - Deploy Now - - - Documentation - -
-
-
+ {navItems.map((item) => ( + router.push(item.path)} + sx={{ + borderRadius: 2, + border: "1px solid rgba(255,255,255,0.16)", + backgroundColor: "rgba(0,0,0,0.18)", + transition: "transform 120ms ease, background-color 120ms ease", + "&:hover": { + backgroundColor: "rgba(255,255,255,0.12)", + transform: "translateX(-4px)", + }, + "&:active": { + transform: "translateX(-2px) scale(0.99)", + }, + }} + > + + + ))} + + + + + ); } + diff --git a/src/paths.ts b/src/paths.ts new file mode 100644 index 0000000..d5a71c8 --- /dev/null +++ b/src/paths.ts @@ -0,0 +1,11 @@ +export const paths = { + home: '/', + products: { + home: '/demo', + }, + auth: { + signIn: '/auth/sign-in', + resetPassword: '/auth/reset-password', + setPassword: '/auth/set-password', + }, +} as const; diff --git a/src/sql/products.sql b/src/sql/products.sql new file mode 100644 index 0000000..7a14459 --- /dev/null +++ b/src/sql/products.sql @@ -0,0 +1,13 @@ +DROP TABLE products IF EXISTS; +DROP product_record_num_sequence IF EXISTS; +DROP product_product_id_sequence IF EXISTS; + +CREATE product_record_num_sequence CASCADE; +CREATE product_product_id_sequence CASCADE; + +CREATE TABLE products( + record_num INTEGER PRIMARY KEY DEFAULT nextval('product_record_num_sequence'), + product_id INTEGER PRIMARY KEY DEFAULT, + name VARCHAR(20), + exp_date DATE NOT NULL, +);