Skip to content

Commit

Permalink
feat: Revamped layout with improved UX/UI for Financial Tracker app
Browse files Browse the repository at this point in the history
Home Component:
- Redesigned hero section: Added a high-quality background image with dark overlay for better text contrast, updated typography for title and subtitle to improve readability.
- Updated feature cards: Implemented hover effects for better interactivity, added consistent image sizes (800x533) to maintain uniformity across the cards, and applied shadow effects for visual depth.
- Enhanced carousel: Improved design with clear, modern captions and smooth transitions. The carousel now handles testimonials with better spacing and readability.
- Improved call-to-action: Brightened the CTA section with a bolder primary color and refined button hover effects for better user interaction.
- Mobile responsiveness: Ensured proper scaling and responsive design using Bootstrap grid system for a seamless experience across devices.

Nav Component:
- Streamlined navigation: Simplified the navbar by aligning user icons and notification icons. Improved spacing and alignment for consistency between desktop and mobile views.
- Added sidebar toggle functionality: Sidebar now opens and closes responsively, with proper transitions and spacing.
- UI enhancements: Adjusted icon placements and hover effects for a cleaner, more intuitive navigation experience.

Dashboard Component:
- Enhanced summary cards: Improved the design of dashboard cards by adding hover effects, consistent color schemes, and clearer financial metrics display.
- Fixed chart responsiveness: Addressed issues with charts not scaling properly in responsive mode, ensuring better readability on smaller screens.
- Updated layout: Reorganized dashboard elements for better visual hierarchy, making financial data easier to understand and more accessible.
- Improved styling: Applied a modern and clean color scheme to all charts, tables, and key financial figures for enhanced clarity and user experience.
  • Loading branch information
Pedrolustosa committed Oct 13, 2024
1 parent e07426a commit 0fc11d4
Show file tree
Hide file tree
Showing 29 changed files with 542 additions and 227 deletions.
2 changes: 1 addition & 1 deletion Back/FinanceTracker.API/Data/MessageRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public void DeleteMessage(Message message)
return await context.Messages.FindAsync(id);
}

public async Task<Group?> GetMessageGroup(string groupName)
public async Task<Group> GetMessageGroup(string groupName)
{
return await context.Groups.Include(x => x.Connections)
.FirstOrDefaultAsync(x => x.Name == groupName);
Expand Down
3 changes: 1 addition & 2 deletions Back/FinanceTracker.API/Entities/Group.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ public class Group
{
[Key]
public required string Name { get; set; }

public ICollection<Connection> Connections { get; set; }
public ICollection<Connection> Connections { get; set; } = [];
}
}
2 changes: 1 addition & 1 deletion Back/FinanceTracker.API/SignalR/MessageHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class MessageHub(IUnitOfWork unitOfWork, IMapper mapper, IHubContext<Pres
public override async Task OnConnectedAsync()
{
var httpContext = Context.GetHttpContext();
var otherUser = httpContext.Request.Query["user"];
var otherUser = httpContext?.Request.Query["user"];
if (Context.User == null || string.IsNullOrEmpty(otherUser)) throw new Exception("Cannot join group");
var groupName = GetGroupName(Context.User.GetUsername(), otherUser);
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
Expand Down
Binary file modified Back/FinanceTracker.API/financetracker.db
Binary file not shown.
4 changes: 3 additions & 1 deletion Front/FinanceTracker.Client/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
"node_modules/ngx-toastr/toastr.css",
"src/styles.css"
],
"scripts": []
"scripts": [
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
]
},
"configurations": {
"production": {
Expand Down
1 change: 1 addition & 0 deletions Front/FinanceTracker.Client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Front/FinanceTracker.Client/src/app/_guards/auth.guard.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { inject } from '@angular/core';
import { CanActivateFn } from '@angular/router';
import { CanActivateFn, Router } from '@angular/router';
import { AccountService } from '../_services/account.service';
import { ToastrService } from 'ngx-toastr';

export const authGuard: CanActivateFn = (route, state) => {
const accountService = inject(AccountService);
const toastr = inject(ToastrService);
const router = inject(Router);

if (accountService.currentUser()) {
return true;
} else {
toastr.error('You shall not pass!');
router.navigate(['/']);
return false;
}
};
124 changes: 118 additions & 6 deletions Front/FinanceTracker.Client/src/app/_shared/nav/nav.component.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,121 @@
.dropdown-toggle, .dropdown-item{
cursor: pointer;
/* Navbar estilos */
.navbar {
background-color: #ffffff;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
z-index: 1030;
}

img{
max-height: 50px;
border: 2px solid white;
display: inline;
.navbar-brand {
display: flex;
align-items: center; /* Alinha o ícone da logo e o nome */
}

.logo-img {
max-height: 40px;
}

/* Ícone de notificação (sino) visível apenas no modo desktop */
.navbar-nav .fa-bell {
font-size: 1.5rem;
display: flex;
align-items: center;
}

/* Ícone de notificação visível no modo responsivo */
.d-lg-none .fa-bell {
font-size: 1.5rem;
margin-left: 10px;
}

/* Nome do sistema visível apenas no desktop */
.navbar-brand span {
font-size: 1.25rem;
font-weight: bold;
color: #333;
}

/* Estilo geral para manter os ícones alinhados na navbar */
.navbar-nav {
display: flex;
align-items: center;
margin-left: auto;
}

.navbar-toggler {
border: none;
padding: 0.25rem 0.75rem;
}

/* Sidebar estilos */
.sidebar {
width: 250px;
height: 100vh;
position: fixed;
top: 70px; /* Começa logo abaixo do navbar */
left: -250px;
z-index: 1020;
transition: left 0.3s ease-in-out;
background-color: #ff7a22;
}

.sidebar-open {
left: 0;
}

.sidebar-header {
display: flex;
justify-content: flex-end;
padding: 1rem;
}

.sidebar .nav-link {
padding: 15px;
font-size: 1rem;
transition: background-color 0.3s;
}

.sidebar .nav-link:hover {
background-color: rgba(255, 255, 255, 0.1);
}

.active-link {
background-color: rgba(255, 255, 255, 0.2);
border-right: 4px solid #1abc9c;
}

.nav-item i {
font-size: 1.2rem;
}

/* Exibição do sidebar em telas maiores */
@media (min-width: 992px) {
.sidebar {
left: 0;
top: 70px;
}
.sidebar-header {
display: none;
}
}

/* Estilos responsivos */
@media (max-width: 992px) {
.navbar .navbar-brand {
font-size: 1.1rem;
}

.form-control {
display: none;
}

.sidebar {
left: -250px;
top: 0;
height: 100%;
z-index: 1040;
}

.sidebar-open {
left: 0;
}
}
136 changes: 95 additions & 41 deletions Front/FinanceTracker.Client/src/app/_shared/nav/nav.component.html
Original file line number Diff line number Diff line change
@@ -1,51 +1,105 @@
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-primary">
<div class="container">
<a class="navbar-brand" routerLink="/" routerLinkActive="active">Dating App</a>
<!-- Navbar fixa no topo -->
<nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm fixed-top">
<div class="container-fluid d-flex align-items-center justify-content-between">

<!-- Botão de abrir o sidebar no modo responsivo -->
<button class="navbar-toggler d-lg-none me-3" type="button" (click)="toggleSidebar()">
<i class="fas fa-bars"></i>
</button>

<ul class="navbar-nav me-auto mb-2 mb-md-0">
@if (accountService.currentUser()) {
<li class="nav-item">
<a routerLink="/members" routerLinkActive="active" class="nav-link">Matches</a>
<!-- Ícone do sistema e nome exibidos corretamente conforme o modo -->
<div class="d-flex align-items-center">
<a class="navbar-brand d-flex align-items-center" routerLink="/">
<img src="../../../assets/financa.png" alt="Financial Tracker Logo" class="logo-img">
<span class="d-none d-lg-inline ms-2">Financial Tracker</span> <!-- Nome aparece apenas no desktop -->
</a>
<!-- Ícone de notificação (sino) visível apenas no modo responsivo -->
<a href="#" class="nav-link text-dark d-flex align-items-center d-lg-none">
<i class="fas fa-bell"></i>
</a>
</div>

<!-- Dropdown do usuário com ngx-bootstrap alinhado à direita ou formulário de login -->
<ul class="navbar-nav d-flex align-items-center ms-auto">
<!-- Ícone de notificação (sino) visível apenas no modo desktop -->
<li class="nav-item me-3 d-none d-lg-flex align-items-center" *ngIf="accountService.currentUser()">
<a href="#" class="nav-link text-dark">
<i class="fas fa-bell"></i>
</a>
</li>

<ng-container *ngIf="accountService.currentUser(); else loginForm">
<!-- Usuário autenticado -->
<li class="nav-item dropdown d-flex align-items-center" dropdown>
<a class="nav-link dropdown-toggle text-dark d-flex align-items-center" dropdownToggle>
<img class="rounded-circle me-2" [src]="accountService.currentUser()?.photoUrl || './assets/user.png'"
alt="User Image" style="width: 40px; height: 40px;">
<span class="d-none d-lg-inline">{{ accountService.currentUser()?.knownAs }}</span>
</a>
<ul *dropdownMenu class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" routerLink="/member/edit">Edit Profile</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item" (click)="logout()">Logout</a></li>
</ul>
</li>
</ng-container>

<!-- Formulário de login para usuários deslogados -->
<ng-template #loginForm>
<form #loginForm="ngForm" (ngSubmit)="login()" class="d-flex ms-auto" autocomplete="off">
<input name="username" [(ngModel)]="model.username" class="form-control me-2" placeholder="Username" />
<input name="password" [(ngModel)]="model.password" class="form-control me-2" placeholder="Password"
type="password" />
<button class="btn btn-success" type="submit">Login</button>
</form>
</ng-template>
</ul>
</div>
</nav>

<!-- Sidebar sempre disponível em telas maiores -->
<div id="sidebar" [class.sidebar-open]="sidebarOpen" class="sidebar bg-primary text-white">
<!-- Botão de fechar com ícone de X -->
<div class="sidebar-header d-lg-none d-flex justify-content-end p-3">
<button class="btn btn-link text-white" (click)="closeSidebar()">
<i class="fas fa-times fa-lg"></i>
</button>
</div>

<ul class="nav flex-column p-2">
<li class="nav-item">
<a routerLink="/home" routerLinkActive="active-link" class="nav-link text-white d-flex align-items-center">
<i class="fas fa-home me-2"></i> Home
</a>
</li>
<ng-container *ngIf="accountService.currentUser()">
<li class="nav-item">
<a routerLink="/lists" routerLinkActive="active" class="nav-link">Lists</a>
<a routerLink="/dashboard" routerLinkActive="active-link" class="nav-link text-white d-flex align-items-center">
<i class="fas fa-tachometer-alt me-2"></i> Dashboard
</a>
</li>
<li class="nav-item">
<a routerLink="/messages" routerLinkActive="active" class="nav-link">Messages</a>
<a routerLink="/members" routerLinkActive="active-link" class="nav-link text-white d-flex align-items-center">
<i class="fas fa-users me-2"></i> Matches
</a>
</li>
<li *appHasRole="['Admin','Moderator']" class="nav-item">
<a routerLink="/admin" routerLinkActive="active" class="nav-link">Admin</a>
<li class="nav-item">
<a routerLink="/lists" routerLinkActive="active-link" class="nav-link text-white d-flex align-items-center">
<i class="fas fa-list me-2"></i> Lists
</a>
</li>
}
<li class="nav-item">
<a routerLink="/errors" routerLinkActive="active" class="nav-link">Errors</a>
<a routerLink="/messages" routerLinkActive="active-link" class="nav-link text-white d-flex align-items-center">
<i class="fas fa-envelope me-2"></i> Messages
</a>
</li>
</ul>

@if (accountService.currentUser()) {
<div dropdown class="dropdown">
<img class="me-2" src="{{accountService.currentUser()?.photoUrl || './assets/user.png'}}" alt="user main image">
<a dropdownToggle class="dropdown-toggle text-light text-decoration-none">
Welcome {{accountService.currentUser()?.knownAs}}
</a>
<div *dropdownMenu class="dropdown-menu">
<a routerLink="/member/edit" class="dropdown-item">Edit profile</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" (click)="logout()">Logout</a>
</div>
</div>
}

@if (!accountService.currentUser()) {
<form #loginForm="ngForm" (ngSubmit)="login()" class="d-flex" autocomplete="off">
<input name="username" [(ngModel)]="model.username" class="form-control me-2" placeholder="Username">
<input name="password" [(ngModel)]="model.password" class="form-control me-2" placeholder="Password"
type="password">
<button class="btn btn-success" type="submit">Login</button>
</form>
}


</div>
</nav>
<li *appHasRole="['Admin', 'Moderator']" class="nav-item">
<a routerLink="/admin" routerLinkActive="active-link" class="nav-link text-white d-flex align-items-center">
<i class="fas fa-user-shield me-2"></i> Admin
</a>
</li>
</ng-container>
</ul>
</div>
16 changes: 15 additions & 1 deletion Front/FinanceTracker.Client/src/app/_shared/nav/nav.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,31 @@ import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { Router, RouterLink, RouterLinkActive } from '@angular/router';
import { ToastrService } from 'ngx-toastr';
import { HasRoleDirective } from '../../_directives/has-role.directive';
import { NgIf } from '@angular/common';

@Component({
selector: 'app-nav',
standalone: true,
imports: [
NgIf,
FormsModule,
BsDropdownModule,
RouterLink,
RouterLinkActive,
HasRoleDirective,
],
templateUrl: './nav.component.html',
styleUrl: './nav.component.css',
styleUrls: ['./nav.component.css'],
})
export class NavComponent {
accountService = inject(AccountService);
private router = inject(Router);
private toastr = inject(ToastrService);
model: any = {};

// Variável para controlar a sidebar
sidebarOpen = false;

login() {
this.accountService.login(this.model).subscribe({
next: (_) => {
Expand All @@ -38,4 +43,13 @@ export class NavComponent {
this.accountService.logout();
this.router.navigateByUrl('/');
}

// Funções para abrir/fechar o sidebar
toggleSidebar() {
this.sidebarOpen = !this.sidebarOpen;
}

closeSidebar() {
this.sidebarOpen = false;
}
}
Loading

0 comments on commit 0fc11d4

Please sign in to comment.