diff --git a/.gitignore b/.gitignore index 5ef6a52..7dcd5b1 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ # production /build +/.history # misc .DS_Store @@ -39,3 +40,5 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +/lilya/* \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b9e89dd..4286a68 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,8 @@ "@radix-ui/react-toggle": "^1.1.3", "@radix-ui/react-toggle-group": "^1.1.3", "@radix-ui/react-tooltip": "^1.2.0", + "@supabase/ssr": "^0.1.0", + "@supabase/supabase-js": "^2.39.3", "@svgr/webpack": "^8.1.0", "@tabler/icons-react": "^3.31.0", "@tanstack/react-table": "^8.21.2", @@ -3309,6 +3311,93 @@ "dev": true, "license": "MIT" }, + "node_modules/@supabase/auth-js": { + "version": "2.69.1", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.69.1.tgz", + "integrity": "sha512-FILtt5WjCNzmReeRLq5wRs3iShwmnWgBvxHfqapC/VoljJl+W8hDAyFmf1NVw3zH+ZjZ05AKxiKxVeb0HNWRMQ==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/functions-js": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.4.4.tgz", + "integrity": "sha512-WL2p6r4AXNGwop7iwvul2BvOtuJ1YQy8EbOd0dhG1oN1q8el/BIRSFCFnWAMM/vJJlHWLi4ad22sKbKr9mvjoA==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/node-fetch": { + "version": "2.6.15", + "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz", + "integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/@supabase/postgrest-js": { + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.19.4.tgz", + "integrity": "sha512-O4soKqKtZIW3olqmbXXbKugUtByD2jPa8kL2m2c1oozAO11uCcGrRhkZL0kVxjBLrXHE0mdSkFsMj7jDSfyNpw==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/realtime-js": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.11.2.tgz", + "integrity": "sha512-u/XeuL2Y0QEhXSoIPZZwR6wMXgB+RQbJzG9VErA3VghVt7uRfSVsjeqd7m5GhX3JR6dM/WRmLbVR8URpDWG4+w==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14", + "@types/phoenix": "^1.5.4", + "@types/ws": "^8.5.10", + "ws": "^8.18.0" + } + }, + "node_modules/@supabase/ssr": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.1.0.tgz", + "integrity": "sha512-bIVrkqjAK5G3KjkIMKYKtAOlCgRRplEWjrlyRyXSOYtgDieiOhk2ZyNAPsEOa1By9OZVxuX5eAW1fitdnuxayw==", + "license": "MIT", + "dependencies": { + "cookie": "^0.5.0", + "ramda": "^0.29.0" + }, + "peerDependencies": { + "@supabase/supabase-js": "^2.33.1" + } + }, + "node_modules/@supabase/storage-js": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.7.1.tgz", + "integrity": "sha512-asYHcyDR1fKqrMpytAS1zjyEfvxuOIp1CIXX7ji4lHHcJKqyk+sLl/Vxgm4sN6u8zvuUtae9e4kDxQP2qrwWBA==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/supabase-js": { + "version": "2.49.4", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.49.4.tgz", + "integrity": "sha512-jUF0uRUmS8BKt37t01qaZ88H9yV1mbGYnqLeuFWLcdV+x1P4fl0yP9DGtaEhFPZcwSom7u16GkLEH9QJZOqOkw==", + "license": "MIT", + "dependencies": { + "@supabase/auth-js": "2.69.1", + "@supabase/functions-js": "2.4.4", + "@supabase/node-fetch": "2.6.15", + "@supabase/postgrest-js": "1.19.4", + "@supabase/realtime-js": "2.11.2", + "@supabase/storage-js": "2.7.1" + } + }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", @@ -5862,12 +5951,17 @@ "version": "20.17.30", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.30.tgz", "integrity": "sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg==", - "dev": true, "license": "MIT", "dependencies": { "undici-types": "~6.19.2" } }, + "node_modules/@types/phoenix": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.6.tgz", + "integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==", + "license": "MIT" + }, "node_modules/@types/react": { "version": "19.1.0", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.0.tgz", @@ -5888,6 +5982,15 @@ "@types/react": "^19.0.0" } }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.29.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.1.tgz", @@ -7926,6 +8029,15 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "license": "MIT" }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/copy-concurrently": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", @@ -13976,6 +14088,16 @@ "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==", "license": "ISC" }, + "node_modules/ramda": { + "version": "0.29.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.1.tgz", + "integrity": "sha512-OfxIeWzd4xdUNxlWhgFazxsA/nl3mS4/jGZI5n00uWOoSSFRhC1b6gl6xvmzUamgmqELraWp0J/qqVlXYPDPyA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ramda" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -15955,6 +16077,12 @@ "optional": true, "peer": true }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, "node_modules/ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", @@ -16160,7 +16288,6 @@ "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "dev": true, "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -16992,6 +17119,12 @@ "node": ">=0.10.0" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, "node_modules/webpack": { "version": "4.47.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz", @@ -17304,6 +17437,16 @@ "node": ">=0.10.0" } }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -17436,6 +17579,27 @@ "license": "ISC", "peer": true }, + "node_modules/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index e9e99a9..a1a7c27 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,8 @@ "@radix-ui/react-toggle": "^1.1.3", "@radix-ui/react-toggle-group": "^1.1.3", "@radix-ui/react-tooltip": "^1.2.0", + "@supabase/ssr": "^0.1.0", + "@supabase/supabase-js": "^2.39.3", "@svgr/webpack": "^8.1.0", "@tabler/icons-react": "^3.31.0", "@tanstack/react-table": "^8.21.2", diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png new file mode 100644 index 0000000..482f6f5 Binary files /dev/null and b/public/android-chrome-192x192.png differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png new file mode 100644 index 0000000..9daf21a Binary files /dev/null and b/public/android-chrome-512x512.png differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000..2d8a83c Binary files /dev/null and b/public/apple-touch-icon.png differ diff --git a/public/assets/email-verification.png b/public/assets/email-verification.png new file mode 100644 index 0000000..14759c3 Binary files /dev/null and b/public/assets/email-verification.png differ diff --git a/public/control/air-conditionair.png b/public/control/air-conditionair.png new file mode 100644 index 0000000..458b4ba Binary files /dev/null and b/public/control/air-conditionair.png differ diff --git a/public/control/backup.png b/public/control/backup.png new file mode 100644 index 0000000..5f1e342 Binary files /dev/null and b/public/control/backup.png differ diff --git a/public/control/curtains.png b/public/control/curtains.png new file mode 100644 index 0000000..8a8d34e Binary files /dev/null and b/public/control/curtains.png differ diff --git a/public/control/distinguisher.png b/public/control/distinguisher.png new file mode 100644 index 0000000..c2aba6d Binary files /dev/null and b/public/control/distinguisher.png differ diff --git a/public/control/door.png b/public/control/door.png new file mode 100644 index 0000000..f612c32 Binary files /dev/null and b/public/control/door.png differ diff --git a/public/control/lamp1.png b/public/control/lamp1.png new file mode 100644 index 0000000..9566aed Binary files /dev/null and b/public/control/lamp1.png differ diff --git a/public/control/lamp2.png b/public/control/lamp2.png new file mode 100644 index 0000000..e6bbf05 Binary files /dev/null and b/public/control/lamp2.png differ diff --git a/public/control/lamp3.png b/public/control/lamp3.png new file mode 100644 index 0000000..d0d99d4 Binary files /dev/null and b/public/control/lamp3.png differ diff --git a/public/control/lamp4.png b/public/control/lamp4.png new file mode 100644 index 0000000..f979c98 Binary files /dev/null and b/public/control/lamp4.png differ diff --git a/public/control/lamp5.png b/public/control/lamp5.png new file mode 100644 index 0000000..63d1020 Binary files /dev/null and b/public/control/lamp5.png differ diff --git a/public/control/restart.png b/public/control/restart.png new file mode 100644 index 0000000..6a8e7bf Binary files /dev/null and b/public/control/restart.png differ diff --git a/public/control/shutdown.png b/public/control/shutdown.png new file mode 100644 index 0000000..95bc0c4 Binary files /dev/null and b/public/control/shutdown.png differ diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png new file mode 100644 index 0000000..2796766 Binary files /dev/null and b/public/favicon-16x16.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png new file mode 100644 index 0000000..25d29b1 Binary files /dev/null and b/public/favicon-32x32.png differ diff --git a/public/file.svg b/public/file.svg deleted file mode 100644 index 004145c..0000000 --- a/public/file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/globe.svg b/public/globe.svg deleted file mode 100644 index 567f17b..0000000 --- a/public/globe.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000..363adca Binary files /dev/null and b/public/logo.png differ diff --git a/public/next.svg b/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/open-graph.png b/public/open-graph.png new file mode 100644 index 0000000..0da83de Binary files /dev/null and b/public/open-graph.png differ diff --git a/public/site.webmanifest b/public/site.webmanifest new file mode 100644 index 0000000..1eeeb0a --- /dev/null +++ b/public/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "Next Level UI", + "short_name": "NLU", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index 7705396..0000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/window.svg b/public/window.svg deleted file mode 100644 index b2b2a44..0000000 --- a/public/window.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/app/(auth)/Login.tsx b/src/app/(auth)/Login.tsx new file mode 100644 index 0000000..5111187 --- /dev/null +++ b/src/app/(auth)/Login.tsx @@ -0,0 +1,7 @@ +export default function Auth () { + return ( +
+ Login Component +
+ ); +}; diff --git a/src/app/(auth)/email-verify/page.tsx b/src/app/(auth)/email-verify/page.tsx new file mode 100644 index 0000000..d9d28a5 --- /dev/null +++ b/src/app/(auth)/email-verify/page.tsx @@ -0,0 +1,26 @@ +import Image from "next/image"; + +const EmailSuccessPage = () => { + return ( +
+
+ Email Verification + +

Check your email

+ +

+ To confirm your email address, tap the link in the email we sent to + you. +

+
+
+ ); +}; + +export default EmailSuccessPage; diff --git a/src/app/(auth)/layout.tsx b/src/app/(auth)/layout.tsx new file mode 100644 index 0000000..81f024d --- /dev/null +++ b/src/app/(auth)/layout.tsx @@ -0,0 +1,96 @@ +import { ThemeProvider } from "@/components//theme-provider"; +import { siteConfig } from "@/config//site"; +import { cn } from "@/utils/cn"; +import type { Metadata, Viewport } from "next"; +import { Inter } from "next/font/google"; +import { Toaster } from "react-hot-toast"; + +import "./globals.css"; + +const inter = Inter({ subsets: ["latin"] }); + +export const viewport: Viewport = { + themeColor: [ + { media: "(prefers-color-scheme: light)", color: "white" }, + { media: "(prefers-color-scheme: dark)", color: "black" }, + ], +}; + +export const metadata: Metadata = { + title: { + default: siteConfig.name, + template: `%s | ${siteConfig.name}`, + }, + description: siteConfig.description, + keywords: [ + "Next.js", + "Nextjs 14", + "React", + "Tailwind CSS", + "Server Components", + "Radix UI", + "Shadcn UI", + "Basic Nextjs template", + ], + authors: [ + { + name: "Sarath Adhithya", + url: "https://sarathadhi.com", + }, + ], + creator: "Sarath Adhithya", + metadataBase: new URL(siteConfig.url), + openGraph: { + type: "website", + locale: "en_US", + url: siteConfig.url, + title: siteConfig.name, + description: siteConfig.description, + siteName: siteConfig.name, + images: siteConfig.ogImage, + }, + twitter: { + card: "summary_large_image", + title: siteConfig.name, + description: siteConfig.description, + images: [siteConfig.ogImage], + creator: "@AdhithyaSarath", + }, + icons: { + icon: "/favicon.ico", + shortcut: "/favicon-16x16.png", + apple: "/apple-touch-icon.png", + }, + manifest: `${siteConfig.url}/site.webmanifest`, + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + }, + }, +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + + {children} + + + + + + ); +} diff --git a/src/app/(auth)/login/_components/login-form.tsx b/src/app/(auth)/login/_components/login-form.tsx new file mode 100644 index 0000000..48be56c --- /dev/null +++ b/src/app/(auth)/login/_components/login-form.tsx @@ -0,0 +1,75 @@ +"use client"; + +import { Button } from "@/components/ui/button"; +import { Form } from "@/components/ui/form"; +import { InputForm } from "@/components/ui/input/input-form"; +import { createClient } from "@/utils/supabase/client"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useRouter } from "next/navigation"; +import { useForm } from "react-hook-form"; +import toast from "react-hot-toast"; +import { z } from "zod"; + +export const loginFormSchema = z.object({ + email: z.string().email(), + password: z.string().min(8, { + message: "Password must be at least 8 characters.", + }), +}); + +type LoginValuesType = z.infer; + +const defaultValues: LoginValuesType = { + email: "", + password: "", +}; + +const LoginForm = () => { + const router = useRouter(); + + const supabase = createClient(); + + const form = useForm({ + resolver: zodResolver(loginFormSchema), + defaultValues, + }); + + async function handleLogin(values: LoginValuesType) { + const { error } = await supabase.auth.signInWithPassword(values); + + if (error) return toast.error(error.message); + + toast.success("Login successful"); + + router.refresh(); + } + + return ( +
+ + + + + + + + + ); +}; + +export default LoginForm; diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx new file mode 100644 index 0000000..c39513e --- /dev/null +++ b/src/app/(auth)/login/page.tsx @@ -0,0 +1,44 @@ +import { Button } from "@/components/ui/button"; +import { cn } from "@/utils/cn"; +import { ChevronLeftCircle } from "lucide-react"; +import Link from "next/link"; +import LoginForm from "./_components/login-form"; + +const LoginPage = () => { + return ( +
+
+ + +
+

+ Welcome Back +

+

+ Enter your email and password to sign in to your account +

+
+ + + +
+

+ + Don't have an account? Register + +

+
+
+
+ ); +}; + +export default LoginPage; diff --git a/src/app/(auth)/register/_components/register-form.tsx b/src/app/(auth)/register/_components/register-form.tsx new file mode 100644 index 0000000..7896c7d --- /dev/null +++ b/src/app/(auth)/register/_components/register-form.tsx @@ -0,0 +1,82 @@ +"use client"; + +import { Button } from "@/components/ui/button"; +import { Form } from "@/components/ui/form"; +import { InputForm } from "@/components/ui/input/input-form"; +import { createClient } from "@/utils/supabase/client"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useRouter } from "next/navigation"; +import { useForm } from "react-hook-form"; +import toast from "react-hot-toast"; +import { z } from "zod"; + +export const registerFormSchema = z.object({ + email: z.string().email(), + password: z.string().min(8, { + message: "Password must be at least 8 characters.", + }), +}); + +type RegisterValuesType = z.infer; + +const defaultValues: RegisterValuesType = { + email: "", + password: "", +}; + +const RegisterForm = () => { + const router = useRouter(); + + const supabase = createClient(); + + const form = useForm({ + resolver: zodResolver(registerFormSchema), + defaultValues, + }); + + async function handleRegister(values: RegisterValuesType) { + const { error, data } = await supabase.auth.signUp({ + ...values, + options: { + emailRedirectTo: `${process.env.NEXT_PUBLIC_BASE_URL}/api/auth/callback`, + }, + }); + + if (error) return toast.error(error.message); + + console.log({ data }); + + toast.success("Verification email sent. Check your mail."); + + router.replace("/email-verify"); + } + + return ( +
+ + + + + + + + + ); +}; + +export default RegisterForm; diff --git a/src/app/(auth)/register/page.tsx b/src/app/(auth)/register/page.tsx new file mode 100644 index 0000000..96149c7 --- /dev/null +++ b/src/app/(auth)/register/page.tsx @@ -0,0 +1,44 @@ +import { Button } from "@/components/ui/button"; +import { cn } from "@/utils/cn"; +import { ChevronLeftCircle } from "lucide-react"; +import Link from "next/link"; +import RegisterForm from "./_components/register-form"; + +const RegisterPage = () => { + return ( +
+
+ + +
+

+ Create an Account +

+

+ Enter your email and password to create your account +

+
+ + + +
+

+ + Already have an account? Login + +

+
+
+
+ ); +}; + +export default RegisterPage; diff --git a/src/app/(main)/(home)/_components/bento-grid-section.tsx b/src/app/(main)/(home)/_components/bento-grid-section.tsx new file mode 100644 index 0000000..410e75f --- /dev/null +++ b/src/app/(main)/(home)/_components/bento-grid-section.tsx @@ -0,0 +1,107 @@ +import { BentoCard, BentoGrid } from "@/components/ui/bento-grid"; +import { + Activity, + ThermometerSnowflake, + AlertTriangle, + ShieldCheck, + BarChart3, + BrainCircuit, + LockKeyhole, + Palette, + LayoutDashboard, +} from "lucide-react"; + +const features = [ + { + Icon: BrainCircuit, + name: "AI-Powered Intelligence", + description: + "Predictive algorithms optimize cooling schedules and detect anomalies in security patterns before they become threats.", + href: "#", + cta: "Learn more", + className: "col-span-3 lg:col-span-1", + background:
, + }, + { + Icon: Activity, + name: "Real-Time Monitoring", + description: + "Stay informed with continuous tracking of temperature levels and security status across all monitored zones.", + href: "#", + cta: "Learn more", + className: "col-span-3 lg:col-span-1", + background:
, + }, + { + Icon: ThermometerSnowflake, + name: "Automated Temperature Control", + description: + "Smart sensors adjust cooling systems dynamically, conserving energy while maintaining optimal server conditions.", + href: "#", + cta: "Learn more", + className: "col-span-3 lg:col-span-1", + background:
, + }, + { + Icon: AlertTriangle, + name: "Advanced Alert System", + description: + "Instant alerts via SMS, email, or dashboard notifications when temperature thresholds or unauthorized access attempts are detected.", + href: "#", + cta: "Learn more", + className: "col-span-3 lg:col-span-1", + background:
, + }, + { + Icon: ShieldCheck, + name: "Multi-Layer Security", + description: + "Includes RFID, keypad, and optional facial recognition access control—backed by intrusion detection sensors and real-time logging.", + href: "#", + cta: "Learn more", + className: "col-span-3 lg:col-span-1", + background:
, + }, + { + Icon: BarChart3, + name: "Data Logging & Analytics", + description: + "Automatically logs temperature data and access records, allowing you to analyze trends and generate performance reports.", + href: "#", + cta: "Learn more", + className: "col-span-3 lg:col-span-1", + background:
, + }, + { + Icon: LockKeyhole, + name: "Authentication", + description: + "Secure your application with the robust authentication provided using Supabase Auth.", + href: "https://supabase.com/docs/guides/auth/server-side/nextjs", + cta: "Learn more", + className: "col-span-3 lg:col-span-2", + background:
, + }, + { + Icon: Palette, + name: "Modern UI", + description: + "Craft stunning and responsive user interfaces with the latest design principles and practices.", + href: "#", + cta: "Learn more", + className: "col-span-3 lg:col-span-1", + background:
, + }, +]; + +const BentoGridSection = () => { + return ( + + {features.map((feature, idx) => ( + + ))} + + ); +}; + +export default BentoGridSection; diff --git a/src/app/(main)/(home)/_components/floatingcirclebutton.tsx b/src/app/(main)/(home)/_components/floatingcirclebutton.tsx new file mode 100644 index 0000000..bf6a352 --- /dev/null +++ b/src/app/(main)/(home)/_components/floatingcirclebutton.tsx @@ -0,0 +1,17 @@ +"use client"; + +import { LayoutDashboard } from "lucide-react"; // You can choose any icon you prefer +import Link from "next/link"; + +const FloatingCircleButton = () => { + return ( + + + + ); +}; + +export default FloatingCircleButton; diff --git a/src/app/(main)/(home)/page.tsx b/src/app/(main)/(home)/page.tsx new file mode 100644 index 0000000..8947f3d --- /dev/null +++ b/src/app/(main)/(home)/page.tsx @@ -0,0 +1,48 @@ +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Lock } from "lucide-react"; +import Link from "next/link"; +import BentoGridSection from "./_components/bento-grid-section"; +import FloatingCircleButton from "./_components/floatingcirclebutton"; +import { createClient } from "@/utils/supabase/server"; + +const HomePage = async () => { + const supabase = createClient(); + + const { + data: { user }, + } = await supabase.auth.getUser(); + + return ( +
+
+

+ Smart. Secure. Sustainable. Empowering Server Centers with Intelligent Control +

+ +

+ Mobilis introduces an innovative Smart Temperature and Security System designed to protect and optimize server infrastructures across Algeria. With real-time monitoring, AI-powered insights, and reliable alerts, we ensure your data centers remain cool, safe, and always operational. +

+ +
+ + + +
+
+ +
+

Key Features

+ +
+ + {user && } +
+ ); +}; + +export default HomePage; diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx new file mode 100644 index 0000000..f182171 --- /dev/null +++ b/src/app/(main)/layout.tsx @@ -0,0 +1,19 @@ +import Footer from "@/components//footer"; +import Navbar from "@/components//navbar"; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + <> + + +
{children}
+ +