diff --git a/assets/css/custom.css b/assets/css/custom.css index 0d57b28..4ffac01 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -1,8 +1,235 @@ +/* General Body & Layout */ body { font-family: 'Inter', sans-serif; background-color: #f8f9fa; + transition: margin-left .3s; } +.wrapper { + display: flex; + width: 100%; +} + +/* Sidebar Styles */ +#sidebar { + width: 280px; + position: fixed; + top: 0; + left: 0; + height: 100vh; + z-index: 999; + background: #4C5958; + color: #fff; + transition: all 0.3s; + overflow-y: auto; + padding-bottom: 20px; +} + +#sidebar.mini { + width: 80px; +} + +#sidebar.mini .sidebar-header h3, +#sidebar.mini .menu-item-text, +#sidebar.mini .profile-text, +#sidebar.mini .dropdown-toggle::after { + display: none; +} + +#sidebar.mini .menu-item .lucide { + margin-right: 0; +} + +#sidebar.mini .profile-section .lucide-user-circle { + margin: 0 auto; +} + + +.sidebar-header { + padding: 20px; + background: #4C5958; + text-align: center; + border-bottom: 1px solid #5a6867; +} + +.sidebar-header h3 { + color: white; + font-weight: 700; + margin-bottom: 0; + font-size: 1.5rem; + white-space: nowrap; +} + +/* Profile Section */ +.profile-section { + padding: 15px 20px; + border-bottom: 1px solid #5a6867; + color: white; +} +.profile-section .dropdown-toggle { + color: white; + text-decoration: none; + display: flex; + align-items: center; + padding: 5px 0; +} +.profile-section .lucide-user-circle { + width: 40px; + height: 40px; + margin-right: 10px; +} +.profile-section .profile-text span { + display: block; + white-space: nowrap; +} +.profile-section .profile-text .username { + font-weight: bold; +} +.profile-section .dropdown-menu { + background-color: #3f4a49; + border: none; +} +.profile-section .dropdown-item { + color: #e0e0e0; +} +.profile-section .dropdown-item:hover { + background-color: #5a6867; + color: white; +} + + +/* Menu List Styles */ +.menu-list { + list-style: none; + padding: 10px 0; + margin: 0; +} + +.menu-list a { + display: flex; + align-items: center; + padding: 12px 20px; + text-decoration: none; + transition: background 0.2s; + font-size: 0.95rem; + white-space: nowrap; +} + +.menu-list .lucide { + margin-right: 15px; + width: 20px; + height: 20px; + flex-shrink: 0; +} + +/* Top Level Items */ +.menu-section > a { + color: #DBF227; + font-weight: 500; + letter-spacing: 0.5px; +} + +.menu-section > a:hover { + background: #3f4a49; +} + +/* Sub Items (Level 2) */ +.sub-menu { + list-style: none; + padding-left: 0; + background: rgba(0,0,0,0.1); +} + +.sub-menu a { + /* NOTE: Using white for better contrast against the dark sidebar. + The requested #10403B is too dark for this background. */ + color: #FFFFFF; + font-size: 0.9rem; + padding-left: 35px; +} + +.sub-menu a:hover { + background: #3f4a49; +} + +.sub-menu .lucide { + width: 18px; + height: 18px; +} + +/* Sub-Sub Items (Level 3) */ +.sub-sub-menu { + list-style: none; + padding-left: 0; + background: rgba(0,0,0,0.15); +} + +.sub-sub-menu a { + color: #e0e0e0; /* Slightly dimmer white */ + font-size: 0.85rem; + padding-left: 55px; +} + +.sub-sub-menu a:hover { + background: #3f4a49; +} + +/* Dropdown Arrow for collapsible menus */ +.dropdown-toggle::after { + display: inline-block; + margin-left: auto; + vertical-align: .255em; + content: ""; + border-top: .3em solid; + border-right: .3em solid transparent; + border-bottom: 0; + border-left: .3em solid transparent; + transition: transform .2s ease-in-out; +} + +.dropdown-toggle[aria-expanded="true"]::after { + transform: rotate(-180deg); +} + +/* Badge for notifications */ +.badge-notification { + background-color: #dc3545; + color: white; + border-radius: 50%; + padding: 0.2em 0.5em; + font-size: 0.7rem; + margin-left: auto; + margin-right: 10px; +} + +/* Main Content Area */ +#content { + width: 100%; + padding: 20px; + min-height: 100vh; + transition: all 0.3s; + margin-left: 280px; +} + +#content.full-width { + margin-left: 80px; +} + +.content-header { + display: flex; + align-items: center; + margin-bottom: 20px; +} + +#sidebar-toggle { + background: none; + border: none; + font-size: 1.5rem; + color: #333; + cursor: pointer; +} + +/* Login Form Styles (keep existing) */ .login-container { min-height: 100vh; display: flex; @@ -19,7 +246,21 @@ body { box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.1); } -.navbar-brand-logo { - font-weight: 700; - color: #0D6EFD; /* Bootstrap Primary */ -} +/* Responsive */ +@media (max-width: 768px) { + #sidebar { + left: -280px; + } + #sidebar.active { + left: 0; + } + #content { + margin-left: 0; + } + #content.full-width { + margin-left: 0; + } + body.sidebar-open { + overflow: hidden; + } +} \ No newline at end of file diff --git a/includes/footer.php b/includes/footer.php index a99c75b..9a3727a 100644 --- a/includes/footer.php +++ b/includes/footer.php @@ -1,3 +1,23 @@ + - + \ No newline at end of file diff --git a/includes/header.php b/includes/header.php index 320a6f2..0da3d7d 100644 --- a/includes/header.php +++ b/includes/header.php @@ -1,10 +1,7 @@ execute(['id' => $_SESSION['user_id']]); $user = $stmt->fetch(PDO::FETCH_ASSOC); if ($user) { + // Pega o primeiro nome para uma saudação mais curta + $first_name = explode(' ', $user['name'])[0]; $user_name = $user['name']; } } catch (PDOException $e) { // Em caso de erro, o nome fica em branco } } + +// Placeholder for unclassified expenses count +$unclassifiedCount = 5; // Example value + ?> - Galilei Finance + Concilia Fácil - + - + + + - + + + + + + + + + + + \ No newline at end of file diff --git a/includes/session.php b/includes/session.php new file mode 100644 index 0000000..7bfef79 --- /dev/null +++ b/includes/session.php @@ -0,0 +1,37 @@ + 0, + 'path' => '/', + 'domain' => '', + 'secure' => true, + 'httponly' => true, + 'samesite' => 'None' // 'None' requer 'secure' => true + ]); +} else { + // Configuração para desenvolvimento local (HTTP) + session_set_cookie_params([ + 'lifetime' => 0, + 'path' => '/', + 'domain' => '', + 'secure' => false, + 'httponly' => true, + 'samesite' => 'Lax' + ]); +} + +// Inicia a sessão +if (session_status() == PHP_SESSION_NONE) { + session_start(); +} \ No newline at end of file diff --git a/index.php b/index.php index f764c0e..2271da8 100644 --- a/index.php +++ b/index.php @@ -1,172 +1,30 @@ prepare( - "SELECT category, SUM(amount) as total_spent FROM expenses - WHERE user_id = :user_id AND MONTH(expense_date) = MONTH(CURRENT_DATE()) AND YEAR(expense_date) = YEAR(CURRENT_DATE()) - GROUP BY category" -); -$stmt_expenses->execute(['user_id' => $user_id]); -$monthly_expenses = $stmt_expenses->fetchAll(PDO::FETCH_KEY_PAIR); - -// 2. Orçamentos do Mês Atual -$stmt_budgets = $pdo->prepare("SELECT category, amount FROM budgets WHERE user_id = :user_id AND budget_month = :budget_month"); -$stmt_budgets->execute(['user_id' => $user_id, 'budget_month' => $current_month_date]); -$monthly_budgets = $stmt_budgets->fetchAll(PDO::FETCH_KEY_PAIR); - -// 3. Consolidar dados de Orçamento e Despesas -$categories = ['Alimentação', 'Transporte', 'Moradia', 'Lazer', 'Saúde', 'Outros']; -$summary = []; -$total_spent_this_month = 0; -$total_budget_this_month = 0; - -foreach ($categories as $category) { - $spent = $monthly_expenses[$category] ?? 0; - $budget = $monthly_budgets[$category] ?? 0; - $summary[$category] = [ - 'spent' => $spent, - 'budget' => $budget, - 'remaining' => $budget - $spent, - ]; - $total_spent_this_month += $spent; - $total_budget_this_month += $budget; -} - -// 4. Últimas 5 despesas -$stmt_recent = $pdo->prepare("SELECT * FROM expenses WHERE user_id = :user_id ORDER BY expense_date DESC LIMIT 5"); -$stmt_recent->execute(['user_id' => $user_id]); -$recent_expenses = $stmt_recent->fetchAll(PDO::FETCH_ASSOC); - -// Função para determinar a classe da barra de progresso -function get_progress_bar_class($percentage) { - if ($percentage > 100) return 'bg-danger'; - if ($percentage > 75) return 'bg-warning'; - return 'bg-success'; -} - -include __DIR__ . '/includes/header.php'; +require_once 'db/config.php'; +require_once 'includes/header.php'; ?> -
-

Dashboard de

- - -
-
-
-
-

Visão Geral do Mês

-

Gastos vs. Orçamento Total

- R$ - / R$ +
+
+
+
+
+

Dashboard

-
- 0) ? ($total_spent_this_month / $total_budget_this_month) * 100 : 0; - $progress_class = get_progress_bar_class($overall_percentage); - ?> -
-
- % -
-
+
+

Bem-vindo ao seu painel de controle de despesas!

+

Use os links na barra de navegação para gerenciar suas despesas e orçamentos.

+
- -
-
-
Resumo do Orçamento por Categoria
-
-
-
- - - - - - - - - - - - $data): ?> - - - - - - - - - -
CategoriaGastoOrçamentoRestanteProgresso
R$ R$ - R$ - - 0) ? ($data['spent'] / $data['budget']) * 100 : 0; - $progress_class = get_progress_bar_class($percentage); - ?> -
-
-
-
-
-
-
-
- - -
-
-
Despesas Recentes
-
-
-
- - - - - - - - - - - - - - -
Nenhuma despesa registrada este mês.
R$
-
- -
-
-
- - \ No newline at end of file + diff --git a/login.php b/login.php index c18dd75..e8244a8 100644 --- a/login.php +++ b/login.php @@ -1,9 +1,7 @@ fetch(PDO::FETCH_ASSOC); if ($user && password_verify($password, $user['password_hash'])) { - // Login bem-sucedido - $_SESSION['user_id'] = $user['id']; - header('Location: index.php'); - exit; - } else { - // Credenciais inválidas - $error_message = 'E-mail ou senha inválidos.'; - } - - if ($user && password_verify($password, $user['password_hash'])) { - // Login bem-sucedido - $_SESSION['user_id'] = $user['id']; - header('Location: index.php'); - exit; + // Login bem-sucedido: Redireciona com flag de depuração + // Senha correta, inicie a sessão + $_SESSION['user_id'] = $user['id']; + $_SESSION['user_email'] = $user['email']; + header("Location: index.php"); + exit(); } else { // Credenciais inválidas $error_message = 'E-mail ou senha inválidos.';