/** ========= REACT & REACT ROUTER ========= */
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
/** ========= MUI ========= */
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Checkbox from '@mui/material/Checkbox';
import CircularProgress from '@mui/material/CircularProgress';
import Divider from '@mui/material/Divider';
import FormControlLabel from '@mui/material/FormControlLabel';
import Grid from '@mui/material/Grid';
import Paper from '@mui/material/Paper';
import Stack from '@mui/material/Stack';
import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
/** ========= MISC ========= */
import LoadingComp from '../components/LoadingComp';
import PageWrapper from '../components/PageWrapper';
import { useAuth } from '../contexts/useAuth';
import { useFeedback } from '../contexts/useFeedback';
import { db } from '../data/Firebase';
import { doc, setDoc } from 'firebase/firestore';
/** Define out here because we don't need to re-define on re-render. */
const defaultAvailability = [
{ day: 'Mon', from: '09:00', to: '17:00', active: false },
{ day: 'Tue', from: '09:00', to: '17:00', active: false },
{ day: 'Wed', from: '09:00', to: '17:00', active: false },
{ day: 'Thu', from: '09:00', to: '17:00', active: false },
{ day: 'Fri', from: '09:00', to: '17:00', active: false },
{ day: 'Sat', from: '10:00', to: '14:00', active: false },
{ day: 'Sun', from: '10:00', to: '14:00', active: false },
];
export default function Profile() {
const { user, userData, loading } = useAuth();
const { setFeedback } = useFeedback();
const navigate = useNavigate();
const [tradingSkill, setTradingSkill] = useState('');
const [phoneNumber, setPhoneNumber] = useState('');
const [availability, setAvailability] = useState(defaultAvailability);
const [profileLoading, setProfileLoading] = useState(false);
useEffect(() => {
if (!loading && (!user || !userData)) {
navigate('/');
return;
}
if (userData?.profile) {
const profile = userData.profile;
if (profile.tradingSkill) setTradingSkill(profile.tradingSkill);
if (profile.phoneNumber) setPhoneNumber(profile.phoneNumber);
if (profile.availability) setAvailability(profile.availability);
}
}, [loading, user, userData, navigate]);
const updateSlot = (index, key, value) => {
const updated = [...availability];
updated[index][key] = value;
setAvailability(updated);
};
const handleSave = async (e) => {
e.preventDefault();
if (!user) return;
setProfileLoading(true);
try {
const userRef = doc(db, 'users', user.uid);
await setDoc(
userRef,
{ profile: { tradingSkill, phoneNumber, availability } },
{ merge: true }
);
setFeedback('Profile saved successfully!', 'success');
} catch (err) {
console.error(err);
setFeedback('Error saving profile!', 'error');
} finally {
setProfileLoading(false);
}
};
if (loading || !userData) return <LoadingComp />;
return (
<PageWrapper>
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'flex-start',
minHeight: 'calc(100vh - 180px)',
mt: 6,
width: '100%',
}}
>
<Paper
elevation={6}
sx={{
p: 4,
borderRadius: 3,
width: '100%',
maxWidth: '800px',
backgroundColor: (theme) =>
theme.palette.mode === 'dark'
? 'rgba(18,25,35,0.9)'
: 'rgba(255,255,255,0.95)',
border: (theme) =>
theme.palette.mode === 'dark'
? '1px solid rgba(0,229,255,0.3)'
: '1px solid rgba(0,0,0,0.1)',
boxShadow: (theme) =>
theme.palette.mode === 'dark'
? '0 0 25px rgba(0,229,255,0.2)'
: '0 0 15px rgba(0,0,0,0.1)',
}}
>
<Typography
variant="h4"
fontWeight={700}
textAlign="center"
sx={{
mb: 3,
color: (theme) =>
theme.palette.mode === 'dark' ? '#00e5ff' : '#1565c0',
textShadow: (theme) =>
theme.palette.mode === 'dark'
? '0 0 10px rgba(0,229,255,0.6)'
: '0 0 6px rgba(25,118,210,0.4)',
}}
>
Profile
</Typography>
<Divider
sx={{
mb: 4,
borderColor: (theme) =>
theme.palette.mode === 'dark'
? 'rgba(0,229,255,0.3)'
: 'rgba(0,0,0,0.1)',
}}
/>
<form onSubmit={handleSave}>
{/* Account Section */}
<Box sx={{ mb: 4 }}>
<Typography variant="h6" fontWeight={600} sx={{ mb: 1 }}>
Account
</Typography>
<TextField
fullWidth
label="Google Account Name"
value={user.displayName || ''}
InputProps={{ readOnly: true }}
/>
</Box>
{/* Contact Section */}
<Box sx={{ mb: 4 }}>
<Typography variant="h6" fontWeight={600} sx={{ mb: 1 }}>
Contact
</Typography>
<TextField
fullWidth
label="Phone Number"
value={phoneNumber}
onChange={(e) => setPhoneNumber(e.target.value)}
/>
</Box>
{/* Skill Section */}
<Box sx={{ mb: 4 }}>
<Typography variant="h6" fontWeight={600} sx={{ mb: 1 }}>
Skill You Are Trading
</Typography>
<TextField
fullWidth
label="Skill"
value={tradingSkill}
onChange={(e) => setTradingSkill(e.target.value)}
/>
</Box>
{/* Availability Section */}
<Box sx={{ mb: 4 }}>
<Typography variant="h6" fontWeight={600} sx={{ mb: 1 }}>
Availability
</Typography>
<Typography variant="body2" sx={{ mb: 2 }}>
Select the days you are available and set your time range.
</Typography>
<Stack spacing={1}>
{availability.map((slot, index) => (
<Grid
container
key={slot.day}
alignItems="center"
spacing={2}
sx={{
p: 1,
borderRadius: 2,
backgroundColor: (theme) =>
theme.palette.mode === 'dark'
? 'rgba(255,255,255,0.05)'
: 'rgba(0,0,0,0.03)',
}}
>
<Grid item xs={3}>
<FormControlLabel
control={
<Checkbox
checked={slot.active}
onChange={(e) =>
updateSlot(index, 'active', e.target.checked)
}
/>
}
label={slot.day}
/>
</Grid>
<Grid item xs={4}>
<TextField
type="time"
size="small"
value={slot.from}
onChange={(e) =>
updateSlot(index, 'from', e.target.value)
}
sx={{ width: '140px' }}
/>
</Grid>
<Grid item xs={1} textAlign="center">
<Typography>to</Typography>
</Grid>
<Grid item xs={4}>
<TextField
type="time"
size="small"
value={slot.to}
onChange={(e) =>
updateSlot(index, 'to', e.target.value)
}
sx={{ width: '140px' }}
/>
</Grid>
</Grid>
))}
</Stack>
</Box>
{/* Save Button */}
<Box textAlign="center">
<Button
type="submit"
variant="contained"
disabled={profileLoading}
sx={{
px: 4,
py: 1.3,
fontWeight: 600,
borderRadius: 2,
background: (theme) =>
theme.palette.mode === 'dark'
? 'linear-gradient(90deg, #00e5ff, #00bcd4)'
: 'linear-gradient(90deg, #1565c0, #42a5f5)',
'&:hover': {
transform: 'scale(1.05)',
boxShadow: (theme) =>
theme.palette.mode === 'dark'
? '0 0 15px rgba(0,229,255,0.6)'
: '0 0 10px rgba(25,118,210,0.4)',
},
}}
>
{profileLoading ? (
<CircularProgress size={24} />
) : (
'Save Profile'
)}
</Button>
</Box>
</form>
</Paper>
</Box>
</PageWrapper>
);
}