Compare commits

...

10 Commits
0.1.3 ... 0.2.0

Author SHA1 Message Date
Nicolai Ort 0dc6fe6704 🚀RELEASE 0.2.0
continuous-integration/drone/push Build is passing Details
2021-08-21 08:47:51 +02:00
Nicolai Ort 5f82c5bef8
Removed useless console log
continuous-integration/drone/push Build is passing Details
2021-08-21 08:47:22 +02:00
Nicolai Ort 47f7583659
Added comments to apiclient 2021-08-21 08:46:56 +02:00
Nicolai Ort 0819dc7b5d
Added comments to fix
closes #1
2021-08-21 08:40:32 +02:00
Nicolai Ort 2010cc3260
No longer showing logged out users the profile pic thingy
continuous-integration/drone/push Build is passing Details
2021-08-21 08:38:01 +02:00
Nicolai Ort 8c1a2d319b
Now ignoring status on logout 2021-08-21 08:36:38 +02:00
Nicolai Ort b57aa535de
Removed unused function 2021-08-21 08:35:18 +02:00
Nicolai Ort 84ab757e11
More userstore fixes
ref #1
2021-08-21 08:34:54 +02:00
Nicolai Ort cd3508dcb6
Weired fucking fix for the userstore data not being instantly loaded....
ref #1
2021-08-21 08:34:33 +02:00
Nicolai Ort 4f5b7f38fb
First mitigations for localforage error stuff
continuous-integration/drone/push Build is passing Details
ref #1
2021-08-21 07:43:31 +02:00
8 changed files with 117 additions and 33 deletions

View File

@ -2,9 +2,24 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC. All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [0.2.0](https://git.odit.services/kauft.es/linkylinky-dashboard/compare/0.1.3...0.2.0)
- Added comments to fix [`#1`](https://git.odit.services/kauft.es/linkylinky-dashboard/issues/1)
- More userstore fixes [`84ab757`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/84ab757e1159eac3cd160aac158873deaf51bb3f)
- Added comments to apiclient [`47f7583`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/47f75836597ff13a32660e03d61629ddd173f86c)
- No longer showing logged out users the profile pic thingy [`2010cc3`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/2010cc326019085ca37fcdc8b8dab8445006b6fa)
- Weired fucking fix for the userstore data not being instantly loaded.... [`cd3508d`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/cd3508dcb61f165a7c83d6f0f9332f799677cb9f)
- First mitigations for localforage error stuff [`4f5b7f3`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/4f5b7f38fb625e4da0ea3f432df958029ee8d25c)
- Now ignoring status on logout [`8c1a2d3`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/8c1a2d319b9fb6e63c3e27163392bad1becba8dd)
- Removed unused function [`b57aa53`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/b57aa535de94e22f19754b729cc6b63166a07a9d)
- Removed useless console log [`5f82c5b`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/5f82c5bef8011bd7cee853bde76433585d93b88b)
#### [0.1.3](https://git.odit.services/kauft.es/linkylinky-dashboard/compare/0.1.2...0.1.3) #### [0.1.3](https://git.odit.services/kauft.es/linkylinky-dashboard/compare/0.1.2...0.1.3)
> 18 August 2021
- Tmp fix for the build fail, for more info see: https://github.com/sveltejs/kit/issues/2230 [`b160ab0`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/b160ab04b8324daa6389c947356bc58c865059aa) - Tmp fix for the build fail, for more info see: https://github.com/sveltejs/kit/issues/2230 [`b160ab0`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/b160ab04b8324daa6389c947356bc58c865059aa)
- 🚀RELEASE 0.1.3 [`c34f45c`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/c34f45ca6f8a7fe955e8d82f0f2c10b3cdfd54ce)
#### [0.1.2](https://git.odit.services/kauft.es/linkylinky-dashboard/compare/0.1.1...0.1.2) #### [0.1.2](https://git.odit.services/kauft.es/linkylinky-dashboard/compare/0.1.1...0.1.2)

View File

@ -1,6 +1,6 @@
{ {
"name": "@odit/linkylinky-dashboard", "name": "@odit/linkylinky-dashboard",
"version": "0.1.3", "version": "0.2.0",
"scripts": { "scripts": {
"dev": "svelte-kit dev", "dev": "svelte-kit dev",
"build": "svelte-kit build", "build": "svelte-kit build",

View File

@ -11,12 +11,21 @@ axios.interceptors.response.use(response => {
}); });
export default class Apiclient { export default class Apiclient {
/**
* API-Getter for the linkylinky api stats endpoint
* @returns Current linkylinky stats (url count, total visits)
*/
static async getStats() { static async getStats() {
return ( return (
await axios.get('https://kauft.es/api/stats') await axios.get('https://kauft.es/api/stats')
).data; ).data;
} }
/**
* API-Getter for the linkylinky api all urls endpoint (needs auth)
* @returns All urls with shortcode, target, full url and visits in an array of objects
*/
static async getUrls() { static async getUrls() {
return ( return (
await axios.get('https://kauft.es/api?showVisits=true', { await axios.get('https://kauft.es/api?showVisits=true', {
@ -25,7 +34,13 @@ export default class Apiclient {
).data; ).data;
} }
/**
* API-Getter for the linkylinky api url details endpoint (needs auth)
* @param {*} shortcode The shortcode of your favourite url
* @returns Url shortcode, target, full url and visit count in an object
*/
static async getUrlDetails(shortcode) { static async getUrlDetails(shortcode) {
//TODO: Handle 404
return ( return (
await axios.get(`https://kauft.es/api/${shortcode}`, { await axios.get(`https://kauft.es/api/${shortcode}`, {
headers: { Authorization: `Bearer ${UserStore.state.token}` } headers: { Authorization: `Bearer ${UserStore.state.token}` }
@ -33,7 +48,13 @@ export default class Apiclient {
).data; ).data;
} }
/**
* API-Getter for the linkylinky api url vists endpoint (needs auth)
* @param {*} shortcode The shortcode of your favourite url
* @returns Url visit details as an object for each visits (r/n they only contain timestamps)
*/
static async getUrlVisits(shortcode) { static async getUrlVisits(shortcode) {
//TODO: Handle 404
return ( return (
await axios.get(`https://kauft.es/api/${shortcode}/visits`, { await axios.get(`https://kauft.es/api/${shortcode}/visits`, {
headers: { Authorization: `Bearer ${UserStore.state.token}` } headers: { Authorization: `Bearer ${UserStore.state.token}` }
@ -41,6 +62,11 @@ export default class Apiclient {
).data; ).data;
} }
/**
* API-Delet for the linkylinky api url deletion endpoint (needs auth)
* @param {*} shortcode The shortcode of your most hated url
* @returns Just a 204 (no matter if the url got deleted or didn't exist in the first place)
*/
static async deleteUrl(shortcode) { static async deleteUrl(shortcode) {
return ( return (
await axios.delete(`https://kauft.es/api/${shortcode}`, { await axios.delete(`https://kauft.es/api/${shortcode}`, {
@ -49,6 +75,12 @@ export default class Apiclient {
).status; ).status;
} }
/**
* Login and receive a JWT for future auth.
* @param {*} username Your username (cleartext)
* @param {*} password Your password (cleartext)
* @returns A user login object containing your jwt
*/
static async login(username, password) { static async login(username, password) {
return ( return (
await axios.post(`https://kauft.es/api/auth/login`, {}, { await axios.post(`https://kauft.es/api/auth/login`, {}, {
@ -59,10 +91,16 @@ export default class Apiclient {
).data; ).data;
} }
/**
* Log yourself out -> Invalidates your current (and past) JWTs
* @returns Done!
*/
static async logout() { static async logout() {
return ( return (
await axios.post(`https://kauft.es/api/auth/logout`, {}, { await axios.post(`https://kauft.es/api/auth/logout`, {}, {
headers: { Authorization: `Bearer ${UserStore.state.token}` } headers: { Authorization: `Bearer ${UserStore.state.token}`,
validateStatus: null
}
}) })
).data; ).data;
} }

View File

@ -1,22 +1,10 @@
<script> <script>
import UserStore from '$lib/UserStore'; import UserStore from '$lib/UserStore';
import { onDestroy, onMount } from 'svelte'; import { onDestroy } from 'svelte';
import * as localForage from 'localforage';
import Apiclient from './Apiclient'; import Apiclient from './Apiclient';
$: logged_in = false; $: logged_in = false;
UserStore.init();
onMount(() => {
localForage.getItem('userdata', (err, value) => {
if (value) {
if (value.token) {
UserStore.login(value);
}
}
});
});
const unsubscribe = UserStore.subscribe((value) => { const unsubscribe = UserStore.subscribe((value) => {
logged_in = value.isLoggedIn; logged_in = value.isLoggedIn;
}); });
@ -24,7 +12,7 @@
onDestroy(unsubscribe); onDestroy(unsubscribe);
async function logout() { async function logout() {
await Apiclient.logout().catch((e)=>{}); await Apiclient.logout().catch((e) => {});
UserStore.logout(); UserStore.logout();
} }
</script> </script>
@ -167,13 +155,15 @@
{/if} {/if}
</nav> </nav>
<div class="flex items-center px-4 -mx-2"> {#if logged_in}
<img <div class="flex items-center px-4 -mx-2">
class="object-cover mx-2 rounded-full h-9 w-9" <img
src="https://images.unsplash.com/photo-1531427186611-ecfd6d936c79?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80" class="object-cover mx-2 rounded-full h-9 w-9"
alt="avatar" src="https://images.unsplash.com/photo-1531427186611-ecfd6d936c79?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=634&q=80"
/> alt="avatar"
<h4 class="mx-2 font-medium text-gray-800 dark:text-gray-200 hover:underline">John Doe</h4> />
</div> <h4 class="mx-2 font-medium text-gray-800 dark:text-gray-200 hover:underline">Username here</h4>
</div>
{/if}
</div> </div>
</div> </div>

View File

@ -1,11 +1,30 @@
<script> <script>
import '../app.postcss'; import '../app.postcss';
import Sidebar from '$lib/Sidebar.svelte'; import Sidebar from '$lib/Sidebar.svelte';
import UserStore from '$lib/UserStore';
import { onMount } from 'svelte';
import * as localForage from 'localforage';
/**
* Master init for all things userstore, b/c async stuff somethimes does weired shit.
* Yes i know this isn't the best way to implement this, but linkylinky dashboard is just a oneshot sideproject r/n.
*/
onMount(() => {
UserStore.init();
localForage.getItem('userdata', (err, value) => {
if (value) {
if (value.token) {
UserStore.login(value);
}
}
});
});
</script> </script>
<div style="min-height: 640px;" class="bg-white dark:bg-gray-800"> <div style="min-height: 640px;" class="bg-white dark:bg-gray-800">
<div class="h-screen flex overflow-hidden"> <div class="h-screen flex overflow-hidden">
<Sidebar/> <Sidebar />
<div class="px-4 py-8 flex flex-col w-0 flex-1 overflow-hidden"> <div class="px-4 py-8 flex flex-col w-0 flex-1 overflow-hidden">
<slot /> <slot />
</div> </div>

View File

@ -1,8 +1,11 @@
<script> <script>
import { page } from '$app/stores'; import { page } from '$app/stores';
import Apiclient from '$lib/Apiclient'; import Apiclient from '$lib/Apiclient';
import UserStore from '$lib/UserStore';
import { onDestroy } from 'svelte';
let shortcode = $page.query.get('shortcode'); let shortcode = $page.query.get('shortcode');
$: urlDetails = { $: urlDetails = {
shortcode: 'Loading...', shortcode: 'Loading...',
url: 'Loading...', url: 'Loading...',
@ -10,13 +13,21 @@
visits: 'Loading...' visits: 'Loading...'
}; };
$: urlVisists = []; $: urlVisists = [];
let visitQuery;
Apiclient.getUrlDetails(shortcode).then((res) => { // Yes i know this isn't the best way to implement this, but linkylinky dashboard is just a oneshot sideproject r/n.
urlDetails = res; const unsubscribe = UserStore.subscribe((value) => {
}); if (value.isLoggedIn) {
let visitQuery = Apiclient.getUrlVisits(shortcode).then((res) => { Apiclient.getUrlDetails(shortcode).then((res) => {
urlVisists = res; urlDetails = res;
});
visitQuery = Apiclient.getUrlVisits(shortcode).then((res) => {
urlVisists = res;
});
}
}); });
onDestroy(unsubscribe);
</script> </script>
<h2 class="text-3xl font-bold text-gray-800 dark:text-gray-100 pb-6">Details: {shortcode}</h2> <h2 class="text-3xl font-bold text-gray-800 dark:text-gray-100 pb-6">Details: {shortcode}</h2>

View File

@ -1,10 +1,22 @@
<script> <script>
import Apiclient from '$lib/Apiclient'; import Apiclient from '$lib/Apiclient';
import UserStore from '$lib/UserStore';
import { onDestroy } from 'svelte';
$: urls = []; $: urls = [];
let urlQuery = Apiclient.getUrls().then((res) => { let urlQuery;
urls = res;
// Yes i know this isn't the best way to implement this, but linkylinky dashboard is just a oneshot sideproject r/n.
const unsubscribe = UserStore.subscribe((value) => {
if (value.isLoggedIn) {
urlQuery = Apiclient.getUrls().then((res) => {
urls = res;
});
}
}); });
onDestroy(unsubscribe);
function deleteUrl(shortcode) { function deleteUrl(shortcode) {
Apiclient.deleteUrl(shortcode).then(() => { Apiclient.deleteUrl(shortcode).then(() => {
urls = urls.filter((url) => url.shortcode != shortcode); urls = urls.filter((url) => url.shortcode != shortcode);

View File

@ -7,7 +7,6 @@ import Apiclient from '$lib/Apiclient';
$: password = ""; $: password = "";
$: error = ""; $: error = "";
UserStore.init();
async function login() { async function login() {
try { try {
const login = await Apiclient.login(username, password); const login = await Apiclient.login(username, password);