refactor: integrate ProtectedRoute component across dashboard pages
- Added the ProtectedRoute component to various dashboard pages to enforce authentication and role-based access control. - Updated allowedRoles and maxLevel parameters for specific routes to align with the new permission management structure. - Enhanced user experience by ensuring consistent access checks across the application.
This commit is contained in:
@@ -1,16 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { useQuery } from "convex-svelte";
|
import { useQuery } from 'convex-svelte';
|
||||||
import { api } from "@sgse-app/backend/convex/_generated/api";
|
import { api } from '@sgse-app/backend/convex/_generated/api';
|
||||||
import { onMount } from "svelte";
|
import { onMount } from 'svelte';
|
||||||
import { page } from "$app/stores";
|
import type { Snippet } from 'svelte';
|
||||||
import type { Snippet } from "svelte";
|
|
||||||
|
|
||||||
let {
|
let {
|
||||||
children,
|
children,
|
||||||
requireAuth = true,
|
requireAuth = true,
|
||||||
allowedRoles = [],
|
allowedRoles = [],
|
||||||
maxLevel = 3,
|
maxLevel = 3,
|
||||||
redirectTo = "/",
|
redirectTo = '/'
|
||||||
}: {
|
}: {
|
||||||
children: Snippet;
|
children: Snippet;
|
||||||
requireAuth?: boolean;
|
requireAuth?: boolean;
|
||||||
@@ -41,9 +40,7 @@
|
|||||||
|
|
||||||
// Verificar roles
|
// Verificar roles
|
||||||
if (allowedRoles.length > 0 && currentUser?.data) {
|
if (allowedRoles.length > 0 && currentUser?.data) {
|
||||||
const hasRole = allowedRoles.includes(
|
const hasRole = allowedRoles.includes(currentUser.data.role?.nome ?? '');
|
||||||
currentUser.data.role?.nome ?? "",
|
|
||||||
);
|
|
||||||
if (!hasRole) {
|
if (!hasRole) {
|
||||||
const currentPath = window.location.pathname;
|
const currentPath = window.location.pathname;
|
||||||
window.location.href = `${redirectTo}?error=access_denied&route=${encodeURIComponent(currentPath)}`;
|
window.location.href = `${redirectTo}?error=access_denied&route=${encodeURIComponent(currentPath)}`;
|
||||||
@@ -69,10 +66,10 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if isChecking}
|
{#if isChecking}
|
||||||
<div class="flex justify-center items-center min-h-screen">
|
<div class="flex min-h-screen items-center justify-center">
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<span class="loading loading-spinner loading-lg text-primary"></span>
|
<span class="loading loading-spinner loading-lg text-primary"></span>
|
||||||
<p class="mt-4 text-base-content/70">Verificando permissões...</p>
|
<p class="text-base-content/70 mt-4">Verificando permissões...</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else if hasAccess}
|
{:else if hasAccess}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
import { resolve } from "$app/paths";
|
import { resolve } from "$app/paths";
|
||||||
import { UserPlus, Mail } from "lucide-svelte";
|
import { UserPlus, Mail } from "lucide-svelte";
|
||||||
import { useAuth } from "@mmailaender/convex-better-auth-svelte/svelte";
|
import { useAuth } from "@mmailaender/convex-better-auth-svelte/svelte";
|
||||||
|
import ProtectedRoute from "$lib/components/ProtectedRoute.svelte";
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
@@ -128,6 +129,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<ProtectedRoute>
|
||||||
<main class="container mx-auto px-4 py-4">
|
<main class="container mx-auto px-4 py-4">
|
||||||
<!-- Alerta de Acesso Negado / Autenticação -->
|
<!-- Alerta de Acesso Negado / Autenticação -->
|
||||||
{#if showAlert}
|
{#if showAlert}
|
||||||
@@ -823,6 +825,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</main>
|
</main>
|
||||||
|
</ProtectedRoute>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@keyframes fadeIn {
|
@keyframes fadeIn {
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ShoppingCart, ShoppingBag, Plus } from "lucide-svelte";
|
import { ShoppingCart, ShoppingBag, Plus } from "lucide-svelte";
|
||||||
import { resolve } from "$app/paths";
|
import { resolve } from "$app/paths";
|
||||||
|
import ProtectedRoute from "$lib/components/ProtectedRoute.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<ProtectedRoute>
|
||||||
<main class="container mx-auto px-4 py-4">
|
<main class="container mx-auto px-4 py-4">
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
<ul>
|
<ul>
|
||||||
@@ -41,4 +43,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
</ProtectedRoute>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Megaphone, Edit, Plus } from "lucide-svelte";
|
import { Megaphone, Edit, Plus } from "lucide-svelte";
|
||||||
import { resolve } from "$app/paths";
|
import { resolve } from "$app/paths";
|
||||||
|
import ProtectedRoute from "$lib/components/ProtectedRoute.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<ProtectedRoute>
|
||||||
<main class="container mx-auto px-4 py-4">
|
<main class="container mx-auto px-4 py-4">
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
<ul>
|
<ul>
|
||||||
@@ -41,4 +43,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
</ProtectedRoute>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { BarChart3, ClipboardCheck, Plus, CheckCircle2, Clock, TrendingUp } from "lucide-svelte";
|
import { BarChart3, ClipboardCheck, Plus, CheckCircle2, Clock, TrendingUp } from "lucide-svelte";
|
||||||
import { resolve } from "$app/paths";
|
import { resolve } from "$app/paths";
|
||||||
|
import ProtectedRoute from "$lib/components/ProtectedRoute.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<ProtectedRoute>
|
||||||
<main class="container mx-auto px-4 py-4">
|
<main class="container mx-auto px-4 py-4">
|
||||||
<!-- Breadcrumb -->
|
<!-- Breadcrumb -->
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
@@ -86,4 +88,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
</ProtectedRoute>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { DollarSign, Building2, Plus, Calculator, TrendingUp, FileText } from "lucide-svelte";
|
import { DollarSign, Building2, Plus, Calculator, TrendingUp, FileText } from "lucide-svelte";
|
||||||
import { resolve } from "$app/paths";
|
import { resolve } from "$app/paths";
|
||||||
|
import ProtectedRoute from "$lib/components/ProtectedRoute.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<ProtectedRoute>
|
||||||
<main class="container mx-auto px-4 py-4">
|
<main class="container mx-auto px-4 py-4">
|
||||||
<!-- Breadcrumb -->
|
<!-- Breadcrumb -->
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
@@ -86,4 +88,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
</ProtectedRoute>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Scale, BookOpen, Plus } from "lucide-svelte";
|
import { Scale, BookOpen, Plus } from "lucide-svelte";
|
||||||
import { resolve } from "$app/paths";
|
import { resolve } from "$app/paths";
|
||||||
|
import ProtectedRoute from "$lib/components/ProtectedRoute.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<ProtectedRoute>
|
||||||
<main class="container mx-auto px-4 py-4">
|
<main class="container mx-auto px-4 py-4">
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
<ul>
|
<ul>
|
||||||
@@ -41,4 +43,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
</ProtectedRoute>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { FileText, ClipboardCopy, Plus, Users, FileDoc } from "lucide-svelte";
|
import { FileText, ClipboardCopy, Plus, Users, FileDoc } from "lucide-svelte";
|
||||||
import { resolve } from "$app/paths";
|
import { resolve } from "$app/paths";
|
||||||
|
import ProtectedRoute from "$lib/components/ProtectedRoute.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<ProtectedRoute>
|
||||||
<main class="container mx-auto px-4 py-4">
|
<main class="container mx-auto px-4 py-4">
|
||||||
<!-- Breadcrumb -->
|
<!-- Breadcrumb -->
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
@@ -86,4 +88,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
</ProtectedRoute>
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
import AprovarAusencias from '$lib/components/AprovarAusencias.svelte';
|
import AprovarAusencias from '$lib/components/AprovarAusencias.svelte';
|
||||||
import CalendarioAusencias from '$lib/components/ausencias/CalendarioAusencias.svelte';
|
import CalendarioAusencias from '$lib/components/ausencias/CalendarioAusencias.svelte';
|
||||||
import { generateAvatarGallery } from '$lib/utils/avatars';
|
import { generateAvatarGallery } from '$lib/utils/avatars';
|
||||||
|
import ProtectedRoute from '$lib/components/ProtectedRoute.svelte';
|
||||||
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
|
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
|
||||||
import { X, Calendar } from 'lucide-svelte';
|
import { X, Calendar } from 'lucide-svelte';
|
||||||
import type { FunctionReturnType } from 'convex/server';
|
import type { FunctionReturnType } from 'convex/server';
|
||||||
@@ -365,6 +366,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<ProtectedRoute>
|
||||||
<main class="min-h-screen pb-12">
|
<main class="min-h-screen pb-12">
|
||||||
<!-- BANNER HERO PREMIUM -->
|
<!-- BANNER HERO PREMIUM -->
|
||||||
<div class="relative mb-8 overflow-hidden">
|
<div class="relative mb-8 overflow-hidden">
|
||||||
@@ -2264,6 +2266,7 @@
|
|||||||
</dialog>
|
</dialog>
|
||||||
{/if}
|
{/if}
|
||||||
</main>
|
</main>
|
||||||
|
</ProtectedRoute>
|
||||||
|
|
||||||
<!-- Modal Wizard Solicitação de Férias -->
|
<!-- Modal Wizard Solicitação de Férias -->
|
||||||
{#if mostrarWizard && funcionarioIdDisponivel}
|
{#if mostrarWizard && funcionarioIdDisponivel}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Trophy, Award, Plus } from "lucide-svelte";
|
import { Trophy, Award, Plus } from "lucide-svelte";
|
||||||
import { resolve } from "$app/paths";
|
import { resolve } from "$app/paths";
|
||||||
|
import ProtectedRoute from "$lib/components/ProtectedRoute.svelte";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<ProtectedRoute>
|
||||||
<main class="container mx-auto px-4 py-4">
|
<main class="container mx-auto px-4 py-4">
|
||||||
<div class="text-sm breadcrumbs mb-4">
|
<div class="text-sm breadcrumbs mb-4">
|
||||||
<ul>
|
<ul>
|
||||||
@@ -41,4 +43,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
</ProtectedRoute>
|
||||||
|
|
||||||
|
|||||||
@@ -138,7 +138,7 @@
|
|||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ProtectedRoute allowedRoles={['ti_master', 'admin', 'ti_usuario']} maxLevel={3}>
|
<ProtectedRoute allowedRoles={['ti_master', 'admin', 'ti_usuario']} maxLevel={1}>
|
||||||
<div class="container mx-auto max-w-7xl px-4 py-6">
|
<div class="container mx-auto max-w-7xl px-4 py-6">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="mb-8 flex items-center justify-between">
|
<div class="mb-8 flex items-center justify-between">
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import { resolve } from '$app/paths';
|
import { resolve } from '$app/paths';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ProtectedRoute allowedRoles={['admin', 'ti']} maxLevel={1}>
|
<ProtectedRoute allowedRoles={['ti_master', 'admin']} maxLevel={1}>
|
||||||
<!-- Breadcrumb -->
|
<!-- Breadcrumb -->
|
||||||
<div class="breadcrumbs mb-4 text-sm">
|
<div class="breadcrumbs mb-4 text-sm">
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
@@ -257,7 +257,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ProtectedRoute allowedRoles={['ti_master', 'admin', 'ti_usuario']} maxLevel={3}>
|
<ProtectedRoute allowedRoles={['ti_master', 'admin', 'ti_usuario']} maxLevel={1}>
|
||||||
<div class="container mx-auto max-w-7xl px-4 py-6">
|
<div class="container mx-auto max-w-7xl px-4 py-6">
|
||||||
<!-- Mensagem de Feedback -->
|
<!-- Mensagem de Feedback -->
|
||||||
{#if mensagem}
|
{#if mensagem}
|
||||||
|
|||||||
@@ -278,7 +278,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ProtectedRoute allowedRoles={['ti_master', 'admin', 'ti_usuario']} maxLevel={2}>
|
<ProtectedRoute allowedRoles={['ti_master', 'admin', 'ti_usuario']} maxLevel={1}>
|
||||||
<main class="container mx-auto max-w-7xl px-4 py-6">
|
<main class="container mx-auto max-w-7xl px-4 py-6">
|
||||||
<!-- Breadcrumb -->
|
<!-- Breadcrumb -->
|
||||||
<div class="breadcrumbs mb-4 text-sm">
|
<div class="breadcrumbs mb-4 text-sm">
|
||||||
|
|||||||
@@ -535,7 +535,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ProtectedRoute allowedRoles={['ti_master', 'admin', 'ti_usuario']} maxLevel={3}>
|
<ProtectedRoute allowedRoles={['ti_master', 'admin', 'ti_usuario']} maxLevel={1}>
|
||||||
<div class="container mx-auto max-w-7xl px-4 py-6">
|
<div class="container mx-auto max-w-7xl px-4 py-6">
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="mb-6 flex items-center justify-between">
|
<div class="mb-6 flex items-center justify-between">
|
||||||
|
|||||||
Reference in New Issue
Block a user