🚀 Final: Fix stats, staff list, settings profile, and logout redirect

This commit is contained in:
Hamza-Ayed
2026-04-19 15:36:45 +03:00
parent 946c7db96c
commit 3ae3f1d797
5 changed files with 43 additions and 11 deletions

View File

@@ -62,6 +62,16 @@ export class AuthController {
return this.authService.logout(user.id);
}
/**
* الملف الشخصي الحالي والبيانات الأساسية
*/
@UseGuards(JwtAuthGuard)
@Get('me')
@HttpCode(HttpStatus.OK)
async me(@CurrentUser() user: any) {
return this.authService.getMe(user.id);
}
/**
* الملف الشخصي
*/

View File

@@ -179,6 +179,29 @@ export class AuthService {
};
}
/**
* الحصول على بيانات المستخدم والاشتراك الحالي
*/
async getMe(userId: string) {
const user = await this.dataSource.getRepository(User).findOne({
where: { id: userId },
relations: ['tenant'],
});
if (!user) throw new UnauthorizedException();
return {
user: {
id: user.id,
name: user.name,
email: user.email,
role: user.role,
tenantId: user.tenant_id,
},
tenant: user.tenant,
};
}
/**
* تسجيل خروج
*/

View File

@@ -22,13 +22,6 @@ export class DashboardService {
where: { tenant_id: tenantId, status: InvoiceStatus.APPROVED },
});
const pendingInvoices = await this.invoiceRepository.count({
where: {
tenant_id: tenantId,
status: Buffer.from('approved').toString() === InvoiceStatus.APPROVED ? InvoiceStatus.UPLOADED : InvoiceStatus.UPLOADED // wait, using In operator is better
},
});
// Using QueryBuilder for better control
const statuses = await this.invoiceRepository
.createQueryBuilder('invoice')

View File

@@ -4,7 +4,7 @@
* ════════════════════════════════════════════════════════════
*/
import { NavLink } from 'react-router-dom';
import { NavLink, useNavigate } from 'react-router-dom';
import {
LayoutDashboard,
FileText,
@@ -24,8 +24,14 @@ const menuItems = [
];
export const Sidebar = () => {
const navigate = useNavigate();
const clearAuth = useAuthStore((state) => state.clearAuth);
const handleLogout = () => {
clearAuth();
navigate('/login');
};
return (
<aside className="w-64 h-screen glass border-l border-slate-200 sticky top-0 flex flex-col p-4">
<div className="flex items-center gap-3 px-2 py-6">
@@ -58,7 +64,7 @@ export const Sidebar = () => {
<div className="pt-4 border-t border-slate-100">
<button
onClick={clearAuth}
onClick={handleLogout}
className="flex items-center gap-3 px-4 py-3 w-full rounded-xl text-red-500 hover:bg-red-50 transition-all group"
>
<LogOut className="w-5 h-5 group-hover:-translate-x-1 transition-transform" />

View File

@@ -40,7 +40,7 @@ export const StaffPage = () => {
e.preventDefault();
try {
await apiClient.post('/users', {
full_name: fullName,
name: fullName,
email,
password,
role
@@ -108,7 +108,7 @@ export const StaffPage = () => {
</div>
</div>
<h3 className="text-xl font-bold text-slate-900 mb-1">{member.full_name}</h3>
<h3 className="text-xl font-bold text-slate-900 mb-1">{member.name}</h3>
<div className="flex items-center gap-2 mb-6">
<span className={`text-[10px] font-black uppercase tracking-widest px-2 py-0.5 rounded-md ${
member.role === 'admin' ? 'bg-indigo-50 text-indigo-600' : 'bg-slate-50 text-slate-600'