Skip to content

Commit c0129b7

Browse files
committed
Lets try this user login
1 parent 98c48f0 commit c0129b7

File tree

4 files changed

+190
-18
lines changed

4 files changed

+190
-18
lines changed

app/page.tsx

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,39 @@ import dynamic from 'next/dynamic'
1414
import Head from "next/head";
1515
import Link from "next/link";
1616
import {Button} from "@/components/ui/button";
17+
import { useAuth } from '@/components/AuthProvider';
18+
import LoginForm from "@/components/LoginForm";
19+
1720

1821
const GlyphGenerator = dynamic(() => import('../components/GlyphGenerator'), { ssr: false })
1922

2023
export default function Home() {
21-
return (
22-
<>
23-
<Head>
24-
<title>No Man's Sky Portal Address Tool</title>
25-
<link rel="icon" href="/favicon.ico" sizes="any"/>
26-
<meta name="description" content="Generate and share portal addresses for No Man's Sky"/>
27-
</Head>
28-
<div className="min-h-screen flex flex-col">
29-
<Header/>
30-
<main className="flex-grow container mx-auto px-4 py-8">
31-
<div className="mb-4 flex justify-center items-center text-center">
32-
<Link href="/info" className="text-blue-600 hover:underline">
33-
Got questions?
34-
</Link>
35-
</div>
36-
<GlyphGenerator/>
37-
</main>
24+
const { user, logOut } = useAuth();
25+
26+
return (
27+
<>
28+
<Head>
29+
<title>No Man's Sky Portal Address Tool</title>
30+
<link rel="icon" href="/favicon.ico" sizes="any"/>
31+
<meta name="description" content="Generate and share portal addresses for No Man's Sky"/>
32+
</Head>
33+
<div className="min-h-screen flex flex-col">
34+
<Header/>
35+
<main className="flex-grow container mx-auto px-4 py-8">
36+
<div className="mb-4 flex justify-center items-center text-center">
37+
<Link href="/info" className="text-blue-600 hover:underline">
38+
Got questions?
39+
</Link>
40+
</div>
41+
{user ? (
42+
<>
43+
<Button onClick={logOut} className="mb-4">Log Out</Button>
44+
<GlyphGenerator/>
45+
</>
46+
) : (
47+
<LoginForm />
48+
)}
49+
</main>
3850
<footer className="bg-muted text-muted-foreground py-6">
3951
<div
4052
className="container mx-auto px-4 md:px-6 flex flex-col sm:flex-row items-center justify-between">

components/AuthProvider.tsx

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import React, { createContext, useContext, useEffect, useState } from 'react';
2+
import { auth, database } from '@/firebaseConfig';
3+
import { User, createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut } from 'firebase/auth';
4+
import { ref, set, get } from 'firebase/database';
5+
6+
interface AuthContextType {
7+
user: User | null;
8+
signUp: (email: string, password: string, friendCode: string) => Promise<void>;
9+
signIn: (email: string, password: string) => Promise<void>;
10+
logOut: () => Promise<void>;
11+
setFriendCode: (code: string) => Promise<void>;
12+
friendCode: string | null;
13+
}
14+
15+
const AuthContext = createContext<AuthContextType | undefined>(undefined);
16+
17+
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
18+
const [user, setUser] = useState<User | null>(null);
19+
const [friendCode, setFriendCode] = useState<string | null>(null);
20+
21+
useEffect(() => {
22+
const unsubscribe = auth.onAuthStateChanged(async (user) => {
23+
setUser(user);
24+
if (user) {
25+
const friendCodeRef = ref(database, `users/${user.uid}/friendCode`);
26+
const snapshot = await get(friendCodeRef);
27+
if (snapshot.exists()) {
28+
setFriendCode(snapshot.val());
29+
}
30+
} else {
31+
setFriendCode(null);
32+
}
33+
});
34+
return unsubscribe;
35+
}, []);
36+
37+
const signUp = async (email: string, password: string, friendCode: string) => {
38+
const userCredential = await createUserWithEmailAndPassword(auth, email, password);
39+
await set(ref(database, `users/${userCredential.user.uid}/friendCode`), friendCode);
40+
setFriendCode(friendCode);
41+
};
42+
43+
const signIn = async (email: string, password: string) => {
44+
await signInWithEmailAndPassword(auth, email, password);
45+
};
46+
47+
const logOut = async () => {
48+
await signOut(auth);
49+
setFriendCode(null);
50+
};
51+
52+
const setFriendCodeForUser = async (code: string) => {
53+
if (user) {
54+
await set(ref(database, `users/${user.uid}/friendCode`), code);
55+
setFriendCode(code);
56+
}
57+
};
58+
59+
return (
60+
<AuthContext.Provider value={{ user, signUp, signIn, logOut, setFriendCode: setFriendCodeForUser, friendCode }}>
61+
{children}
62+
</AuthContext.Provider>
63+
);
64+
};
65+
66+
export const useAuth = () => {
67+
const context = useContext(AuthContext);
68+
if (context === undefined) {
69+
throw new Error('useAuth must be used within an AuthProvider');
70+
}
71+
return context;
72+
};

components/GlyphGenerator.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@
1717
import { Label } from "@/components/ui/label";
1818
import useEmblaCarousel from 'embla-carousel-react';
1919
import { ChevronLeft, ChevronRight } from 'lucide-react';
20+
import {useAuth} from "@/components/AuthProvider";
2021

2122
const glyphs = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
2223

@@ -182,6 +183,7 @@ const GlyphGenerator = () => {
182183
const [filterGalaxy, setFilterGalaxy] = useState('All');
183184
const [sortBy, setSortBy] = useState('votes');
184185
const [filteredGallery, setFilteredGallery] = useState<GalleryItem[]>([]);
186+
const { friendCode, setFriendCode } = useAuth();
185187

186188
useEffect(() => {
187189
const filtered = gallery.filter(item =>
@@ -363,7 +365,7 @@ const GlyphGenerator = () => {
363365
},
364366
description: description,
365367
tags: tags.split(',').map(tag => tag.trim()),
366-
creatorId: friendshipCode,
368+
creatorId: friendCode,
367369
images: imageUrls,
368370
galaxy: selectedGalaxy === "Not Specified" ? null : selectedGalaxy,
369371
createdAt: new Date().toISOString()

components/LoginForm.tsx

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import React, { useState } from 'react';
2+
import { useAuth } from './AuthProvider';
3+
import { Button } from "@/components/ui/button";
4+
import { Input } from "@/components/ui/input";
5+
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
6+
7+
const LoginForm: React.FC = () => {
8+
const [email, setEmail] = useState('');
9+
const [password, setPassword] = useState('');
10+
const [friendCode, setFriendCode] = useState('');
11+
const { signIn, signUp } = useAuth();
12+
13+
const handleSignIn = async (e: React.FormEvent) => {
14+
e.preventDefault();
15+
try {
16+
await signIn(email, password);
17+
} catch (error) {
18+
console.error('Failed to sign in', error);
19+
}
20+
};
21+
22+
const handleSignUp = async (e: React.FormEvent) => {
23+
e.preventDefault();
24+
try {
25+
await signUp(email, password, friendCode);
26+
} catch (error) {
27+
console.error('Failed to sign up', error);
28+
}
29+
};
30+
31+
return (
32+
<Tabs defaultValue="signin" className="w-[400px]">
33+
<TabsList className="grid w-full grid-cols-2">
34+
<TabsTrigger value="signin">Sign In</TabsTrigger>
35+
<TabsTrigger value="signup">Sign Up</TabsTrigger>
36+
</TabsList>
37+
<TabsContent value="signin">
38+
<form onSubmit={handleSignIn} className="space-y-4">
39+
<Input
40+
type="email"
41+
value={email}
42+
onChange={(e) => setEmail(e.target.value)}
43+
placeholder="Email"
44+
required
45+
/>
46+
<Input
47+
type="password"
48+
value={password}
49+
onChange={(e) => setPassword(e.target.value)}
50+
placeholder="Password"
51+
required
52+
/>
53+
<Button type="submit" className="w-full">Sign In</Button>
54+
</form>
55+
</TabsContent>
56+
<TabsContent value="signup">
57+
<form onSubmit={handleSignUp} className="space-y-4">
58+
<Input
59+
type="email"
60+
value={email}
61+
onChange={(e) => setEmail(e.target.value)}
62+
placeholder="Email"
63+
required
64+
/>
65+
<Input
66+
type="password"
67+
value={password}
68+
onChange={(e) => setPassword(e.target.value)}
69+
placeholder="Password"
70+
required
71+
/>
72+
<Input
73+
type="text"
74+
value={friendCode}
75+
onChange={(e) => setFriendCode(e.target.value)}
76+
placeholder="NMS Friend Code"
77+
required
78+
/>
79+
<Button type="submit" className="w-full">Sign Up</Button>
80+
</form>
81+
</TabsContent>
82+
</Tabs>
83+
);
84+
};
85+
86+
export default LoginForm;

0 commit comments

Comments
 (0)