Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(admin): sidebar #33

Merged
merged 12 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/lib/api/getToken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import CryptoJS from 'crypto-js';

const secretKey = import.meta.env.VITE_SECRET_KEY;

export const getDecryptedToken = () => {
const encryptedToken = sessionStorage.getItem('encryptedToken');
if (encryptedToken) {
const bytes = CryptoJS.AES.decrypt(encryptedToken, secretKey);
const decryptedToken = bytes.toString(CryptoJS.enc.Utf8);
return decryptedToken;
}
console.log('No encrypted token found in sessionStorage.');
return null;
};
23 changes: 23 additions & 0 deletions src/lib/api/getme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const API_URL = '/api/getme';

export async function getMe(token: string) {
try {
const response = await fetch(API_URL, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`
}
});

if (!response.ok) {
throw new Error('Failed to fetch user data');
}

const data = await response.json();
return data;
} catch (error) {
console.error(error);
throw error;
}
}
3 changes: 3 additions & 0 deletions src/lib/assets/icons/edit.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/lib/assets/images/isdlogo.png
Chulinuwu marked this conversation as resolved.
Show resolved Hide resolved
Chulinuwu marked this conversation as resolved.
Show resolved Hide resolved
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
72 changes: 72 additions & 0 deletions src/lib/components/Sidebar/Sidebar.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<script lang="ts">
import { onMount } from 'svelte';
import sgcuLogo from '$lib/assets/images/sgcu.png';
import isdLogo from '$lib/assets/images/isdlogo.png';
import editLogo from '$lib/assets/icons/edit.svg';
export let menuItems: { title: string; href: string }[];
export let user: { name: string; lastname: string; role: string };

let currentPath = '';

onMount(() => {
currentPath = window.location.pathname;
});

function handleClick() {
console.log('Edit icon clicked');
}
</script>

<aside
class="fixed left-0 top-0 z-50 flex h-screen w-[250px] flex-col justify-between bg-sucu-pink-05"
>
<div>
<div class="flex justify-center p-4 my-4">
<img src={sgcuLogo} alt="Logo" class="h-20" />
</div>

<nav class="flex flex-col p-4 gap-2">
{#each menuItems as item}
<a
href={item.href}
class="p-2 hover:bg-sucu-pink-04 font-semibold {currentPath === item.href
? 'bg-white'
: ''}"
>
{item.title}
</a>
{/each}
</nav>
</div>

<div>
<div class="relative p-4 m-4 bg-white">
<div class="absolute top-2 right-2">
<button
type="button"
class="h-4 w-4 cursor-pointer"
on:click={handleClick}
aria-label="Edit"
>
<img src={editLogo} alt="Edit" class="h-4 w-4" />
</button>
</div>
<div class="body-small font-semibold">
<div class="text-xs">{user.name}</div>
<div class="text-xs">{user.lastname}</div>
</div>
<div class="text-xs font-semibold">
{user.role}
</div>
</div>

<div class="p-4 m-4 body-medium font-semibold hover:bg-sucu-pink-04">ออกจากระบบ</div>

<hr class="border-pink-200 mx-4 my-4" />

<div class="flex flex-col items-center p-4">
<div class="text-xs">Develop by SGCU</div>
<img src={isdLogo} alt="Develop by SGCU" class="h-10 my-2" />
</div>
</div>
</aside>
43 changes: 43 additions & 0 deletions src/routes/admin/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<script lang="ts">
import Sidebar from '$lib/components/Sidebar/Sidebar.svelte';
import { getMe } from '$lib/api/getme';
import { getDecryptedToken } from '$lib/api/getToken';
import { onMount } from 'svelte';
const menuItems = [
{ title: 'ประกาศ', href: '/admin' },
{ title: 'เอกสาร', href: '/admin/documents' },
{ title: 'สถิติ และ งบประมาณ', href: '/admin/stats' },
{ title: 'จัดการผู้ใช้งาน', href: '/admin/users' }
];
let user = {
name: 'Not found',
lastname: 'Not found',
role: 'Not found',
id: 'Not found'
};
onMount(async () => {
const token = getDecryptedToken();
if (token) {
try {
const userData = await getMe(token);
user = {
name: userData.result.first_name,
lastname: userData.result.last_name,
role: userData.result.role,
id: userData.result.id
};
} catch (error) {
console.error('Failed to fetch user data:', error);
}
} else {
console.log('No token found');
}
});
</script>

<div class="flex min-h-screen bg-white">
<Sidebar {menuItems} {user} />
</div>
24 changes: 24 additions & 0 deletions src/routes/api/getme/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { RequestHandler } from '@sveltejs/kit';

export const GET: RequestHandler = async ({ request }) => {
const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/v1/auth/me`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: request.headers.get('Authorization') || ''
}
});

if (!response.ok) {
return new Response(JSON.stringify({ error: 'Failed to fetch user data' }), {
status: response.status,
headers: { 'Content-Type': 'application/json' }
});
}

const data = await response.json();
return new Response(JSON.stringify(data), {
status: 200,
headers: { 'Content-Type': 'application/json' }
});
};
15 changes: 1 addition & 14 deletions src/routes/auth/login/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { goto } from '$app/navigation';
import { login } from '$lib/api/login';
import CryptoJS from 'crypto-js';
Expand All @@ -20,19 +20,6 @@
} catch (error) {
errorMessage = error instanceof Error ? error.message : 'An unknown error occurred';
}
// getDecryptedToken();
};
const getDecryptedToken = () => {
const encryptedToken = sessionStorage.getItem('encryptedToken');
if (encryptedToken) {
const bytes = CryptoJS.AES.decrypt(encryptedToken, secretKey);
const decryptedToken = bytes.toString(CryptoJS.enc.Utf8);
console.log('Decrypted Token:', decryptedToken);
return decryptedToken;
}
console.log('No encrypted token found in sessionStorage.');
return null;
};
</script>

Expand Down
Loading