Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 55 additions & 35 deletions src/components/AuthComponents/Login.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React, { useState } from 'react';
import { useNavigate} from 'react-router-dom';
import { Navigate, Link, useNavigate } from 'react-router-dom';
import { doSignInWithEmailAndPassword, doSignInWithGoogle } from '../../firebase/auth';

import { useAuth } from '../../contexts/authContext';
import { getApiUrl } from '../pages/createsteps helpers/CreateStepsUtils';

const Login = () => {
const { userLoggedIn } = useAuth();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isSigningIn, setIsSigningIn] = useState(false);
Expand Down Expand Up @@ -44,21 +46,32 @@ const Login = () => {
is_creator: true
};

const backendApiUrl = 'http://localhost:8000/users/'

const response = await fetch(backendApiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(backendUserData),
});

const responseData = await response.json();
if (!response.ok && response.status !== 400) {
throw new Error(responseData.detail || "Failed to sync user with backend.");
// If the user is created successfully, we also need to create a user profile in our backend
if (result.user) {
try {
const response = await fetch(`${getApiUrl()}/users/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(backendUserData),
});

const responseData = await response.json();
if (!response.ok && response.status !== 400) {
throw new Error(responseData.detail || "Failed to sync user with backend.");
}
navigate('/home'); // Redirect to home after successful sign-in
} catch (error) {
setErrorMessage(handleFirebaseError(error));
setIsSigningIn(false);
} finally {
setIsSigningIn(false);
setIsSyncing(false); // End sync process, allowing navigation to proceed if user is logged in
}
} else {
throw new Error("Could not get user details from Google Sign-In.");
}
navigate('/home'); // Redirect to home after successful sign-in
} else {
throw new Error("Could not get user details from Google Sign-In.");
}
Expand Down Expand Up @@ -88,42 +101,49 @@ const Login = () => {

return (
<div>
{userLoggedIn && (<Navigate to={'/home'} replace={true} />)}

<main className="w-full h-screen flex self-center place-content-center place-items-center">
<div className="w-96 text-gray-600 space-y-5 p-4 shadow-xl border rounded-xl">
<div className="text-center">
<div className="text-center mb-6">
<div className="mt-2">
<h3 className="text-gray-800 text-xl font-semibold sm:text-2xl">Welcome Back</h3>
</div>
</div>
<form onSubmit={onSubmit} className="space-y-5">
<form
onSubmit={onSubmit}
className="space-y-4"
>
<div>
<label className="text-sm text-gray-600 font-bold">Email</label>
<label className="text-sm text-gray-600 font-bold">
Email
</label>
<input
type="email"
autoComplete="email"
autoComplete='email'
required
value={email}
onChange={(e) => { setEmail(e.target.value) }}
className="w-full mt-2 px-3 py-2 text-gray-500 bg-transparent outline-none border focus:border-indigo-600 shadow-sm rounded-lg transition duration-300"
className="w-full mt-2 px-3 py-2 text-gray-500 bg-transparent outline-none border focus:border-indigo-600 shadow-sm rounded-lg"
/>
</div>

<div>
<label className="text-sm text-gray-600 font-bold">Password</label>
<label className="text-sm text-gray-600 font-bold">
Password
</label>
<input
type="password"
autoComplete="current-password"
autoComplete='current-password'
required
value={password}
onChange={(e) => { setPassword(e.target.value) }}
className="w-full mt-2 px-3 py-2 text-gray-500 bg-transparent outline-none border focus:border-indigo-600 shadow-sm rounded-lg transition duration-300"
className="w-full mt-2 px-3 py-2 text-gray-500 bg-transparent outline-none border focus:border-indigo-600 shadow-sm rounded-lg"
/>
</div>

{errorMessage && (
<div className='text-red-600 font-bold'>
{errorMessage}
</div>
<span className='text-red-600 font-bold'>{errorMessage}</span>
)}

<button
Expand All @@ -134,35 +154,35 @@ const Login = () => {
{isSigningIn ? 'Signing In...' : 'Sign In'}
</button>
</form>
{/* <p className="text-center text-sm">Don't have an account? <Link to={'/register'} className="hover:underline font-bold">Sign up</Link></p> */}
<p className="text-center text-sm">Don't have an account? <Link to={'/register'} className="hover:underline font-bold">Sign up</Link></p>
<div className='flex flex-row text-center w-full'>
<div className='border-b-2 mb-2.5 mr-2 w-full'></div>
<div className='text-sm font-bold w-fit'>OR</div>
<div className='border-b-2 mb-2.5 ml-2 w-full'></div>
</div>
<button
disabled={isSigningIn}
onClick={(e) => { onGoogleSignIn(e) }}
onClick={onGoogleSignIn}
className={`w-full flex items-center justify-center gap-x-3 py-2.5 border rounded-lg text-sm font-medium ${isSigningIn ? 'cursor-not-allowed' : 'hover:bg-gray-100 transition duration-300 active:bg-gray-100'}`}>
<svg className="w-5 h-5" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clipPath="url(#clip0_17_40)">
<path d="M47.532 24.5528C47.532 22.9214 47.3997 21.2811 47.1175 19.6761H24.48V28.9181H37.4434C36.9055 31.8988 35.177 34.5356 32.6461 36.2111V42.2078H40.3801C44.9217 38.0278 47.532 31.8547 47.532 24.5528Z" fill="#4285F4" />
<path d="M24.48 48.0016C30.9529 48.0016 36.4116 45.8764 40.3888 42.2078L32.6549 36.2111C30.5031 37.675 27.7252 38.5039 24.4888 38.5039C18.2275 38.5039 12.9187 34.2798 11.0139 28.6006H3.03296V34.7825C7.10718 42.8868 15.4056 48.0016 24.48 48.0016Z" fill="#34A853" />
<path d="M11.0051 28.6006C9.99973 25.6199 9.99973 22.3922 11.0051 19.4115V13.2296H3.03298C-0.371021 20.0112 -0.371021 28.0009 3.03298 34.7825L11.0051 28.6006Z" fill="#FBBC04" />
<path d="M24.48 9.49932C27.9016 9.44641 31.2086 10.7339 33.6866 13.0973L40.5387 6.24523C36.2 2.17101 30.4414 -0.068932 24.48 0.00161733C15.4055 0.00161733 7.10718 5.11644 3.03296 13.2296L11.005 19.4115C12.901 13.7235 18.2187 9.49932 24.48 9.49932Z" fill="#EA4335" />
<path d="M47.532 24.5528C47.532 22.9214 47.3997 21.2811 47.1175 19.6761H24.48V28.9181H37.4434C36.9055 31.8988 35.177 34.5356 32.6461 36.2111V42.2078H40.3801C44.9217 38.0239 47.532 31.8547 47.532 24.5528Z" fill="#4285F4" />
<path d="M24.48 48.0001C31.0212 48.0001 36.5663 45.6936 40.3801 42.2078L32.6461 36.2111C30.2241 37.8099 27.5212 38.7944 24.48 38.7944C18.6744 38.7944 13.7223 35.1411 11.9341 29.8936H3.92383V36.0278C7.79283 43.6366 15.5348 48.0001 24.48 48.0001Z" fill="#34A853" />
<path d="M11.9341 29.8936C11.5284 28.7099 11.2344 27.4488 11.2344 26.1361C11.2344 24.8234 11.5284 23.5623 11.9341 22.3786V16.2444H3.92383C2.43483 19.0499 1.52441 22.4778 1.52441 26.1361C1.52441 29.7944 2.43483 33.2223 3.92383 36.0278L11.9341 29.8936Z" fill="#FBBC05" />
<path d="M24.48 9.47781C28.0927 9.47781 31.3934 10.7061 33.9822 13.2044L40.5612 6.6423C36.5574 2.94909 31.0212 0.45459 24.48 0.45459C15.5348 0.45459 7.79283 4.81809 3.92383 12.4269L11.9341 18.5611C13.7223 13.3136 18.6744 9.47781 24.48 9.47781Z" fill="#EA4335" />
</g>
<defs>
<clipPath id="clip0_17_40">
<rect width="48" height="48" fill="white" />
</clipPath>
</defs>
</svg>
{isSigningIn ? 'Signing In...' : 'Continue with Google'}
Continue with Google
</button>
</div>
</main>
</div>
)
}

export default Login;
export default Login
6 changes: 3 additions & 3 deletions src/components/AuthComponents/Register.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { useState } from 'react';
import { Navigate, Link} from 'react-router-dom';
import { useAuth } from '../../contexts/authContext';
import { doCreateUserWithEmailAndPassword } from '../../firebase/auth';
import { doCreateUserWithEmailAndPassword, doSignInWithGoogle } from '../../firebase/auth';
import { getApiUrl } from '../pages/createsteps helpers/CreateStepsUtils';

const Register = () => {
const { userLoggedIn } = useAuth();
const { userLoggedIn, currentUser } = useAuth();

const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
Expand Down Expand Up @@ -49,7 +50,6 @@ const Register = () => {
console.log('Sending user data to backend:', backendUserData);

// Use consistent API URL helper
const getApiUrl = () => process.env.REACT_APP_API_URL || 'http://localhost:8000';
const backendApiUrl = `${getApiUrl()}/users/`;

const response = await fetch(backendApiUrl, {
Expand Down
4 changes: 3 additions & 1 deletion src/components/Layout/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useAuth } from '../../contexts/authContext';
import { doSignOut } from '../../firebase/auth';
import { AiOutlineMenu, AiOutlineLogout, AiFillTool, AiOutlineVideoCamera as AiOutlineVideo, AiOutlineEye, AiOutlineArrowLeft, AiOutlineCheck, AiOutlineUser, AiOutlineDatabase, AiOutlineFolder, AiOutlineBarChart } from 'react-icons/ai';
import logo from '../../assets/trvise_logo.png';
import { getApiUrl } from '../pages/createsteps helpers/CreateStepsUtils';

// Chrome detection
const isChrome = typeof window !== 'undefined' && /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
Expand Down Expand Up @@ -51,7 +52,8 @@ const Sidebar = ({ isCollapsed, toggleSidebar, animateLogo }) => {
if (!currentUser?.uid) return;

try {
const response = await fetch(`${process.env.REACT_APP_API_URL || 'http://localhost:8000'}/users/${currentUser.uid}`);
const apiUrl = getApiUrl();
const response = await fetch(`${apiUrl}/users/${currentUser.uid}`);
if (response.ok) {
const data = await response.json();
setProfileData(data);
Expand Down
12 changes: 5 additions & 7 deletions src/components/authoring/MaterialsAndFilesTab.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import React, { useState, useEffect, useCallback } from 'react';
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { useAuth } from '../../contexts/authContext';
import { storage } from '../../firebase/firebase'; // Fixed import path
import { ref, uploadBytes } from 'firebase/storage'; // Added import for Firebase storage functions

import { COMPONENTS, TYPOGRAPHY, LAYOUT, getListItemBorder } from './shared/styles';
import { AiOutlineSearch, AiOutlinePlus } from 'react-icons/ai';
import { getApiUrl } from '../pages/createsteps helpers/CreateStepsUtils';

// Import the getApiUrl function to match the existing codebase pattern
const getApiUrl = () => {
return process.env.REACT_APP_API_URL || 'http://localhost:8000';
};
// No local getApiUrl function

const MaterialsAndToolsTab = ({
const MaterialsAndFilesTab = ({
// Tools props
currentStepTools,
currentStepToolName,
Expand Down Expand Up @@ -1203,4 +1201,4 @@ const MaterialsAndToolsTab = ({
);
};

export default MaterialsAndToolsTab;
export default MaterialsAndFilesTab;
7 changes: 2 additions & 5 deletions src/components/authoring/RepositoryPanel.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import React, { useState, useEffect, useCallback } from 'react';
import { useAuth } from '../../contexts/authContext';
import { AiOutlinePlus, AiOutlineSearch, AiOutlineEdit, AiOutlineDelete, AiOutlineClose, AiOutlineUpload } from 'react-icons/ai';
import { uploadFileToFirebase } from '../pages/createsteps helpers/CreateStepsUtils';
import { uploadFileToFirebase, getApiUrl } from '../pages/createsteps helpers/CreateStepsUtils';
import { repositoryStyles } from '../pages/Repository.styles';

// Import the getApiUrl function to match the existing codebase pattern
const getApiUrl = () => {
return process.env.REACT_APP_API_URL || 'http://localhost:8000';
};
// No local getApiUrl function

const RepositoryPanel = ({ contextType = 'main', onAddToStep, onAddToBuyList }) => {
const { currentUser } = useAuth();
Expand Down
5 changes: 1 addition & 4 deletions src/components/authoring/RepositoryTab.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import React, { useState, useEffect, useCallback } from 'react';
import { useAuth } from '../../contexts/authContext';
import { AiOutlinePlus, AiOutlineSearch, AiOutlineClose } from 'react-icons/ai';
import { getApiUrl } from '../pages/createsteps helpers/CreateStepsUtils.js';

// Import the getApiUrl function to match the existing codebase pattern
const getApiUrl = () => {
return process.env.REACT_APP_API_URL || 'http://localhost:8000';
};

const RepositoryTab = () => {
const { currentUser } = useAuth();
Expand Down
2 changes: 1 addition & 1 deletion src/components/pages/MyProjects.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState, useEffect, useCallback } from 'react';
import { useAuth } from '../../contexts/authContext';
import { useNavigate, useLocation } from 'react-router-dom';
import { isImageUrl, isVideoUrl, formatDate, createApiCall } from './createsteps helpers/CreateStepsUtils';
import { isImageUrl, isVideoUrl, formatDate, createApiCall, getApiUrl } from './createsteps helpers/CreateStepsUtils';
import { LazyImage, VideoThumbnail } from './createsteps helpers/CommonComponents';

const responsiveGridCSS = `
Expand Down
3 changes: 2 additions & 1 deletion src/components/pages/createsteps helpers/CreateStepsUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export const formatDate = (dateString) => {

// API utility functions
export const getApiUrl = () => {
return process.env.REACT_APP_API_URL || 'http://localhost:8000';
// Always return the production URL, ignoring any local environment variables.
return 'https://pbsggxqwqp.us-east-1.awsapprunner.com';
};

export const createApiCall = async (endpoint, options = {}) => {
Expand Down
Loading