Skip to content

Commit 279dc9a

Browse files
authored
Merge pull request #5 from 100XEnginners/v0/chat
feat: settins
2 parents fa765e6 + d63af7b commit 279dc9a

47 files changed

Lines changed: 2321 additions & 720 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

next.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import "./src/env.js";
77
/** @type {import("next").NextConfig} */
88
const config = {
99
output: "standalone",
10+
images: {
11+
domains: ["lh3.googleusercontent.com"]
12+
}
1013
};
1114

1215
export default config;

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@
3131
"@radix-ui/react-collapsible": "^1.1.11",
3232
"@radix-ui/react-dialog": "^1.1.14",
3333
"@radix-ui/react-dropdown-menu": "^2.1.15",
34+
"@radix-ui/react-label": "^2.1.7",
3435
"@radix-ui/react-select": "^2.2.5",
3536
"@radix-ui/react-separator": "^1.1.7",
3637
"@radix-ui/react-slot": "^1.2.3",
38+
"@radix-ui/react-switch": "^1.2.5",
39+
"@radix-ui/react-tabs": "^1.1.12",
3740
"@radix-ui/react-tooltip": "^1.2.7",
3841
"@t3-oss/env-nextjs": "^0.12.0",
3942
"@tanstack/react-query": "^5.69.0",
@@ -49,6 +52,7 @@
4952
"lucide-react": "^0.514.0",
5053
"next": "^15.2.3",
5154
"next-auth": "5.0.0-beta.25",
55+
"next-themes": "^0.4.6",
5256
"openai": "^5.1.1",
5357
"react": "^19.0.0",
5458
"react-dom": "^19.0.0",

src/actions/fetchUser.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"use server"
2+
import { auth } from "@/server/auth"
3+
import { db } from "@/server/db"
4+
export async function FetchUser() {
5+
const session = await auth()
6+
if (!session) {
7+
return null
8+
}
9+
const user = await db.user.findUnique({
10+
where: { id: session.user.id }
11+
})
12+
13+
return user
14+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
"use client";
2+
import Chat from "@/app/_components/Chat";
3+
4+
export default function SingleChatPage() {
5+
return (
6+
<>
7+
<Chat />
8+
</>
9+
);
10+
}

src/app/(app)/ask/layout.tsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { SidebarToggle } from "@/app/_components/sidebar-toggle";
2+
import {
3+
SidebarInset,
4+
SidebarTrigger,
5+
useSidebar,
6+
} from "@/components/ui/sidebar";
7+
import { SelectTheme } from "@/components/ui/theme-toggler";
8+
import { UIStructure } from "@/components/ui/ui-structure";
9+
import { SlidersHorizontalIcon } from "@phosphor-icons/react/dist/ssr";
10+
import Link from "next/link";
11+
12+
export default function ChatLayout({
13+
children,
14+
}: {
15+
children: React.ReactNode;
16+
}) {
17+
return (
18+
<>
19+
<UIStructure />
20+
<SidebarInset className="!h-svh p-2">
21+
<div className="bg-muted/80 relative h-full max-h-svh w-full overflow-hidden rounded-xl p-4">
22+
<div className="absolute top-0 left-0 flex h-12 w-full items-center justify-between px-3">
23+
<SidebarToggle />
24+
<div className="flex items-center gap-2">
25+
<Link
26+
className="hover:bg-accent flex size-7 items-center justify-center rounded-lg"
27+
href="/settings/subscription"
28+
>
29+
<SlidersHorizontalIcon weight="bold" className="size-5" />
30+
</Link>
31+
<SelectTheme />
32+
</div>
33+
</div>
34+
<div className="mx-auto flex h-full w-full max-w-3xl flex-col">
35+
{children}
36+
</div>
37+
</div>
38+
</SidebarInset>
39+
</>
40+
);
41+
}

src/app/(app)/ask/page.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from "react";
2+
import { HydrateClient } from "@/trpc/server";
3+
import UIInput from "@/components/ui/ui-input";
4+
5+
const page = () => {
6+
return (
7+
<HydrateClient>
8+
<div className="flex w-full max-w-screen flex-col items-center justify-center">
9+
<UIInput />
10+
</div>
11+
</HydrateClient>
12+
);
13+
};
14+
15+
export default page;
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import type { ReactNode } from "react";
2+
import Image from "next/image";
3+
import { Badge } from "@/components/ui/badge";
4+
import { Button } from "@/components/ui/button";
5+
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
6+
import { FetchUser } from "@/actions/fetchUser";
7+
import Link from "next/link";
8+
import { ArrowLeftIcon } from "@phosphor-icons/react/dist/ssr";
9+
import SignOut from "@/components/ui/signout";
10+
import { SelectTheme } from "@/components/ui/theme-toggler";
11+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
12+
import { Account } from "@/components/subscription/account";
13+
import { Customisation } from "@/components/subscription/customisation";
14+
import { Profile } from "@/components/subscription/profile/profile";
15+
import Models from "@/components/subscription/model";
16+
import APIKeysPage from "@/components/subscription/api-key";
17+
import { AttachmentsPage } from "@/components/subscription/attachments";
18+
import { ContactUsPage } from "@/components/subscription/contact-us";
19+
import { History } from "@/components/subscription/history";
20+
21+
export default async function SubscriptionPage() {
22+
const user = await FetchUser();
23+
console.log(user);
24+
return (
25+
<div className="bg-background text-foreground min-h-screen w-full border">
26+
<div className="mx-auto w-full max-w-6xl p-8">
27+
<div>
28+
<div className="mb-6 flex items-center justify-between text-2xl font-bold">
29+
<Button asChild variant="ghost" className="font-semibold">
30+
<Link className="flex items-center gap-2" href="/">
31+
<ArrowLeftIcon className="size-4" />
32+
Back to chat
33+
</Link>
34+
</Button>
35+
<div className="flex items-center gap-3">
36+
<SelectTheme />
37+
<SignOut />
38+
</div>
39+
</div>
40+
</div>
41+
<div className="grid grid-cols-1 gap-14 lg:grid-cols-3">
42+
{/* Left Column - Profile and Shortcuts */}
43+
<div className="hidden space-y-8 lg:col-span-1 lg:block">
44+
{/* Profile Section */}
45+
<Profile image={user?.image as string} />
46+
47+
{/* Message Usage */}
48+
<div className="bg-accent space-y-4 rounded-xl p-4 dark:bg-black">
49+
<div className="flex items-center justify-between">
50+
<span className="text-foreground font-medium">
51+
Message Usage
52+
</span>
53+
<span className="text-muted-foreground text-sm">
54+
Resets today at 5:30 AM
55+
</span>
56+
</div>
57+
58+
<div className="space-y-2">
59+
<div className="flex items-center justify-between">
60+
<span className="text-foreground">Standard</span>
61+
<span className="text-foreground font-mono">0/20</span>
62+
</div>
63+
<div className="bg-muted h-2 w-full rounded-full">
64+
<div
65+
className="bg-primary h-2 rounded-full"
66+
style={{ width: "0%" }}
67+
></div>
68+
</div>
69+
<p className="text-muted-foreground text-sm">
70+
20 messages remaining
71+
</p>
72+
</div>
73+
</div>
74+
</div>
75+
76+
{/* Right Column - Tabs Section */}
77+
<div className="lg:col-span-2">
78+
<Tabs defaultValue="account" className="max-w-full overflow-x-auto">
79+
<div className="no-scrollbar overflow-x-auto">
80+
<TabsList className="h-[34px] rounded-lg">
81+
<TabsTrigger className="rounded-md text-xs" value="account">
82+
Account
83+
</TabsTrigger>
84+
<TabsTrigger
85+
className="rounded-lg text-xs"
86+
value="customisation"
87+
>
88+
Customisation
89+
</TabsTrigger>
90+
<TabsTrigger className="rounded-lg text-xs" value="history">
91+
History & Sync
92+
</TabsTrigger>
93+
<TabsTrigger className="rounded-lg text-xs" value="models">
94+
Models
95+
</TabsTrigger>
96+
<TabsTrigger className="rounded-lg text-xs" value="api-keys">
97+
API Keys
98+
</TabsTrigger>
99+
<TabsTrigger
100+
className="rounded-lg text-xs"
101+
value="attachments"
102+
>
103+
Attachments
104+
</TabsTrigger>
105+
<TabsTrigger className="rounded-lg text-xs" value="contact">
106+
Contact
107+
</TabsTrigger>
108+
</TabsList>
109+
</div>
110+
<TabsContent value="account" className="mt-6">
111+
<Account />
112+
</TabsContent>
113+
<TabsContent value="customisation">
114+
<Customisation />
115+
</TabsContent>
116+
<TabsContent value="history">
117+
<History />
118+
</TabsContent>
119+
<TabsContent value="models">
120+
<Models />
121+
</TabsContent>
122+
<TabsContent value="api-keys">
123+
<APIKeysPage />
124+
</TabsContent>
125+
<TabsContent value="attachments">
126+
<AttachmentsPage />
127+
</TabsContent>
128+
<TabsContent value="contact">
129+
<ContactUsPage />
130+
</TabsContent>
131+
</Tabs>
132+
</div>
133+
</div>
134+
</div>
135+
</div>
136+
);
137+
}

src/app/(auth)/auth/page.tsx

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
"use client";
2+
import { useRouter } from "next/navigation";
3+
import { signIn } from "next-auth/react";
4+
import { ArrowLeft } from "lucide-react";
5+
import { Button } from "@/components/ui/button";
6+
import Link from "next/link";
7+
8+
function LoginPage() {
9+
const router = useRouter();
10+
11+
return (
12+
<div className="mx-auto max-h-screen max-w-6xl">
13+
<div className="absolute top-4 left-4">
14+
<Button asChild variant="ghost" className="font-semibold">
15+
<Link className="flex items-center gap-2" href="/">
16+
<ArrowLeft className="size-4" />
17+
Back to chat
18+
</Link>
19+
</Button>
20+
</div>
21+
<div className="flex h-full flex-col items-center justify-center gap-8">
22+
<div className="flex flex-col items-center gap-2">
23+
<div className="flex items-center gap-2">
24+
<span className="text-xl font-bold text-white">Welcome to</span>
25+
<span className="text-primary-foreground text-2xl font-bold">
26+
T3.chat
27+
</span>
28+
</div>
29+
<p className="text-foreground text-center">
30+
Sign in below (we'll increase your message limits if you do 😉)
31+
</p>
32+
</div>
33+
<Button
34+
variant="t3"
35+
onClick={() => signIn("google")}
36+
className="h-14 w-[25rem] text-lg font-semibold text-white"
37+
>
38+
<svg
39+
viewBox="-3 0 262 262"
40+
xmlns="http://www.w3.org/2000/svg"
41+
preserveAspectRatio="xMidYMid"
42+
fill="#000000"
43+
className="mr-4 size-3"
44+
>
45+
<g id="SVGRepo_bgCarrier" strokeWidth="0"></g>
46+
<g
47+
id="SVGRepo_tracerCarrier"
48+
strokeLinecap="round"
49+
strokeLinejoin="round"
50+
></g>
51+
<g id="SVGRepo_iconCarrier">
52+
<path
53+
d="M255.878 133.451c0-10.734-.871-18.567-2.756-26.69H130.55v48.448h71.947c-1.45 12.04-9.283 30.172-26.69 42.356l-.244 1.622 38.755 30.023 2.685.268c24.659-22.774 38.875-56.282 38.875-96.027"
54+
fill="#4285F4"
55+
></path>
56+
<path
57+
d="M130.55 261.1c35.248 0 64.839-11.605 86.453-31.622l-41.196-31.913c-11.024 7.688-25.82 13.055-45.257 13.055-34.523 0-63.824-22.773-74.269-54.25l-1.531.13-40.298 31.187-.527 1.465C35.393 231.798 79.49 261.1 130.55 261.1"
58+
fill="#34A853"
59+
></path>
60+
<path
61+
d="M56.281 156.37c-2.756-8.123-4.351-16.827-4.351-25.82 0-8.994 1.595-17.697 4.206-25.82l-.073-1.73L15.26 71.312l-1.335.635C5.077 89.644 0 109.517 0 130.55s5.077 40.905 13.925 58.602l42.356-32.782"
62+
fill="#FBBC05"
63+
></path>
64+
<path
65+
d="M130.55 50.479c24.514 0 41.05 10.589 50.479 19.438l36.844-35.974C195.245 12.91 165.798 0 130.55 0 79.49 0 35.393 29.301 13.925 71.947l42.211 32.783c10.59-31.477 39.891-54.251 74.414-54.251"
66+
fill="#EB4335"
67+
></path>
68+
</g>
69+
</svg>
70+
Continue with Google
71+
</Button>
72+
<div className="text-muted-foreground/80 text-sm">
73+
By continuing, you agree to our{" "}
74+
<span className="text-muted-foreground font-medium">
75+
Terms of Service
76+
</span>{" "}
77+
and{" "}
78+
<span className="text-muted-foreground font-medium">
79+
Privacy Policy
80+
</span>
81+
</div>
82+
</div>
83+
</div>
84+
);
85+
}
86+
87+
export default LoginPage;

0 commit comments

Comments
 (0)