initial commit
This commit is contained in:
18
src/pages/_app.tsx
Normal file
18
src/pages/_app.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
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);
|
||||
4
src/pages/api/auth/[...nextauth].ts
Normal file
4
src/pages/api/auth/[...nextauth].ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import NextAuth from "next-auth";
|
||||
import { authOptions } from "~/server/auth";
|
||||
|
||||
export default NextAuth(authOptions);
|
||||
18
src/pages/api/trpc/[trpc].ts
Normal file
18
src/pages/api/trpc/[trpc].ts
Normal file
@@ -0,0 +1,18 @@
|
||||
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,
|
||||
});
|
||||
149
src/pages/index.module.css
Normal file
149
src/pages/index.module.css
Normal file
@@ -0,0 +1,149 @@
|
||||
.main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
background-image: linear-gradient(to bottom, #2e026d, #15162c);
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 3rem;
|
||||
padding: 4rem 1rem;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.container {
|
||||
max-width: 640px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.container {
|
||||
max-width: 768px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.container {
|
||||
max-width: 1024px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
.container {
|
||||
max-width: 1280px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1536px) {
|
||||
.container {
|
||||
max-width: 1536px;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 3rem;
|
||||
line-height: 1;
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.025em;
|
||||
margin: 0;
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.title {
|
||||
font-size: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.pinkSpan {
|
||||
color: hsl(280 100% 70%);
|
||||
}
|
||||
|
||||
.cardRow {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.cardRow {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.cardRow {
|
||||
gap: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
max-width: 20rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
padding: 1rem;
|
||||
border-radius: 0.75rem;
|
||||
color: white;
|
||||
background-color: rgb(255 255 255 / 0.1);
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
background-color: rgb(255 255 255 / 0.2);
|
||||
transition: background-color 150ms cubic-bezier(0.5, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.cardText {
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.75rem;
|
||||
}
|
||||
|
||||
.showcaseContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.showcaseText {
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
.authContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.loginButton {
|
||||
border-radius: 9999px;
|
||||
background-color: rgb(255 255 255 / 0.1);
|
||||
padding: 0.75rem 2.5rem;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
text-decoration-line: none;
|
||||
transition: background-color 150ms cubic-bezier(0.5, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.loginButton:hover {
|
||||
background-color: rgb(255 255 255 / 0.2);
|
||||
}
|
||||
80
src/pages/index.tsx
Normal file
80
src/pages/index.tsx
Normal file
@@ -0,0 +1,80 @@
|
||||
import styles from "./index.module.css";
|
||||
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.example.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={styles.main}>
|
||||
<div className={styles.container}>
|
||||
<h1 className={styles.title}>
|
||||
Create <span className={styles.pinkSpan}>T3</span> App
|
||||
</h1>
|
||||
<div className={styles.cardRow}>
|
||||
<Link
|
||||
className={styles.card}
|
||||
href="https://create.t3.gg/en/usage/first-steps"
|
||||
target="_blank"
|
||||
>
|
||||
<h3 className={styles.cardTitle}>First Steps →</h3>
|
||||
<div className={styles.cardText}>
|
||||
Just the basics - Everything you need to know to set up your
|
||||
database and authentication.
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
className={styles.card}
|
||||
href="https://create.t3.gg/en/introduction"
|
||||
target="_blank"
|
||||
>
|
||||
<h3 className={styles.cardTitle}>Documentation →</h3>
|
||||
<div className={styles.cardText}>
|
||||
Learn more about Create T3 App, the libraries it uses, and how
|
||||
to deploy it.
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className={styles.showcaseContainer}>
|
||||
<p className={styles.showcaseText}>
|
||||
{hello.data ? hello.data.greeting : "Loading tRPC query..."}
|
||||
</p>
|
||||
<AuthShowcase />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function AuthShowcase() {
|
||||
const { data: sessionData } = useSession();
|
||||
|
||||
const { data: secretMessage } = api.example.getSecretMessage.useQuery(
|
||||
undefined, // no input
|
||||
{ enabled: sessionData?.user !== undefined },
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles.authContainer}>
|
||||
<p className={styles.showcaseText}>
|
||||
{sessionData && <span>Logged in as {sessionData.user?.name}</span>}
|
||||
{secretMessage && <span> - {secretMessage}</span>}
|
||||
</p>
|
||||
<button
|
||||
className={styles.loginButton}
|
||||
onClick={sessionData ? () => void signOut() : () => void signIn()}
|
||||
>
|
||||
{sessionData ? "Sign out" : "Sign in"}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user