mirror of
https://github.com/fergalmoran/opengifame.git
synced 2025-12-22 01:28:42 +00:00
Rename some files and tidy up navbar
This commit is contained in:
19
.env
19
.env
@@ -1,24 +1,11 @@
|
||||
# When adding additional environment variables, the schema in "/src/env.js"
|
||||
# should be updated accordingly.
|
||||
|
||||
# Drizzle
|
||||
DATABASE_URL="postgresql://postgres:hackme@localhost:5432/opengifame"
|
||||
|
||||
# Next Auth
|
||||
# You can generate a new secret on the command line with:
|
||||
# openssl rand -base64 32
|
||||
# https://next-auth.js.org/configuration/options#secret
|
||||
NEXTAUTH_SECRET="tAOVgxpY1U0BsnPCr6Gf8WVkmRMkp06ztUfwMhBKMQ4="
|
||||
NEXTAUTH_URL="http://localhost:3000"
|
||||
|
||||
# Next Auth Discord Provider
|
||||
DISCORD_CLIENT_ID=""
|
||||
DISCORD_CLIENT_SECRET=""
|
||||
|
||||
NEXTAUTH_URL="https://opengifame.dev.fergl.ie:3000"
|
||||
|
||||
NEXT_PUBLIC_SITE_NAME=Open Gifame
|
||||
NEXT_PUBLIC_SITE_DESCRIPTION=Robot powered giffage
|
||||
NEXT_PUBLIC_SITE_URL=https://gifs.ferg.al,
|
||||
NEXT_PUBLIC_SITE_OG_IMAGE=http://localhost:3000/icon.png
|
||||
NEXT_PUBLIC_SITE_URL=https://opengifame.dev.fergl.ie:3000
|
||||
NEXT_PUBLIC_SITE_OG_IMAGE=https://opengifame.dev.fergl.ie:3000/icon.png
|
||||
NEXT_PUBLIC_SITE_TWITTER=https://twitter.com/opengifame
|
||||
NEXT_PUBLIC_SITE_GITHUB=https://github.com/fergalmoran/opengifame
|
||||
|
||||
@@ -1,61 +1,53 @@
|
||||
/** @type {import("eslint").Linter.Config} */
|
||||
const config = {
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"project": true
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
project: true,
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint",
|
||||
"drizzle"
|
||||
],
|
||||
"extends": [
|
||||
plugins: ["@typescript-eslint", "drizzle"],
|
||||
extends: [
|
||||
"next/core-web-vitals",
|
||||
"plugin:@typescript-eslint/recommended-type-checked",
|
||||
"plugin:@typescript-eslint/stylistic-type-checked"
|
||||
"plugin:@typescript-eslint/stylistic-type-checked",
|
||||
],
|
||||
"rules": {
|
||||
rules: {
|
||||
"@typescript-eslint/prefer-nullish-coalescing": "off",
|
||||
"@typescript-eslint/array-type": "off",
|
||||
"@typescript-eslint/consistent-type-definitions": "off",
|
||||
"@typescript-eslint/consistent-type-imports": [
|
||||
"warn",
|
||||
{
|
||||
"prefer": "type-imports",
|
||||
"fixStyle": "inline-type-imports"
|
||||
}
|
||||
prefer: "type-imports",
|
||||
fixStyle: "inline-type-imports",
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"argsIgnorePattern": "^_"
|
||||
}
|
||||
argsIgnorePattern: "^_",
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/require-await": "off",
|
||||
"@typescript-eslint/no-misused-promises": [
|
||||
"error",
|
||||
{
|
||||
"checksVoidReturn": {
|
||||
"attributes": false
|
||||
}
|
||||
}
|
||||
checksVoidReturn: {
|
||||
attributes: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
"drizzle/enforce-delete-with-where": [
|
||||
"error",
|
||||
{
|
||||
"drizzleObjectName": [
|
||||
"db",
|
||||
"ctx.db"
|
||||
]
|
||||
}
|
||||
drizzleObjectName: ["db", "ctx.db"],
|
||||
},
|
||||
],
|
||||
"drizzle/enforce-update-with-where": [
|
||||
"error",
|
||||
{
|
||||
"drizzleObjectName": [
|
||||
"db",
|
||||
"ctx.db"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
module.exports = config;
|
||||
drizzleObjectName: ["db", "ctx.db"],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
module.exports = config;
|
||||
|
||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -1,3 +1,4 @@
|
||||
{
|
||||
"workbench.colorTheme": "Tinacious Design (High Contrast)"
|
||||
// "workbench.colorTheme": "Tinacious Design (High Contrast)"
|
||||
"workbench.colorTheme": "Cyberpunk 2077 rebuild",
|
||||
}
|
||||
@@ -90,14 +90,15 @@
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/eslint": "^9.6.1",
|
||||
"@faker-js/faker": "^9.0.0",
|
||||
"@types/eslint": "^8.56.12",
|
||||
"@types/node": "^22.5.4",
|
||||
"@types/react": "^18.3.5",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.4.0",
|
||||
"@typescript-eslint/parser": "^8.4.0",
|
||||
"drizzle-kit": "^0.24.2",
|
||||
"eslint": "^9.10.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-next": "^14.2.8",
|
||||
"eslint-plugin-drizzle": "^0.2.3",
|
||||
"postcss": "^8.4.45",
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import RegistrationForm from "@/components/forms/auth/RegistrationForm";
|
||||
import SocialLogin from "@/components/widgets/login/SocialLogin";
|
||||
import RegistrationForm from "@/components/forms/auth/registration-form";
|
||||
import SocialLogin from "@/components/widgets/login/social-login-button";
|
||||
import Link from "next/link";
|
||||
import { Icons } from "@/components/icons";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { buttonVariants } from "@/components/ui/button";
|
||||
|
||||
const RegisterPage: React.FC = () => {
|
||||
return (
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
"use client";
|
||||
import SocialLogin from "@/components/widgets/login/SocialLogin";
|
||||
import SocialLogin from "@/components/widgets/login/social-login-button";
|
||||
import Link from "next/link";
|
||||
import React from "react";
|
||||
import { Icons } from "@/components/icons";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { buttonVariants } from "@/components/ui/button";
|
||||
import SignInForm from "@/components/forms/auth/SignInForm";
|
||||
import SignInForm from "@/components/forms/auth/signin-form";
|
||||
|
||||
const SignInPage = () => {
|
||||
return (
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
|
||||
import { api } from "@/trpc/react";
|
||||
|
||||
export function TrendingImages() {
|
||||
const [name, setName] = useState("");
|
||||
return <div className="w-full max-w-xs">Trending Images</div>;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Inter as FontSans } from "next/font/google";
|
||||
import { Roboto as font } from "next/font/google";
|
||||
import "@/styles/globals.css";
|
||||
|
||||
import { type Metadata, Viewport } from "next";
|
||||
import { type Metadata, type Viewport } from "next";
|
||||
|
||||
import { TRPCReactProvider } from "@/trpc/react";
|
||||
import { cn } from "@/lib/utils";
|
||||
@@ -12,17 +12,18 @@ import React from "react";
|
||||
import TopNavbar from "@/components/navbar/top-navbar";
|
||||
import { dashboardConfig } from "@/config/top-nav.config";
|
||||
import { siteConfig } from "@/config/site.config";
|
||||
import { getServerSession } from "next-auth";
|
||||
|
||||
const fontSans = FontSans({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-sans",
|
||||
});
|
||||
export const viewport: Viewport = {
|
||||
themeColor: [
|
||||
{ media: "(prefers-color-scheme: light)", color: "white" },
|
||||
{ media: "(prefers-color-scheme: dark)", color: "black" },
|
||||
],
|
||||
};
|
||||
const f = font({
|
||||
weight: "400",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Open Gifame",
|
||||
@@ -30,9 +31,10 @@ export const metadata: Metadata = {
|
||||
icons: [{ rel: "icon", url: "/favicon.ico" }],
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: Readonly<{ children: React.ReactNode }>) {
|
||||
const session = await getServerSession();
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<head>
|
||||
@@ -45,15 +47,15 @@ export default function RootLayout({
|
||||
<body
|
||||
className={cn(
|
||||
"min-h-screen bg-background font-sans antialiased",
|
||||
fontSans.variable,
|
||||
f.className,
|
||||
)}
|
||||
>
|
||||
<TRPCReactProvider>
|
||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
||||
<Toaster />
|
||||
<TailwindIndicator />
|
||||
<TopNavbar items={dashboardConfig.mainNav} />
|
||||
{children}
|
||||
<TopNavbar items={dashboardConfig.mainNav} session={session} />
|
||||
<main className="m-4">{children}</main>
|
||||
</ThemeProvider>
|
||||
</TRPCReactProvider>
|
||||
</body>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { TrendingImages } from "@/app/_components/trending-images";
|
||||
import LandingPage from "@/components/pages/landing-page";
|
||||
import { TrendingImages } from "@/components/trending-images";
|
||||
import { getServerAuthSession } from "@/server/auth";
|
||||
import { HydrateClient } from "@/trpc/server";
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
X,
|
||||
type Icon as LucideIcon,
|
||||
Terminal,
|
||||
LogIn,
|
||||
} from "lucide-react";
|
||||
|
||||
export type Icon = typeof LucideIcon;
|
||||
@@ -46,9 +47,9 @@ export const Icons = {
|
||||
user: User,
|
||||
arrowRight: ArrowRight,
|
||||
help: HelpCircle,
|
||||
login: LogIn,
|
||||
logo: ({ ...props }: LucideProps) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" {...props}>
|
||||
{/* Background */}
|
||||
<rect
|
||||
x="0"
|
||||
y="0"
|
||||
@@ -58,11 +59,7 @@ export const Icons = {
|
||||
ry="20"
|
||||
fill="#FF6B6B"
|
||||
/>
|
||||
|
||||
{/* Abstract prism shape - significantly enlarged */}
|
||||
<path d="M50,10 L90,80 L10,80 Z" fill="white" />
|
||||
|
||||
{/* Color refraction lines - adjusted for new size */}
|
||||
<path
|
||||
d="M50,10 L62,80"
|
||||
stroke="#FFD166"
|
||||
@@ -81,8 +78,6 @@ export const Icons = {
|
||||
strokeWidth={4}
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
|
||||
{/* Circular highlight - adjusted position and size */}
|
||||
<circle
|
||||
cx="50"
|
||||
cy="35"
|
||||
|
||||
@@ -1,35 +1,82 @@
|
||||
import { NavItem } from "@/types";
|
||||
"use client";
|
||||
import Link from "next/link";
|
||||
import React from "react";
|
||||
|
||||
import { type NavItem } from "@/types";
|
||||
import { type Session } from "next-auth";
|
||||
|
||||
import { Icons } from "../icons";
|
||||
import { siteConfig } from "@/config/site.config";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useSelectedLayoutSegment } from "next/navigation";
|
||||
|
||||
import LoginButton from "../widgets/login/login-button";
|
||||
|
||||
type TopNavbarProps = {
|
||||
items: NavItem[];
|
||||
session: Session | null;
|
||||
};
|
||||
|
||||
const TopNavbar: React.FC<TopNavbarProps> = ({ items }) => {
|
||||
const TopNavbar: React.FC<TopNavbarProps> = ({ items, session }) => {
|
||||
const segment = useSelectedLayoutSegment();
|
||||
return (
|
||||
<header className="sticky top-0 z-40 border-b bg-background">
|
||||
<div className="container flex h-16 items-center justify-between py-4">
|
||||
<div className="flex gap-6 md:gap-10">
|
||||
<Link href="/" className="hidden items-center space-x-2 md:flex">
|
||||
<Icons.logo className="h-8 w-8" />
|
||||
<span className="hidden font-bold sm:inline-block">
|
||||
{siteConfig.name}
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="mx-auto px-2 sm:px-4 lg:divide-y lg:divide-gray-200 lg:px-8">
|
||||
<div className="relative flex h-16 justify-between">
|
||||
<div className="relative z-10 flex px-2 lg:px-0">
|
||||
<div className="flex flex-shrink-0 items-center gap-4">
|
||||
<Link href="/" className="hidden items-center space-x-2 md:flex">
|
||||
<Icons.logo className="h-8 w-8" />
|
||||
<span className="hidden font-bold sm:inline-block">
|
||||
{siteConfig.name}
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
{/* <UserAccountNav
|
||||
user={{
|
||||
name: user.name,
|
||||
image: user.image,
|
||||
email: user.email,
|
||||
}}
|
||||
/> */}
|
||||
{items?.length ? (
|
||||
<nav className="hidden gap-6 md:flex">
|
||||
{items?.map((item, index) => (
|
||||
<Link
|
||||
key={index}
|
||||
href={item.disabled ? "#" : item.href}
|
||||
className={cn(
|
||||
"flex items-center text-lg font-medium transition-colors hover:text-foreground/80 sm:text-sm",
|
||||
item.href.startsWith(`/${segment}`)
|
||||
? "text-foreground"
|
||||
: "text-foreground/60",
|
||||
item.disabled && "cursor-not-allowed opacity-80",
|
||||
)}
|
||||
>
|
||||
{item.title}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative z-0 flex flex-1 items-center justify-center px-2 sm:absolute sm:inset-0">
|
||||
<div className="w-full sm:max-w-xs">
|
||||
<div className="flex flex-1 items-center justify-between space-x-2 md:justify-end">
|
||||
<div className="w-full flex-1 md:w-auto md:flex-none">
|
||||
<button className="relative inline-flex h-8 w-full items-center justify-start whitespace-nowrap rounded-[0.5rem] border border-input bg-muted/50 px-4 py-2 text-sm font-normal text-muted-foreground shadow-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 sm:pr-12 md:w-40 lg:w-64">
|
||||
<span className="hidden lg:inline-flex">
|
||||
Search images...
|
||||
</span>
|
||||
<span className="inline-flex lg:hidden">Search...</span>
|
||||
<kbd className="pointer-events-none absolute right-[0.3rem] top-[0.3rem] hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex">
|
||||
<span className="text-xs">⌘</span>K
|
||||
</kbd>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative z-10 flex items-center lg:hidden">
|
||||
Mobile menu
|
||||
</div>
|
||||
<div className="hidden lg:relative lg:z-10 lg:ml-4 lg:flex lg:items-center">
|
||||
<LoginButton session={session} />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ import React from "react";
|
||||
const LandingPage: React.FC = () => {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="text-5xl font-extrabold tracking-tight sm:text-[5rem]">
|
||||
Warning <span className="text-[hsl(280,100%,70%)]">contains</span> Gifs
|
||||
</h1>
|
||||
<div>
|
||||
<a href="/signin">Sign In</a>
|
||||
<div className="m-6">
|
||||
<h1 className="text-xl font-extrabold tracking-tight sm:text-[5rem]">
|
||||
Warning <span className="text-[hsl(280,100%,70%)]">contains</span>{" "}
|
||||
Gifs
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -21,28 +21,21 @@ export function TrendingImages() {
|
||||
{latestPost ? (
|
||||
<p className="truncate">Your most recent post: {latestPost.name}</p>
|
||||
) : (
|
||||
<p>You have no posts yet.</p>
|
||||
<p>No images yet.</p>
|
||||
)}
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
createPost.mutate({ name });
|
||||
}}
|
||||
className="flex flex-col gap-2"
|
||||
className="flex flex-col gap-2 my-4"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Title"
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value)}
|
||||
className="w-full rounded-full px-4 py-2 text-black"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="rounded-full bg-white/10 px-10 py-3 font-semibold transition hover:bg-white/20"
|
||||
disabled={createPost.isPending}
|
||||
>
|
||||
{createPost.isPending ? "Submitting..." : "Submit"}
|
||||
{createPost.isPending ? "Submitting..." : "Upload an image"}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -3,23 +3,23 @@
|
||||
import React from "react";
|
||||
import { signIn } from "next-auth/react";
|
||||
import { RiLoginCircleLine } from "react-icons/ri";
|
||||
import UserNavDropdown from "../UserNavDropdown";
|
||||
import UserNavDropdown from "../user-nav-dropdown";
|
||||
import { type Session } from "next-auth";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Icons } from "@/components/icons";
|
||||
|
||||
interface ILoginButtonProps {
|
||||
session: any;
|
||||
session: Session | null;
|
||||
}
|
||||
|
||||
const LoginButton: React.FC<ILoginButtonProps> = ({ session }) => {
|
||||
return session ? (
|
||||
<UserNavDropdown session={session} />
|
||||
) : (
|
||||
<button
|
||||
onClick={() => signIn()}
|
||||
className="btn btn-ghost drawer-button normal-case"
|
||||
>
|
||||
<RiLoginCircleLine className="inline-block h-6 w-6 fill-current md:mr-1" />
|
||||
<Button onClick={() => signIn()} className="">
|
||||
<Icons.login className="mr-2 h-4 w-4" />
|
||||
Login
|
||||
</button>
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,28 +1,25 @@
|
||||
'use client';
|
||||
import { logger } from '@lib/logger';
|
||||
import React, { Fragment } from 'react';
|
||||
import { Menu, Transition } from '@headlessui/react';
|
||||
import { signOut } from 'next-auth/react';
|
||||
"use client";
|
||||
import React, { Fragment } from "react";
|
||||
import { Menu, Transition } from "@headlessui/react";
|
||||
import { signOut } from "next-auth/react";
|
||||
import { logger } from "@/lib/logger";
|
||||
|
||||
interface IUserNavDropdownProps {
|
||||
session: any;
|
||||
}
|
||||
const UserNavDropdown: React.FC<IUserNavDropdownProps> = ({ session }) => {
|
||||
React.useEffect(() => {
|
||||
logger.debug('UserNavDropdown', 'session', session);
|
||||
logger.debug("UserNavDropdown", "session", session);
|
||||
}, [session]);
|
||||
|
||||
return (
|
||||
<div className="flex items-center">
|
||||
<Menu
|
||||
as="div"
|
||||
className="relative flex-shrink-0 ml-4"
|
||||
>
|
||||
<Menu as="div" className="relative ml-4 flex-shrink-0">
|
||||
<div>
|
||||
<Menu.Button className="flex text-sm text-white bg-gray-800 rounded-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white">
|
||||
<Menu.Button className="flex rounded-full bg-gray-800 text-sm text-white focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800">
|
||||
<span className="sr-only">Open user menu</span>
|
||||
<img
|
||||
className="w-8 h-8 rounded-full"
|
||||
className="h-8 w-8 rounded-full"
|
||||
src={session?.user?.image as string}
|
||||
alt="Profile image"
|
||||
/>
|
||||
@@ -37,7 +34,7 @@ const UserNavDropdown: React.FC<IUserNavDropdownProps> = ({ session }) => {
|
||||
leaveFrom="transform opacity-100 scale-100"
|
||||
leaveTo="transform opacity-0 scale-95"
|
||||
>
|
||||
<Menu.Items className="absolute right-0 z-50 w-48 py-1 mt-2 origin-top-right bg-white rounded-md shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
|
||||
<Menu.Items className="absolute right-0 z-50 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
|
||||
<Menu.Item>
|
||||
{({ active }) => (
|
||||
<button
|
||||
@@ -3,13 +3,8 @@ import { DashboardConfig } from "@/types";
|
||||
export const dashboardConfig: DashboardConfig = {
|
||||
mainNav: [
|
||||
{
|
||||
title: "Documentation",
|
||||
href: "/docs",
|
||||
},
|
||||
{
|
||||
title: "Support",
|
||||
href: "/support",
|
||||
disabled: true,
|
||||
title: "Upload image",
|
||||
href: "/upload",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
@@ -2,18 +2,19 @@ import { createTRPCRouter, publicProcedure } from "../trpc";
|
||||
import { z } from "zod";
|
||||
import { users } from "@/server/db/schema";
|
||||
import bcrypt from "bcrypt";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import { faker } from "@faker-js/faker";
|
||||
|
||||
export const authRouter = createTRPCRouter({
|
||||
create: publicProcedure
|
||||
.input(z.object({ email: z.string().email(), password: z.string().min(5) }))
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
const profileImage = faker.image.avatar();
|
||||
const hashedPassword = await bcrypt.hash(input.password, 10);
|
||||
const user = await ctx.db.insert(users).values({
|
||||
email: input.email,
|
||||
password: hashedPassword,
|
||||
image: profileImage,
|
||||
});
|
||||
return user;
|
||||
}),
|
||||
|
||||
});
|
||||
|
||||
@@ -57,7 +57,7 @@ export function TRPCReactProvider(props: { children: React.ReactNode }) {
|
||||
},
|
||||
}),
|
||||
],
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
1
src/types/index.d.ts
vendored
1
src/types/index.d.ts
vendored
@@ -6,7 +6,6 @@ export type NavItem = {
|
||||
export type DashboardConfig = {
|
||||
mainNav: NavItem[];
|
||||
};
|
||||
|
||||
export type SiteConfig = {
|
||||
name: string;
|
||||
description: string;
|
||||
|
||||
8
ssl-proxy.json
Normal file
8
ssl-proxy.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Dev Proxy": {
|
||||
"source": "3000",
|
||||
"target": "3002",
|
||||
"key": "/etc/letsencrypt/live/dev.fergl.ie/privkey.pem",
|
||||
"cert": "/etc/letsencrypt/live/dev.fergl.ie/fullchain.pem"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user