Skip to content

Commit

Permalink
Adds skeleton for settings page.
Browse files Browse the repository at this point in the history
  • Loading branch information
bLopata committed Oct 14, 2024
1 parent caba306 commit 0622135
Show file tree
Hide file tree
Showing 5 changed files with 352 additions and 20 deletions.
104 changes: 104 additions & 0 deletions www/app/settings/SettingsLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"use client";

import { useState } from "react";
import Link from "next/link";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { SettingsForm } from "@/components/SettingsForm";
import SubscriptionManager from "@/components/SubscriptionManager";
import SupportForm from "@/components/SupportForm";

export default function SettingsLayout({ user, subscription, products }) {
const [activeTab, setActiveTab] = useState("account");

const navItems = [
{ id: "account", label: "Account" },
{ id: "security", label: "Security" },
{ id: "subscription", label: "Subscription" },
{ id: "support", label: "Support" },
];

return (
<div className="flex-1 flex flex-col bg-background text-foreground">
{/* Top Navigation */}
<div className="p-4 border-b border-border">
<Link href="/">
<Button
variant="outline"
className="text-primary hover:bg-primary hover:text-primary-foreground"
>
Return to Home
</Button>
</Link>
</div>

<div className="flex-1 flex">
{/* Left Navigation */}
<nav className="w-64 bg-muted p-4">
<h2 className="text-2xl font-bold mb-4 text-primary">Settings</h2>
<ul>
{navItems.map((item) => (
<li key={item.id} className="mb-2">
<button
onClick={() => setActiveTab(item.id)}
className={`w-full text-left p-2 rounded ${
activeTab === item.id
? "bg-primary text-primary-foreground"
: "hover:bg-accent hover:text-accent-foreground"
}`}
>
{item.label}
</button>
</li>
))}
</ul>
</nav>

{/* Main Content */}
<div className="flex-1 p-8">
{activeTab === "account" && (
<div className="space-y-4">
<h2 className="text-3xl font-bold text-primary">
Account Settings
</h2>
<SettingsForm user={user} type="account" />
</div>
)}
{activeTab === "security" && (
<div className="space-y-4">
<h2 className="text-3xl font-bold text-primary">
Security Settings
</h2>
<SettingsForm user={user} type="security" />
</div>
)}
{activeTab === "subscription" && (
<div className="space-y-4">
<h2 className="text-3xl font-bold text-primary">
Subscription Management
</h2>
<SubscriptionManager
subscription={subscription}
products={products}
/>
</div>
)}
{activeTab === "support" && (
<div className="space-y-4">
<h2 className="text-3xl font-bold text-primary">
Contact Support
</h2>
<SupportForm user={user} />
</div>
)}
</div>
</div>
</div>
);
}
28 changes: 28 additions & 0 deletions www/app/settings/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Suspense } from "react";
import SettingsLayout from "./SettingsLayout";
import { createClient } from "@/utils/supabase/server";
import { getSubscription, getProducts } from "@/utils/supabase/queries";
import { redirect } from "next/navigation";

export default async function SettingsPage() {
const supabase = createClient();
const {
data: { user },
} = await supabase.auth.getUser();
const subscription = await getSubscription(supabase);
const products = await getProducts(supabase);

if (!user) {
redirect("/auth");
}

return (
<Suspense fallback={<div>Loading...</div>}>
<SettingsLayout
user={user}
subscription={subscription}
products={products}
/>
</Suspense>
);
}
131 changes: 131 additions & 0 deletions www/components/SettingsForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
"use client";

import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";

interface User {
id: string;
email: string;
// Add other user properties as needed
}

interface SettingsFormProps {
user: User;
type: "account" | "security";
}

export function SettingsForm({ user, type }: SettingsFormProps) {
const [email, setEmail] = useState(user.email);
const [currentPassword, setCurrentPassword] = useState("");
const [newPassword, setNewPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");

const handleEmailChange = () => {
// Implement email change logic
console.log("Changing email to:", email);
};

const handlePasswordChange = () => {
// Implement password change logic
console.log("Changing password");
};

return (
<Card className="bg-card text-card-foreground">
<CardHeader>
<CardTitle className="text-primary">
{type === "account" ? "Account Information" : "Security Settings"}
</CardTitle>
<CardDescription>
{type === "account"
? "Update your account settings here."
: "Manage your security settings and change your password."}
</CardDescription>
</CardHeader>
<CardContent className="space-y-6">
{type === "account" && (
<div className="space-y-2">
<Label htmlFor="email" className="text-foreground">
Email
</Label>
<Input
id="email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="bg-input text-foreground flex-grow"
/>
</div>
)}
{type === "security" && (
<>
<div className="space-y-2">
<Label htmlFor="currentPassword" className="text-foreground">
Current Password
</Label>
<Input
id="currentPassword"
type="password"
value={currentPassword}
onChange={(e) => setCurrentPassword(e.target.value)}
className="bg-input text-foreground"
/>
</div>
<div className="space-y-2">
<Label htmlFor="newPassword" className="text-foreground">
New Password
</Label>
<Input
id="newPassword"
type="password"
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
className="bg-input text-foreground"
/>
</div>
<div className="space-y-2">
<Label htmlFor="confirmPassword" className="text-foreground">
Confirm New Password
</Label>
<Input
id="confirmPassword"
type="password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
className="bg-input text-foreground"
/>
</div>
</>
)}
</CardContent>
<CardFooter className="flex justify-start border-t pt-6">
{type === "account" && (
<Button
onClick={handleEmailChange}
className="bg-primary text-primary-foreground hover:bg-primary/90"
>
Update Email
</Button>
)}
{type === "security" && (
<Button
onClick={handlePasswordChange}
className="bg-primary text-primary-foreground hover:bg-primary/90"
>
Change Password
</Button>
)}
</CardFooter>
</Card>
);
}
57 changes: 57 additions & 0 deletions www/components/SupportForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"use client";

import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";

interface SupportFormProps {
user: {
id: string;
email: string;
};
}

export default function SupportForm({ user }: SupportFormProps) {
const [message, setMessage] = useState("");

const handleSubmit = () => {
// Implement support message submission logic
console.log("Submitting support message:", message);
};

return (
<Card className="bg-card text-card-foreground">
<CardHeader>
<CardTitle className="text-primary">Contact Support</CardTitle>
<CardDescription>
Send us a message and we&apos;ll get back to you as soon as possible.
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<Textarea
placeholder="Describe your issue or question"
value={message}
onChange={(e) => setMessage(e.target.value)}
className="bg-input text-foreground"
rows={5}
/>
</CardContent>
<CardFooter className="flex justify-start pt-6">
<Button
onClick={handleSubmit}
className="bg-primary text-primary-foreground hover:bg-primary/90"
>
Send Message
</Button>
</CardFooter>
</Card>
);
}
Loading

0 comments on commit 0622135

Please sign in to comment.