Skip to content

Commit

Permalink
Merge pull request #53 from deepraj21/main
Browse files Browse the repository at this point in the history
updated chat section and model
  • Loading branch information
deepraj21 authored Oct 17, 2024
2 parents 6ef848e + 42b2192 commit 8d204b6
Show file tree
Hide file tree
Showing 24 changed files with 2,187 additions and 577 deletions.
1,298 changes: 1,236 additions & 62 deletions client/package-lock.json

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
"dependencies": {
"@hookform/resolvers": "^3.9.0",
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-avatar": "^1.1.1",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.2",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-navigation-menu": "^1.2.0",
"@radix-ui/react-scroll-area": "^1.2.0",
"@radix-ui/react-select": "^2.1.1",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-toast": "^1.2.1",
Expand All @@ -38,13 +40,15 @@
"react-dom": "^18.3.1",
"react-hook-form": "^7.52.1",
"react-icons": "^5.3.0",
"react-markdown": "^9.0.1",
"react-redux": "^9.1.2",
"react-router-dom": "^6.25.1",
"react-wrap-balancer": "^1.1.1",
"redux": "^5.0.1",
"sonner": "^1.5.0",
"tailwind-merge": "^2.4.0",
"tailwindcss-animate": "^1.0.7",
"typewriter-effect": "^2.21.0",
"vaul": "^0.9.1",
"zod": "^3.23.8"
},
Expand Down
44 changes: 5 additions & 39 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,52 +10,18 @@ import Home from './pages/Home';
import Profile from './pages/Profile';
import { Toaster } from "@/components/ui/sonner";

const backendUrl = import.meta.env.VITE_BACKEND_URL || 'http://localhost:5000';

const App: React.FC = () => {
const [authenticated, setAuthenticated] = useState(false);
const [username, setUsername] = useState<string | null>(null);

useEffect(() => {
const checkAuth = async () => {
try {
const response = await axios.get(`${backendUrl}/check_auth`, { withCredentials: true });
if (response.data.authenticated) {
setAuthenticated(true);
setUsername(response.data.username);
} else {
setAuthenticated(false);
}
} catch (error) {
console.error('Failed to check authentication status:', error);
}
};

checkAuth();
}, []);

const handleLogout = async () => {
try {
const response = await axios.get(`${backendUrl}/logout`, { withCredentials: true });
if (response.data.message === 'Logout successful') {
setAuthenticated(false);
setUsername(null);
}
} catch (error) {
console.error('Failed to logout:', error);
}
};

return (
<ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
<Router>
<Routes>
<Route path="/" element={authenticated ? <Navigate to="/home" /> : <Landing />} />
<Route path="/" element={<Landing />} />
<Route path="/signup" element={<Signup />} />
<Route path="/login" element={<Login onLoginSuccess={(username: string) => { setAuthenticated(true); setUsername(username); }} />} />
<Route path="/home" element={authenticated ? <Home onLogout={handleLogout} username={username || ''} /> : <Navigate to="/" />} />
<Route path="/u/:username" element={<Profile onLogout={handleLogout} username={username || ''} />} />
<Route path="*" element={<Navigate to="/" />} />
<Route path="/login" element={<Login />} />
<Route path="/home" element={<Home />} />
<Route path="/u/:username" element={<Profile />} />
<Route path="*" element={<div>404</div>} />
</Routes>
</Router>
<Toaster />
Expand Down
51 changes: 23 additions & 28 deletions client/src/components/Auth/user-auth-form-login.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
"use client";

import React, { useState } from 'react';
import axios from 'axios';
import { useNavigate } from 'react-router-dom';
import { toast } from "sonner";

Expand All @@ -13,11 +10,7 @@ import { Label } from "@/components/ui/label";

const backendUrl = import.meta.env.VITE_BACKEND_URL || 'http://localhost:5000';

interface UserAuthFormProps extends React.HTMLAttributes<HTMLDivElement> {
onLoginSuccess?: (username: string) => void;
}

export function UserAuthForm({ className, onLoginSuccess, ...props }: UserAuthFormProps) {
export function UserAuthForm() {
const [isLoading, setIsLoading] = useState<boolean>(false);
const [username, setUsername] = useState<string>('');
const [password, setPassword] = useState<string>('');
Expand All @@ -28,42 +21,44 @@ export function UserAuthForm({ className, onLoginSuccess, ...props }: UserAuthFo
setIsLoading(true);

try {
const response = await axios.post(`${backendUrl}/login`, { username, password }, { withCredentials: true });
if (response.status === 200) {
const response = await fetch(`${backendUrl}/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'include',
body: JSON.stringify({ username, password }),
});

if (response.ok) {
localStorage.setItem('devhub_username', username);

if (onLoginSuccess) {
onLoginSuccess(username);
}
navigate('/home');
}
} catch (err: any) {
if (err.response && err.response.data && err.response.data.message) {
toast.error(err.response.data.message, {
description: "Please check your details and try again.",
action: {
label: "Try again",
onClick: () => console.log("Try again clicked"),
},
});
} else {
toast.error("Login failed", {
description: "There was a problem with your request.",
const errorData = await response.json();
toast.error(errorData.message || "Login failed", {
description: "Please check your details and try again.",
action: {
label: "Try again",
onClick: () => console.log("Try again clicked"),
},
});
}
console.error('Login error:', err);
} catch (error) {
toast.error("Login failed", {
description: "There was a problem with your request.",
action: {
label: "Try again",
onClick: () => console.log("Try again clicked"),
},
});
console.error('Login error:', error);
} finally {
setIsLoading(false);
}
}

return (
<div className={cn("grid gap-6", className)} {...props}>
<div className={cn("grid gap-6")}>
<form onSubmit={onSubmit}>
<div className="grid gap-2">
<div className="grid gap-1">
Expand Down
68 changes: 34 additions & 34 deletions client/src/components/Auth/user-auth-form-signup.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use client";

import React, { useState, useEffect } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import { toast } from "sonner";

Expand All @@ -11,7 +10,7 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";

interface UserAuthFormProps extends React.HTMLAttributes<HTMLDivElement> {}
interface UserAuthFormProps extends React.HTMLAttributes<HTMLDivElement> { }
interface PasswordRules {
minLength: boolean;
containsUpper: boolean;
Expand All @@ -26,18 +25,15 @@ const backendUrl = import.meta.env.VITE_BACKEND_URL || "http://localhost:5000";
export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
const [isLoading, setIsLoading] = useState<boolean>(false);
const [username, setUsername] = useState<string>("");
const [isUsernameAvailable, setIsUsernameAvailable] = useState<
boolean | null
>(null);
const [isUsernameAvailable, setIsUsernameAvailable] = useState<boolean | null>(null);
const [email, setEmail] = useState<string>("");
const [password, setPassword] = useState<string>("");
const [usernameError, setUsernameError] = useState<string>("");
const [passwordRules, setPasswordRules] = useState<PasswordRules | null>(
null
);
const [passwordRules, setPasswordRules] = useState<PasswordRules | null>(null);
const [isPasswordValid, setIsPasswordValid] = useState<boolean>(false);
const navigate = useNavigate(); // Hook for navigation
const navigate = useNavigate();

// Username availability check with debounce
useEffect(() => {
const checkUsernameAvailability = async () => {
if (username) {
Expand All @@ -56,10 +52,10 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
return;
}
setUsernameError("");
const response = await axios.get(`${backendUrl}/check_username`, {
params: { username },
});
setIsUsernameAvailable(response.data.available);

const response = await fetch(`${backendUrl}/check_username?username=${username}`);
const data = await response.json();
setIsUsernameAvailable(data.available);
} catch (error) {
console.error("Error checking username availability:", error);
}
Expand All @@ -76,6 +72,7 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
return () => clearTimeout(delayDebounceFn);
}, [username]);

// Password validation rules
const validatePassword = (password: string): PasswordRules => {
return {
minLength: password.length >= 6,
Expand Down Expand Up @@ -107,6 +104,7 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
noWhitespace: "Should not contain spaces.",
};

// Form submission handler
async function onSubmit(event: React.SyntheticEvent) {
event.preventDefault();
setIsLoading(true);
Expand All @@ -116,34 +114,36 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
}

try {
await axios.post(`${backendUrl}/signup`, { username, email, password });
const response = await fetch(`${backendUrl}/signup`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ username, email, password }),
});

if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.message || "Signup failed");
}

toast.success("Signup successful", {
description: "You can now log in with your new account.",
action: {
label: "Login",
onClick: () => navigate("/login"),
},
});
navigate("/login"); // Redirect to login page on successful signup
} catch (err: any) {
if (err.response && err.response.data && err.response.data.message) {
toast.error(err.response.data.message, {
description: "Please check your details and try again.",
action: {
label: "Try again",
onClick: () => console.log("Try again clicked"),
},
});
} else {
toast.error("Signup failed", {
description: "There was a problem with your request.",
action: {
label: "Try again",
onClick: () => console.log("Try again clicked"),
},
});
}
console.error("Error during signup:", err);
navigate("/login");
} catch (error) {
toast.error(`Signup failed ${error}`, {
description: "Please check your details and try again.",
action: {
label: "Try again",
onClick: () => console.log("Try again clicked"),
},
});
console.error("Error during signup:", error);
} finally {
setIsLoading(false);
}
Expand Down
Loading

0 comments on commit 8d204b6

Please sign in to comment.