feat: implement client overview dashboard and admin portal structure with API services and page components
This commit is contained in:
@@ -4,6 +4,7 @@ import { useNavigate } from 'react-router-dom';
|
||||
import { useAuthStore } from '../../store/authStore';
|
||||
import { accountService } from '../../api/accountService';
|
||||
import { DbSelectionDialog } from './DbSelectionDialog';
|
||||
import { useToastStore } from '../../store/toastStore';
|
||||
|
||||
export const Login: React.FC = () => {
|
||||
const [username, setUsername] = useState('');
|
||||
@@ -11,8 +12,8 @@ export const Login: React.FC = () => {
|
||||
const [isInvalid, setIsInvalid] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [tempUserData, setTempUserData] = useState<any>(null);
|
||||
|
||||
const [tempLoginResult, setTempLoginResult] = useState<Awaited<ReturnType<typeof accountService.login>> | null>(null);
|
||||
|
||||
const { login, isAuthenticated } = useAuthStore();
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -26,53 +27,44 @@ export const Login: React.FC = () => {
|
||||
const handleLogin = async () => {
|
||||
setIsInvalid(false);
|
||||
setLoading(true);
|
||||
|
||||
|
||||
try {
|
||||
const userData = await accountService.login(username, password);
|
||||
|
||||
if (!userData) {
|
||||
const result = await accountService.login(username, password);
|
||||
|
||||
if (!result?.user) {
|
||||
setIsInvalid(true);
|
||||
useToastStore.getState().showToast('Invalid username or password.', 'error');
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const roles = userData.user_roles ? userData.user_roles.toLowerCase().split(',') : [];
|
||||
|
||||
if (roles.includes('sr_auditor')) {
|
||||
// Open DB Selection Dialog
|
||||
setTempUserData(userData);
|
||||
setDialogOpen(true);
|
||||
} else if (roles.includes('auditor')) {
|
||||
// Direct login
|
||||
login(userData);
|
||||
navigate('/activity-feeds', { replace: true });
|
||||
} else if (roles.includes('video_uploader')) {
|
||||
// Direct login for dashboard
|
||||
login(userData);
|
||||
navigate('/activity-feeds', { replace: true });
|
||||
} else {
|
||||
alert("Your account is not configured to use this website. Please contact your admin for more info.");
|
||||
}
|
||||
// Every user picks which org/DB to work in after login.
|
||||
setTempLoginResult(result);
|
||||
setDialogOpen(true);
|
||||
} catch (error) {
|
||||
setIsInvalid(true);
|
||||
useToastStore.getState().showToast('Invalid username or password.', 'error');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDbSelection = (selectedOrg?: any) => {
|
||||
const handleDbSelection = (selectedOrg?: { org_id: string; db_name: string; org_name?: string }) => {
|
||||
setDialogOpen(false);
|
||||
if (selectedOrg && tempUserData) {
|
||||
// Merge selected org details into user object
|
||||
const finalUserData = {
|
||||
...tempUserData,
|
||||
if (selectedOrg && tempLoginResult) {
|
||||
login({
|
||||
access_token: tempLoginResult.access_token,
|
||||
refresh_token: tempLoginResult.refresh_token,
|
||||
user_id: tempLoginResult.user.user_id,
|
||||
username: tempLoginResult.user.username,
|
||||
email: tempLoginResult.user.email,
|
||||
role: tempLoginResult.user.role_name,
|
||||
org_id: selectedOrg.org_id,
|
||||
db_name: selectedOrg.db_name,
|
||||
selected_org_name: selectedOrg.org_name
|
||||
};
|
||||
login(finalUserData);
|
||||
});
|
||||
navigate('/activity-feeds', { replace: true });
|
||||
}
|
||||
setTempLoginResult(null);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -206,7 +198,6 @@ export const Login: React.FC = () => {
|
||||
</Paper>
|
||||
</Container>
|
||||
|
||||
{/* Database Selection Dialog for SR_AUDITOR */}
|
||||
<DbSelectionDialog open={dialogOpen} onClose={handleDbSelection} />
|
||||
</Box>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user