new website beginning
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
import { type Session } from "next-auth";
|
||||
import { SessionProvider } from "next-auth/react";
|
||||
import { type AppType } from "next/app";
|
||||
|
||||
import { api } from "@/utils/api";
|
||||
|
||||
import "@/styles/globals.css";
|
||||
|
||||
const MyApp: AppType<{ session: Session | null }> = ({
|
||||
Component,
|
||||
pageProps: { session, ...pageProps },
|
||||
}) => {
|
||||
return (
|
||||
<SessionProvider session={session}>
|
||||
<Component {...pageProps} />
|
||||
</SessionProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default api.withTRPC(MyApp);
|
||||
@@ -0,0 +1,5 @@
|
||||
import NextAuth from "next-auth";
|
||||
|
||||
import { authOptions } from "@/server/auth";
|
||||
|
||||
export default NextAuth(authOptions);
|
||||
@@ -0,0 +1,19 @@
|
||||
import { createNextApiHandler } from "@trpc/server/adapters/next";
|
||||
|
||||
import { env } from "@/env.mjs";
|
||||
import { appRouter } from "@/server/api/root";
|
||||
import { createTRPCContext } from "@/server/api/trpc";
|
||||
|
||||
// export API handler
|
||||
export default createNextApiHandler({
|
||||
router: appRouter,
|
||||
createContext: createTRPCContext,
|
||||
onError:
|
||||
env.NODE_ENV === "development"
|
||||
? ({ path, error }) => {
|
||||
console.error(
|
||||
`❌ tRPC failed on ${path ?? "<no-path>"}: ${error.message}`
|
||||
);
|
||||
}
|
||||
: undefined,
|
||||
});
|
||||
@@ -0,0 +1,80 @@
|
||||
import { signIn, signOut, useSession } from "next-auth/react";
|
||||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
|
||||
import { api } from "@/utils/api";
|
||||
|
||||
export default function Home() {
|
||||
const hello = api.post.hello.useQuery({ text: "from tRPC" });
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Create T3 App</title>
|
||||
<meta name="description" content="Generated by create-t3-app" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<main className=" flex min-h-screen flex-col items-center justify-center bg-gradient-to-b from-[#2e026d] to-[#15162c]">
|
||||
<div className="container flex flex-col items-center justify-center gap-12 px-4 py-16 ">
|
||||
<h1 className="text-5xl font-extrabold tracking-tight text-white sm:text-[5rem]">
|
||||
Create <span className="text-[hsl(280,100%,70%)]">T3</span> App
|
||||
</h1>
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:gap-8">
|
||||
<Link
|
||||
className="flex max-w-xs flex-col gap-4 rounded-xl bg-white/10 p-4 text-white hover:bg-white/20"
|
||||
href="https://create.t3.gg/en/usage/first-steps"
|
||||
target="_blank"
|
||||
>
|
||||
<h3 className="text-2xl font-bold">First Steps →</h3>
|
||||
<div className="text-lg">
|
||||
Just the basics - Everything you need to know to set up your
|
||||
database and authentication.
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
className="flex max-w-xs flex-col gap-4 rounded-xl bg-white/10 p-4 text-white hover:bg-white/20"
|
||||
href="https://create.t3.gg/en/introduction"
|
||||
target="_blank"
|
||||
>
|
||||
<h3 className="text-2xl font-bold">Documentation →</h3>
|
||||
<div className="text-lg">
|
||||
Learn more about Create T3 App, the libraries it uses, and how
|
||||
to deploy it.
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex flex-col items-center gap-2">
|
||||
<p className="text-2xl text-white">
|
||||
{hello.data ? hello.data.greeting : "Loading tRPC query..."}
|
||||
</p>
|
||||
<AuthShowcase />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function AuthShowcase() {
|
||||
const { data: sessionData } = useSession();
|
||||
|
||||
const { data: secretMessage } = api.post.getSecretMessage.useQuery(
|
||||
undefined, // no input
|
||||
{ enabled: sessionData?.user !== undefined }
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center gap-4">
|
||||
<p className="text-center text-2xl text-white">
|
||||
{sessionData && <span>Logged in as {sessionData.user?.name}</span>}
|
||||
{secretMessage && <span> - {secretMessage}</span>}
|
||||
</p>
|
||||
<button
|
||||
className="rounded-full bg-white/10 px-10 py-3 font-semibold text-white no-underline transition hover:bg-white/20"
|
||||
onClick={sessionData ? () => void signOut() : () => void signIn()}
|
||||
>
|
||||
{sessionData ? "Sign out" : "Sign in"}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { signIn, signOut, useSession } from "next-auth/react";
|
||||
import Head from "next/head"
|
||||
import Header from "@/components/header";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main className="min-h-screen bg-black color-white">
|
||||
<div className="w-1/2 mx-auto text-white">
|
||||
<Header />
|
||||
<p>test</p>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import {useRouter} from 'next/router';
|
||||
import {useState, useEffect} from 'react'
|
||||
import {api} from '@/utils/api'
|
||||
import { useSession } from 'next-auth/react';
|
||||
|
||||
export default function ReviewPage() {
|
||||
const router = useRouter()
|
||||
const name = router.query.name as string
|
||||
const {data: bookData} = api.post.getOne.useQuery(name)
|
||||
const [view,setView] = useState(null)
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>Post: {router.query.name}</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import {useSession, getSession} from 'next-auth/react';
|
||||
import {useState, useEffect, FormEvent} from 'react';
|
||||
import Header from '@/components/header';
|
||||
import Router from 'next/router';
|
||||
import { api } from "@/utils/api";
|
||||
|
||||
export default function Page() {
|
||||
const { data: session, status } = useSession()
|
||||
const mutation = api.post.create.useMutation()
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
if (status == "unauthenticated") {
|
||||
console.log('user is unauthenticated!')
|
||||
Router.replace('/')
|
||||
} else {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [status])
|
||||
|
||||
function onSubmit(event: FormEvent<HTMLFormElement>) {
|
||||
event.preventDefault()
|
||||
|
||||
const object = {
|
||||
name: event.target.title.value,
|
||||
reviewContents: event.target.review.value,
|
||||
image: event.target.image.value,
|
||||
type: event.target.type.value
|
||||
}
|
||||
|
||||
mutation.mutate(object)
|
||||
}
|
||||
|
||||
if (!loading) {
|
||||
return (
|
||||
<main className="min-h-screen bg-black color-white">
|
||||
<div className="w-1/2 mx-auto text-white">
|
||||
<Header />
|
||||
<form onSubmit={onSubmit} className="text-black">
|
||||
<div className="bg-gray-500 text-center">
|
||||
<label className="font-bold">Title</label><br />
|
||||
<input name="title" type="text" /><br />
|
||||
|
||||
<label className="font-bold">Image URL</label><br />
|
||||
<input name="image" type="text" /><br />
|
||||
|
||||
<label className="font-bold">Content Type (book, movie, tv, game)</label><br />
|
||||
<input name="type" type="text" /><br />
|
||||
|
||||
<label className="font-bold">Review</label><br />
|
||||
<textarea name="review" />
|
||||
|
||||
<button type="submit">submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<main>
|
||||
<p>
|
||||
Loading..
|
||||
</p>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import Header from "@/components/header"
|
||||
import ReviewCard from "@/components/ReviewCard"
|
||||
import {useSession} from 'next-auth/react';
|
||||
import {useState, useEffect} from 'react';
|
||||
import { api } from "@/utils/api";
|
||||
|
||||
type GenericItemType = {
|
||||
name: string,
|
||||
image: string
|
||||
}
|
||||
|
||||
export default function Reviews() {
|
||||
const { data: sessionData, status } = useSession();
|
||||
const {data: itemData} = api.post.getAll.useQuery()
|
||||
const [list, setList] = useState<null | JSX.Element[]>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (itemData) {
|
||||
setList(
|
||||
itemData?.map((v: GenericItemType) => {
|
||||
return <ReviewCard title={v.name} url={`/reviews/${v.name}`} image={v.image} />
|
||||
})
|
||||
)
|
||||
}
|
||||
}, [itemData])
|
||||
|
||||
return (
|
||||
<main className="min-h-screen bg-black color-white">
|
||||
<div className="w-1/2 mx-auto text-white">
|
||||
<Header />
|
||||
{
|
||||
status == "authenticated" ?
|
||||
<p className="text-center font-bold">
|
||||
<a href="/reviews/create">
|
||||
Create
|
||||
</a>
|
||||
</p>
|
||||
:
|
||||
""
|
||||
}
|
||||
<div className="flex flex-wrap justify-center">
|
||||
{list}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user