Skip to content

Commit

Permalink
update profile, add api keys management
Browse files Browse the repository at this point in the history
  • Loading branch information
juansensio committed Aug 9, 2024
1 parent 9883aa4 commit 294d0cc
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 145 deletions.
2 changes: 0 additions & 2 deletions ui/src/components/Map.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
export let geojson;
$: console.log(geojson);
let map = null;
let zoomPosition = "bottomright";
let options = {
Expand Down
4 changes: 2 additions & 2 deletions ui/src/lib/apikeys/deleteApiKey.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import fetchEOTDL from '$lib/shared/fetchEOTDL';

export default async (token,keyId) => {
let url = `${PUBLIC_EOTDL_API}/auth/keys/${keyId}`;
const {data, error} = await fetchEOTDL(url,token, "DELETE");
const {data, error} = await fetchEOTDL(url, token, "DELETE");
if (error) throw new Error(error);
return data;
return data;
};

2 changes: 1 addition & 1 deletion ui/src/lib/apikeys/requestApiKey.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import fetchEOTDL from '$lib/shared/fetchEOTDL';

export default async (token) => {
let url = `${PUBLIC_EOTDL_API}/auth/keys`;
const {data, error} = await fetchEOTDL(url,token, "POST");
const {data, error} = await fetchEOTDL(url, token, "POST");
if (error) throw new Error(error);
return data;
};
6 changes: 3 additions & 3 deletions ui/src/lib/apikeys/retrieveApiKey.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { PUBLIC_EOTDL_API } from '$env/static/public';
import fetchEOTDL from '$lib/shared/fetchEOTDL';

export default async (token) => {
let url = `${PUBLIC_EOTDL_API}/auth/keys`;
const {data, error} = await fetchEOTDL(url,token, "GET");
let url = `${PUBLIC_EOTDL_API}/auth/keys`;
const {data, error} = await fetchEOTDL(url, token, "GET");
if (error) throw new Error(error);
return data;
return data;
};

File renamed without changes.
12 changes: 12 additions & 0 deletions ui/src/routes/profile/+layout.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script>
import ProfileNavBar from "./ProfileNavBar.svelte";
</script>

<div
class="w-full flex flex-col items-left sm:px-14 px-3 min-h-screen max-w-5xl m-auto"
>
<div class="py-10 mt-10 flex sm:flex-row flex-col gap-12">
<ProfileNavBar />
<slot />
</div>
</div>
40 changes: 15 additions & 25 deletions ui/src/routes/profile/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<script>
import updateProfile from "$lib/auth/updateProfile";
import TermsAndConditions from "./TermsAndConditions.svelte";
import ProfileNavBar from "./ProfileNavBar.svelte";
export let data;
let newName;
Expand All @@ -24,33 +23,24 @@
<meta name="description" content="user profile" />
</svelte:head>

<div class="w-full flex flex-col items-left sm:px-14 px-3 h-screen">
<div class="py-10 mt-10 flex sm:flex-row flex-col">
<ProfileNavBar />
<div class="px-3 w-full max-w-6xl flex flex-col gap-3">
<h1 class="sm:text-left text-center w-full text-2xl">Profile</h1>
<div class="flex sm:flex-row flex-col w-full gap-3">
<div class="avatar">
<div class="w-32 rounded-full">
<img
src={data?.user?.picture || "/avatar.webp"}
alt="avatar"
/>
</div>
</div>
<div>
<h2 class="text-2xl">{data?.user?.name}</h2>
<h3 class="text-xl">Email: {data?.user?.email}</h3>
<label
for="edit-profile"
class="text-gray-400 cursor-pointer hover:underline"
>Edit</label
>
</div>
<div class="w-full flex flex-col gap-3">
<h1 class="sm:text-left w-full text-2xl">Profile</h1>
<div class="flex sm:flex-row flex-col w-full gap-3">
<div class="avatar">
<div class="w-32 rounded-full">
<img src={data?.user?.picture || "/avatar.webp"} alt="avatar" />
</div>
<TermsAndConditions />
</div>
<div>
<h2 class="text-2xl">{data?.user?.name}</h2>
<h3 class="text-xl">Email: {data?.user?.email}</h3>
<label
for="edit-profile"
class="text-gray-400 cursor-pointer hover:underline">Edit</label
>
</div>
</div>
<TermsAndConditions />
</div>

<input type="checkbox" id="edit-profile" class="modal-toggle" />
Expand Down
1 change: 0 additions & 1 deletion ui/src/routes/profile/Credentials.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
};
</script>

<h2 class="font-bold">Your credentials:</h2>
{#if credentials}
<button
class="btn btn-outline w-[100px]"
Expand Down
24 changes: 15 additions & 9 deletions ui/src/routes/profile/ProfileNavBar.svelte
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
<script>
import { page } from "$app/stores"
import { page } from "$app/stores";
let profileSections = {
"Profile":"/profile",
"Credentials":"/profile/credentials",
Profile: "/profile",
Credentials: "/profile/credentials",
"Api keys": "/profile/apikeys",
}
};
</script>
<div class="px-6 py-6 items-center">

<div class="items-center text-sm">
<ul class="flex sm:flex-col flex-row gap-4">
{#each Object.keys(profileSections) as section }
<li class="w-full py-[1px] hover:border-slate-500 border-b-[2px] {$page.url.pathname == profileSections[section] ? " border-black border-b-[2px] ": ""}">
<a class="font-semibold text-lg" href="{profileSections[section]}">
{#each Object.keys(profileSections) as section}
<li
class="w-full py-[1px] hover:border-slate-500 border-b-[2px] {$page
.url.pathname == profileSections[section]
? ' border-black border-b-[2px] '
: ''} text-slate-500 hover:text-slate-900"
>
<a href={profileSections[section]}>
{section}
</a>
</li>
{/each}
</ul>
</div>

<slot />
<slot />
148 changes: 75 additions & 73 deletions ui/src/routes/profile/apikeys/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,94 +1,96 @@
<script>
import ProfileNavBar from "../ProfileNavBar.svelte";
import requestApiKey from "$lib/apikeys/requestApiKey.js";
import deleteApiKey from "$lib/apikeys/deleteApiKey.js";
import retrieveApiKey from "$lib/apikeys/retrieveApiKey.js";
import { id_token } from "$stores/auth"
import { id_token } from "$stores/auth";
import { onMount } from "svelte";
// import copyToClipboard from "$lib/shared/copyToClipboard";
import TrashCanOutline from "svelte-material-icons/TrashCanOutline.svelte"
import ContentCopy from "svelte-material-icons/ContentCopy.svelte"
import TrashCanOutline from "svelte-material-icons/TrashCanOutline.svelte";
import ContentCopy from "svelte-material-icons/ContentCopy.svelte";
let apikeys = [];
let limitReached = false;
let onAlert = false;
let deletingKey;
let key2delete = null;
const formatTime = (dataTime) => {
let data = dataTime.split("T")[0];
let time = dataTime.split("T")[1].split(":").slice(0,2).join(":");
let time = dataTime.split("T")[1].split(":").slice(0, 2).join(":");
return `${data} at ${time}`;
};
}
onMount(() => {
retrieveApiKey($id_token).then((val) =>{
apikeys = val;
});
});
const deleteKey = async (keyId) => {
deleteApiKey($id_token, keyId).then((val) =>{
retrieveApiKey($id_token).then((val) =>{
apikeys = val;
limitReached = false;
});
})
}
const newKey = async () => {
onMount(async () => {
try {
await requestApiKey($id_token)
limitReached = false;
apikeys = await retrieveApiKey($id_token);
} catch (e) {
alert(e.message);
}
catch (e) {
limitReached = true;
});
const createKey = async () => {
try {
const newKey = await requestApiKey($id_token);
apikeys = [...apikeys, newKey];
} catch (e) {
alert(e.message);
}
retrieveApiKey($id_token).then((val) =>{
apikeys = val;
});
}
};
const deleteKey = async () => {
try {
await deleteApiKey($id_token, key2delete);
apikeys = apikeys.filter((key) => key.id !== key2delete);
} catch (e) {
alert(e.message);
}
};
</script>

<div class="fixed flex top-0 h-screen w-screen items-center justify-center bg-slate-500 bg-opacity-50 {onAlert ? "" : "hidden"}">
<div class="bg-slate-50 flex flex-col p-12 rounded-xl fixed">
<p class="font-bold text-center">Confirm delete?</p>
<div class="flex gap-4 mt-6">
<button on:click={() => {deleteKey(deletingKey); onAlert = !onAlert}} class="btn btn-outline btn-error">Yes</button>
<button on:click={() => { onAlert = !onAlert}} class="btn btn-outline">No</button>
</div>
</div>
<div class="w-full flex flex-col sm:items-start gap-3">
<h1 class="sm:text-left w-full text-2xl">Api Keys</h1>
<button class="btn btn-outline w-30" on:click={createKey}>Create new</button
>
{#each apikeys as key}
<div
class="flex justify-between px-4 py-2 mb-2 bg-gray-100 rounded-lg w-full"
>
<div>
<div class="flex items-baseline">
<p>
<strong>Key:</strong>
{key.id.slice(1, 8).concat("...")}
</p>
</div>
<p class="text-sm text-gray-400 pt-4">
Created on {formatTime(key.createdAt)}
</p>
</div>
<div class="flex items-baseline justify-between flex-col ml-4">
<label
for="confirm_modal"
on:click={() => (key2delete = key.id)}
class="active:bg-gray-300 p-1 rounded-md transition-all cursor-pointer"
>
<TrashCanOutline size="18" title="Delete" />
</label>
<button
class="active:bg-gray-300 p-1 rounded-md transition-all"
on:click={navigator.clipboard.writeText(key.id)}
>
<ContentCopy size="18" title="Copy" />
</button>
</div>
</div>
{/each}
</div>

<div class="w-full flex flex-row items-left sm:px-14 px-3 h-screen">
<div class="py-10 mt-10 flex sm:flex-row flex-col">
<ProfileNavBar />
<div class="px-3 w-full max-w-6xl flex flex-col sm:items-start items-center gap-3">
<h1 class="sm:text-left text-center w-full text-2xl">Api Keys</h1>
<button class="btn btn-outline w-30 mt-8" on:click={newKey}>Create new</button>
<p class="transition-all text-red-500 sm:text-left text-center {limitReached ? "opacity-100":"opacity-0"}">API key limit reached. Delete an existing key to create a new one.</p>
{#each apikeys as key}
<div class="flex justify-between px-4 py-2 mb-2 bg-gray-100 rounded-lg">
<div>
<div class="flex items-baseline">
<p><strong>Key:</strong> {key.id.slice(1,8).concat(" . . .")}</p>
</div>
<p class="text-sm text-gray-400 pt-4">Created on {formatTime(key.createdAt)}</p>
</div>
<div class="flex items-baseline justify-between flex-col ml-4">
<button on:click={() => {deletingKey = key.id; onAlert = !onAlert;}} class="active:bg-gray-300 p-1 rounded-md transition-all">
<TrashCanOutline size="18" title="Delete" />
</button>
<button class = "active:bg-gray-300 p-1 rounded-md transition-all" on:click={navigator.clipboard.writeText(key.id)}>
<ContentCopy size="18" title="Copy"/>
</button>
</div>
</div>
{/each}
<input type="checkbox" id="confirm_modal" class="modal-toggle" />
<div class="modal" role="dialog">
<div class="modal-box">
<h3 class="text-lg font-bold">Confirm</h3>
<p class="py-4">Are you sure you want to delete this key?</p>
<div class="modal-action">
<label for="confirm_modal" class="btn btn-ghost">Close</label>
<label for="confirm_modal" class="btn" on:click={deleteKey}
>Confirm</label
>
</div>
</div>
</div>
</div>
</div>
17 changes: 0 additions & 17 deletions ui/src/routes/profile/credentials/+page.server.js

This file was deleted.

18 changes: 6 additions & 12 deletions ui/src/routes/profile/credentials/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
<script>
import ProfileNavBar from "../ProfileNavBar.svelte";
import Credentials from "../Credentials.svelte";
export let data;
import Credentials from "../Credentials.svelte";
export let data;
</script>

<div class="w-full flex flex-col items-left sm:px-14 px-3 h-fit">
<div class="py-10 mt-10 flex sm:flex-row flex-col">
<ProfileNavBar />
<div class="px-3 w-full max-w-6xl flex flex-col gap-3">
<h1 class="sm:text-left text-center w-full text-2xl">Credentials</h1>
<Credentials {data} />
</div>
</div>
</div>
<div class="w-full flex flex-col gap-3">
<h1 class="sm:text-left w-full text-2xl">Credentials</h1>
<Credentials {data} />
</div>

0 comments on commit 294d0cc

Please sign in to comment.