Skip to content

Commit

Permalink
Merge pull request #1 from Quinta0/userlogin
Browse files Browse the repository at this point in the history
Lets try this user login
  • Loading branch information
Quinta0 authored Aug 22, 2024
2 parents 98c48f0 + c0129b7 commit b4b333c
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 18 deletions.
46 changes: 29 additions & 17 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,39 @@ import dynamic from 'next/dynamic'
import Head from "next/head";
import Link from "next/link";
import {Button} from "@/components/ui/button";
import { useAuth } from '@/components/AuthProvider';
import LoginForm from "@/components/LoginForm";


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

export default function Home() {
return (
<>
<Head>
<title>No Man's Sky Portal Address Tool</title>
<link rel="icon" href="/favicon.ico" sizes="any"/>
<meta name="description" content="Generate and share portal addresses for No Man's Sky"/>
</Head>
<div className="min-h-screen flex flex-col">
<Header/>
<main className="flex-grow container mx-auto px-4 py-8">
<div className="mb-4 flex justify-center items-center text-center">
<Link href="/info" className="text-blue-600 hover:underline">
Got questions?
</Link>
</div>
<GlyphGenerator/>
</main>
const { user, logOut } = useAuth();

return (
<>
<Head>
<title>No Man's Sky Portal Address Tool</title>
<link rel="icon" href="/favicon.ico" sizes="any"/>
<meta name="description" content="Generate and share portal addresses for No Man's Sky"/>
</Head>
<div className="min-h-screen flex flex-col">
<Header/>
<main className="flex-grow container mx-auto px-4 py-8">
<div className="mb-4 flex justify-center items-center text-center">
<Link href="/info" className="text-blue-600 hover:underline">
Got questions?
</Link>
</div>
{user ? (
<>
<Button onClick={logOut} className="mb-4">Log Out</Button>
<GlyphGenerator/>
</>
) : (
<LoginForm />
)}
</main>
<footer className="bg-muted text-muted-foreground py-6">
<div
className="container mx-auto px-4 md:px-6 flex flex-col sm:flex-row items-center justify-between">
Expand Down
72 changes: 72 additions & 0 deletions components/AuthProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React, { createContext, useContext, useEffect, useState } from 'react';
import { auth, database } from '@/firebaseConfig';
import { User, createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut } from 'firebase/auth';
import { ref, set, get } from 'firebase/database';

interface AuthContextType {
user: User | null;
signUp: (email: string, password: string, friendCode: string) => Promise<void>;
signIn: (email: string, password: string) => Promise<void>;
logOut: () => Promise<void>;
setFriendCode: (code: string) => Promise<void>;
friendCode: string | null;
}

const AuthContext = createContext<AuthContextType | undefined>(undefined);

export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [user, setUser] = useState<User | null>(null);
const [friendCode, setFriendCode] = useState<string | null>(null);

useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(async (user) => {
setUser(user);
if (user) {
const friendCodeRef = ref(database, `users/${user.uid}/friendCode`);
const snapshot = await get(friendCodeRef);
if (snapshot.exists()) {
setFriendCode(snapshot.val());
}
} else {
setFriendCode(null);
}
});
return unsubscribe;
}, []);

const signUp = async (email: string, password: string, friendCode: string) => {
const userCredential = await createUserWithEmailAndPassword(auth, email, password);
await set(ref(database, `users/${userCredential.user.uid}/friendCode`), friendCode);
setFriendCode(friendCode);
};

const signIn = async (email: string, password: string) => {
await signInWithEmailAndPassword(auth, email, password);
};

const logOut = async () => {
await signOut(auth);
setFriendCode(null);
};

const setFriendCodeForUser = async (code: string) => {
if (user) {
await set(ref(database, `users/${user.uid}/friendCode`), code);
setFriendCode(code);
}
};

return (
<AuthContext.Provider value={{ user, signUp, signIn, logOut, setFriendCode: setFriendCodeForUser, friendCode }}>
{children}
</AuthContext.Provider>
);
};

export const useAuth = () => {
const context = useContext(AuthContext);
if (context === undefined) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
};
4 changes: 3 additions & 1 deletion components/GlyphGenerator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@
import { Label } from "@/components/ui/label";
import useEmblaCarousel from 'embla-carousel-react';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import {useAuth} from "@/components/AuthProvider";

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

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

useEffect(() => {
const filtered = gallery.filter(item =>
Expand Down Expand Up @@ -363,7 +365,7 @@ const GlyphGenerator = () => {
},
description: description,
tags: tags.split(',').map(tag => tag.trim()),
creatorId: friendshipCode,
creatorId: friendCode,
images: imageUrls,
galaxy: selectedGalaxy === "Not Specified" ? null : selectedGalaxy,
createdAt: new Date().toISOString()
Expand Down
86 changes: 86 additions & 0 deletions components/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React, { useState } from 'react';
import { useAuth } from './AuthProvider';
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";

const LoginForm: React.FC = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [friendCode, setFriendCode] = useState('');
const { signIn, signUp } = useAuth();

const handleSignIn = async (e: React.FormEvent) => {
e.preventDefault();
try {
await signIn(email, password);
} catch (error) {
console.error('Failed to sign in', error);
}
};

const handleSignUp = async (e: React.FormEvent) => {
e.preventDefault();
try {
await signUp(email, password, friendCode);
} catch (error) {
console.error('Failed to sign up', error);
}
};

return (
<Tabs defaultValue="signin" className="w-[400px]">
<TabsList className="grid w-full grid-cols-2">
<TabsTrigger value="signin">Sign In</TabsTrigger>
<TabsTrigger value="signup">Sign Up</TabsTrigger>
</TabsList>
<TabsContent value="signin">
<form onSubmit={handleSignIn} className="space-y-4">
<Input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
required
/>
<Input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
required
/>
<Button type="submit" className="w-full">Sign In</Button>
</form>
</TabsContent>
<TabsContent value="signup">
<form onSubmit={handleSignUp} className="space-y-4">
<Input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
required
/>
<Input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
required
/>
<Input
type="text"
value={friendCode}
onChange={(e) => setFriendCode(e.target.value)}
placeholder="NMS Friend Code"
required
/>
<Button type="submit" className="w-full">Sign Up</Button>
</form>
</TabsContent>
</Tabs>
);
};

export default LoginForm;

0 comments on commit b4b333c

Please sign in to comment.