Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 912e0b70a2 | |||
|
7da22287ff
|
|||
| 5f81f55987 | |||
|
8bcab4661b
|
|||
|
f2ec82762e
|
|||
|
0327bdc7a0
|
|||
|
b3b6731c09
|
|||
|
36de0a3eb3
|
|||
|
839c658075
|
|||
|
12aa8eeb3e
|
|||
|
b655ff2372
|
|||
| 58adc6511a | |||
|
29c4b0013a
|
|||
|
8ed16adeff
|
|||
| 09219ff798 | |||
|
d9cd552c89
|
|||
|
2b82f8798c
|
|||
| d9715139cf | |||
|
c731323b0b
|
|||
| 0d8db9f41f | |||
|
6706c9b0d1
|
|||
| 0dc6fe6704 | |||
|
5f82c5bef8
|
|||
|
47f7583659
|
|||
|
0819dc7b5d
|
|||
|
2010cc3260
|
|||
|
8c1a2d319b
|
|||
|
b57aa535de
|
|||
|
84ab757e11
|
|||
|
cd3508dcb6
|
|||
|
4f5b7f38fb
|
|||
| c34f45ca6f | |||
|
b160ab04b8
|
|||
| c5874e16c6 | |||
|
d9134f6de2
|
|||
| db5c530477 |
86
CHANGELOG.md
86
CHANGELOG.md
@@ -2,8 +2,93 @@
|
|||||||
|
|
||||||
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.3.1](https://git.odit.services/kauft.es/linkylinky-dashboard/compare/0.3.0...0.3.1)
|
||||||
|
|
||||||
|
- Removed length check [`7da2228`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/7da22287ff00b9403d2458b486c5289e7b389415)
|
||||||
|
|
||||||
|
#### [0.3.0](https://git.odit.services/kauft.es/linkylinky-dashboard/compare/0.2.4...0.3.0)
|
||||||
|
|
||||||
|
> 21 August 2021
|
||||||
|
|
||||||
|
- Added new "visits" page [`b655ff2`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/b655ff2372655d1fb7fa6cea8a10b193805f315c)
|
||||||
|
- Added visits overview to sidebar [`36de0a3`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/36de0a3eb305317c829bace18a9661308c8cf0f3)
|
||||||
|
- 🚀RELEASE 0.3.0 [`5f81f55`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/5f81f559876328f57b947e7c19d236e45fbf25c0)
|
||||||
|
- Added apiclient method [`839c658`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/839c65807524646c1c6a677f10042988fb2bccdf)
|
||||||
|
- Added safeguard for random updates [`8bcab46`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/8bcab4661bec3c748cc65078e5187d936be9cdf9)
|
||||||
|
- Fixed link to details [`f2ec827`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/f2ec82762e9bc107f29952709555bc3d893def49)
|
||||||
|
- Enabled y scrolling (whyever that was disabled...) [`0327bdc`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/0327bdc7a0cefda343168c911faa51cd42271673)
|
||||||
|
- Fixed typo in visits query [`b3b6731`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/b3b6731c09d47fff9df96903c75914e7042e28c5)
|
||||||
|
- Missing copy-paste :D [`12aa8ee`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/12aa8eeb3e345ccee10bdb6abca93c5fd84a071a)
|
||||||
|
|
||||||
|
#### [0.2.4](https://git.odit.services/kauft.es/linkylinky-dashboard/compare/0.2.3...0.2.4)
|
||||||
|
|
||||||
|
> 21 August 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE 0.2.4 [`58adc65`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/58adc6511aa1ee573abcf21a176131bf10354747)
|
||||||
|
- Fixed logout redirect [`29c4b00`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/29c4b0013abb0466f59239ae3717f60216cecc1f)
|
||||||
|
- Fixed details link [`8ed16ad`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/8ed16adeffed9e1368615caf6022d8a376337b8a)
|
||||||
|
|
||||||
|
#### [0.2.3](https://git.odit.services/kauft.es/linkylinky-dashboard/compare/0.2.2...0.2.3)
|
||||||
|
|
||||||
|
> 21 August 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE 0.2.3 [`09219ff`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/09219ff7987e6088245d8a871e3a5aaca3f855fd)
|
||||||
|
- Updated login text color [`d9cd552`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/d9cd552c89415625c22c1adcb892c5a789823ce9)
|
||||||
|
- Fixed login replace [`2b82f87`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/2b82f8798cd23f15dc48a5375dc1f5ad1a3abbfd)
|
||||||
|
|
||||||
|
#### [0.2.2](https://git.odit.services/kauft.es/linkylinky-dashboard/compare/0.2.1...0.2.2)
|
||||||
|
|
||||||
|
> 21 August 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE 0.2.2 [`d971513`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/d9715139cf0c5583cb1db43953c34e3293345f68)
|
||||||
|
- Fixxed routing links [`c731323`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/c731323b0bd1b757297b601e7bbc3f5034c04e9c)
|
||||||
|
|
||||||
|
#### [0.2.1](https://git.odit.services/kauft.es/linkylinky-dashboard/compare/0.2.0...0.2.1)
|
||||||
|
|
||||||
|
> 21 August 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE 0.2.1 [`0d8db9f`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/0d8db9f41f84ccaba3211d61e6521d57f43e1b88)
|
||||||
|
- Static links (yay) [`6706c9b`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/6706c9b0d1e396b0c6df6bb9b05d2d25c2a45cba)
|
||||||
|
|
||||||
|
#### [0.2.0](https://git.odit.services/kauft.es/linkylinky-dashboard/compare/0.1.3...0.2.0)
|
||||||
|
|
||||||
|
> 21 August 2021
|
||||||
|
|
||||||
|
- 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)
|
||||||
|
- 🚀RELEASE 0.2.0 [`0dc6fe6`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/0dc6fe670498b6d1022a1ef6c4e5c4b3fcd7e352)
|
||||||
|
- 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)
|
||||||
|
|
||||||
|
> 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)
|
||||||
|
- 🚀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)
|
||||||
|
|
||||||
|
> 18 August 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE 0.1.2 [`c5874e1`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/c5874e16c60030361aedf8b7f8437a4410276f38)
|
||||||
|
- Added fix for custom basepath [`d9134f6`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/d9134f6de2f5587a57f69ad06e828d184c3480a2)
|
||||||
|
|
||||||
|
#### [0.1.1](https://git.odit.services/kauft.es/linkylinky-dashboard/compare/0.1.0...0.1.1)
|
||||||
|
|
||||||
|
> 18 August 2021
|
||||||
|
|
||||||
|
- 🚀RELEASE 0.1.1 [`db5c530`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/db5c530477f9584c77d087c3dea3c3f9156b4773)
|
||||||
|
|
||||||
#### 0.1.0
|
#### 0.1.0
|
||||||
|
|
||||||
|
> 18 August 2021
|
||||||
|
|
||||||
- Created "master" lockfile for yarn [`76089ef`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/76089ef44eacf3ec3de4208bd02757559374c630)
|
- Created "master" lockfile for yarn [`76089ef`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/76089ef44eacf3ec3de4208bd02757559374c630)
|
||||||
- Formatting/Linting [`08520ac`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/08520ac61638df3b81aed95260bd52c710fb2dfc)
|
- Formatting/Linting [`08520ac`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/08520ac61638df3b81aed95260bd52c710fb2dfc)
|
||||||
- Added link management page [`a7e4a98`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/a7e4a98b2b302dac161bccdf13cb1b769dfa01d4)
|
- Added link management page [`a7e4a98`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/a7e4a98b2b302dac161bccdf13cb1b769dfa01d4)
|
||||||
@@ -17,6 +102,7 @@ All notable changes to this project will be documented in this file. Dates are d
|
|||||||
- Added text and icons to statscards [`1c43011`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/1c43011842cfc2bd62abaef45af9fccd3e20b250)
|
- Added text and icons to statscards [`1c43011`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/1c43011842cfc2bd62abaef45af9fccd3e20b250)
|
||||||
- Prepared for transition to extensin repo [`ba74bc4`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/ba74bc4161476f87d209cb864a91fafa58cc55cf)
|
- Prepared for transition to extensin repo [`ba74bc4`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/ba74bc4161476f87d209cb864a91fafa58cc55cf)
|
||||||
- Added docker basics [`44c77a8`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/44c77a8aadb0be115bf465595b27ece74ac63bf2)
|
- Added docker basics [`44c77a8`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/44c77a8aadb0be115bf465595b27ece74ac63bf2)
|
||||||
|
- 🚀RELEASE 0.1.0 [`5d4785d`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/5d4785dea560dc05b8db699194762382ee9e389a)
|
||||||
- Added drone builds for latest and tags [`2346275`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/2346275add471a63e5facb32b839f6fbe3bf9abb)
|
- Added drone builds for latest and tags [`2346275`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/2346275add471a63e5facb32b839f6fbe3bf9abb)
|
||||||
- Raw extension stuff [`0da135f`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/0da135f27134e4fb443daeb0b9b5aa8e6cb87146)
|
- Raw extension stuff [`0da135f`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/0da135f27134e4fb443daeb0b9b5aa8e6cb87146)
|
||||||
- Added basic login page [`5263d19`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/5263d1974a25fe2f9a565e8fb61d9a2295acf8c8)
|
- Added basic login page [`5263d19`](https://git.odit.services/kauft.es/linkylinky-dashboard/commit/5263d1974a25fe2f9a565e8fb61d9a2295acf8c8)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@odit/linkylinky-dashboard",
|
"name": "@odit/linkylinky-dashboard",
|
||||||
"version": "0.1.0",
|
"version": "0.3.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "svelte-kit dev",
|
"dev": "svelte-kit dev",
|
||||||
"build": "svelte-kit build",
|
"build": "svelte-kit build",
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
"format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ."
|
"format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/kit": "next",
|
"@sveltejs/kit": "1.0.0-next.147",
|
||||||
"autoprefixer": "^10.3.1",
|
"autoprefixer": "^10.3.1",
|
||||||
"cssnano": "^5.0.6",
|
"cssnano": "^5.0.6",
|
||||||
"eslint": "^7.22.0",
|
"eslint": "^7.22.0",
|
||||||
|
|||||||
@@ -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,23 @@ export default class Apiclient {
|
|||||||
).data;
|
).data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API-Getter for the linkylinky api all vists endpoint (needs auth)
|
||||||
|
* @returns Url visit details for each visit in an array of objects.
|
||||||
|
*/
|
||||||
|
static async getVisits() {
|
||||||
|
return (
|
||||||
|
await axios.get(`https://kauft.es/api/visits`, {
|
||||||
|
headers: { Authorization: `Bearer ${UserStore.state.token}` }
|
||||||
|
})
|
||||||
|
).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 +87,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 +103,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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -58,7 +46,7 @@
|
|||||||
<nav>
|
<nav>
|
||||||
<a
|
<a
|
||||||
class="flex items-center px-4 py-2 text-gray-700 bg-gray-200 rounded-md dark:bg-gray-700 dark:text-gray-200"
|
class="flex items-center px-4 py-2 text-gray-700 bg-gray-200 rounded-md dark:bg-gray-700 dark:text-gray-200"
|
||||||
href="/"
|
href="./"
|
||||||
>
|
>
|
||||||
<svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path
|
<path
|
||||||
@@ -78,7 +66,7 @@
|
|||||||
{#if logged_in}
|
{#if logged_in}
|
||||||
<a
|
<a
|
||||||
class="flex items-center px-4 py-2 mt-5 text-gray-600 transition-colors duration-200 transform rounded-md dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700 dark:hover:text-gray-200 hover:text-gray-700"
|
class="flex items-center px-4 py-2 mt-5 text-gray-600 transition-colors duration-200 transform rounded-md dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700 dark:hover:text-gray-200 hover:text-gray-700"
|
||||||
href="/links"
|
href="./links"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -97,6 +85,33 @@
|
|||||||
|
|
||||||
<span class="mx-4 font-medium">Manage Links</span>
|
<span class="mx-4 font-medium">Manage Links</span>
|
||||||
</a>
|
</a>
|
||||||
|
<a
|
||||||
|
class="flex items-center px-4 py-2 mt-5 text-gray-600 transition-colors duration-200 transform rounded-md dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700 dark:hover:text-gray-200 hover:text-gray-700"
|
||||||
|
href="./visits"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="h-5 w-5"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
stroke-width="2"
|
||||||
|
d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<span class="mx-4 font-medium">All Visits</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
<!-- <a
|
<!-- <a
|
||||||
class="flex items-center px-4 py-2 mt-5 text-gray-600 transition-colors duration-200 transform rounded-md dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700 dark:hover:text-gray-200 hover:text-gray-700"
|
class="flex items-center px-4 py-2 mt-5 text-gray-600 transition-colors duration-200 transform rounded-md dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700 dark:hover:text-gray-200 hover:text-gray-700"
|
||||||
@@ -145,7 +160,7 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<a
|
<a
|
||||||
class="flex items-center px-4 py-2 mt-5 text-gray-600 transition-colors duration-200 transform rounded-md dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700 dark:hover:text-gray-200 hover:text-gray-700"
|
class="flex items-center px-4 py-2 mt-5 text-gray-600 transition-colors duration-200 transform rounded-md dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700 dark:hover:text-gray-200 hover:text-gray-700"
|
||||||
href="/login"
|
href="./login"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -167,13 +182,17 @@
|
|||||||
{/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>
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const userStore = () => {
|
|||||||
//
|
//
|
||||||
return state;
|
return state;
|
||||||
});
|
});
|
||||||
location.replace("/");
|
location.replace("./");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,31 @@
|
|||||||
<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-y-scroll">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -70,7 +82,7 @@
|
|||||||
Delete
|
Delete
|
||||||
</button>
|
</button>
|
||||||
<a
|
<a
|
||||||
href={`/details?shortcode=${url.shortcode}`}
|
href={`./details?shortcode=${url.shortcode}`}
|
||||||
class="px-4 py-2 font-medium tracking-wide text-white capitalize transition-colors duration-200 transform bg-blue-600 rounded-md hover:bg-blue-700 focus:outline-none focus:bg-blue-700"
|
class="px-4 py-2 font-medium tracking-wide text-white capitalize transition-colors duration-200 transform bg-blue-600 rounded-md hover:bg-blue-700 focus:outline-none focus:bg-blue-700"
|
||||||
>
|
>
|
||||||
Details
|
Details
|
||||||
|
|||||||
@@ -7,12 +7,11 @@ 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);
|
||||||
UserStore.login(login);
|
UserStore.login(login);
|
||||||
location.replace("/");
|
location.replace("./");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -31,7 +30,7 @@ import Apiclient from '$lib/Apiclient';
|
|||||||
|
|
||||||
<div class="w-full mt-4">
|
<div class="w-full mt-4">
|
||||||
<input
|
<input
|
||||||
class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border border-gray-300 rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-blue-500 dark:focus:border-blue-500 focus:outline-none focus:ring"
|
class="block w-full px-4 py-2 mt-2 text-gray-700 dark:text-gray-400 placeholder-gray-500 bg-white border border-gray-300 rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-blue-500 dark:focus:border-blue-500 focus:outline-none focus:ring"
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Username"
|
placeholder="Username"
|
||||||
aria-label="Username"
|
aria-label="Username"
|
||||||
@@ -41,7 +40,7 @@ import Apiclient from '$lib/Apiclient';
|
|||||||
|
|
||||||
<div class="w-full mt-4">
|
<div class="w-full mt-4">
|
||||||
<input
|
<input
|
||||||
class="block w-full px-4 py-2 mt-2 text-gray-700 placeholder-gray-500 bg-white border border-gray-300 rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-blue-500 dark:focus:border-blue-500 focus:outline-none focus:ring"
|
class="block w-full px-4 py-2 mt-2 text-gray-700 dark:text-gray-400 placeholder-gray-500 bg-white border border-gray-300 rounded-md dark:bg-gray-800 dark:border-gray-600 dark:placeholder-gray-400 focus:border-blue-500 dark:focus:border-blue-500 focus:outline-none focus:ring"
|
||||||
type="password"
|
type="password"
|
||||||
placeholder="Password"
|
placeholder="Password"
|
||||||
aria-label="Password"
|
aria-label="Password"
|
||||||
|
|||||||
69
src/routes/visits.svelte
Normal file
69
src/routes/visits.svelte
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
<script>
|
||||||
|
import Apiclient from '$lib/Apiclient';
|
||||||
|
import UserStore from '$lib/UserStore';
|
||||||
|
import { onDestroy } from 'svelte';
|
||||||
|
|
||||||
|
$: visits = [];
|
||||||
|
let visitQuery;
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
visitQuery = Apiclient.getVisits().then((res) => {
|
||||||
|
visits = res;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(unsubscribe);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<h2 class="text-3xl font-bold text-gray-800 dark:text-gray-100 pb-6">View all visits</h2>
|
||||||
|
<div class="rounded-xl">
|
||||||
|
<table class="min-w-full divide-y divide-gray-200">
|
||||||
|
<thead class="bg-gray-50 dark:bg-gray-900 text-gray-800 dark:text-gray-100">
|
||||||
|
<tr>
|
||||||
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
|
||||||
|
Shortcode
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
|
||||||
|
Provider
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
|
||||||
|
Timestamp
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="bg-white dark:bg-gray-700 divide-y divide-gray-200 dark:text-gray-100" x-max="1">
|
||||||
|
{#await visitQuery}
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-200"
|
||||||
|
>
|
||||||
|
Loading data...
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm"> Loading data... </td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm"> Loading data... </td>
|
||||||
|
</tr>
|
||||||
|
{:then}
|
||||||
|
{#each visits as visit}
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-200"
|
||||||
|
>
|
||||||
|
{#if visit.provider == "native"}
|
||||||
|
<a href={`./details?shortcode=${visit.shortcode}`}>{visit.shortcode}</a>
|
||||||
|
{:else}
|
||||||
|
{visit.shortcode}
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm">
|
||||||
|
{visit.provider}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm"> {visit.timestamp} </td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
{/await}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
@@ -9,7 +9,10 @@ const config = {
|
|||||||
adapter: staticAdapter(),
|
adapter: staticAdapter(),
|
||||||
files: {
|
files: {
|
||||||
assets: 'static'
|
assets: 'static'
|
||||||
}
|
},
|
||||||
|
paths: {
|
||||||
|
base: '/dashboard',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
preprocess: [
|
preprocess: [
|
||||||
|
|||||||
@@ -209,10 +209,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@sveltejs/adapter-static/-/adapter-static-1.0.0-next.16.tgz#656c90666edd730ccc9bfb89e3f7ece56e7ac7c8"
|
resolved "https://registry.yarnpkg.com/@sveltejs/adapter-static/-/adapter-static-1.0.0-next.16.tgz#656c90666edd730ccc9bfb89e3f7ece56e7ac7c8"
|
||||||
integrity sha512-xGFcg+GHF0BL1fyWx2vCzlYj4S4R+Od9cF00soo1TVp/scGOi1G9grSYYW4x5H+iDn1sscoJ65OGBGWIcOgrXg==
|
integrity sha512-xGFcg+GHF0BL1fyWx2vCzlYj4S4R+Od9cF00soo1TVp/scGOi1G9grSYYW4x5H+iDn1sscoJ65OGBGWIcOgrXg==
|
||||||
|
|
||||||
"@sveltejs/kit@next":
|
"@sveltejs/kit@1.0.0-next.147":
|
||||||
version "1.0.0-next.151"
|
version "1.0.0-next.147"
|
||||||
resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-1.0.0-next.151.tgz#6cd086e0f73c40de1ed9625a69af0e2f2773749c"
|
resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-1.0.0-next.147.tgz#1dad06fd7f4365405beebdcd12b410a52c3a03b0"
|
||||||
integrity sha512-dioqHt4XxqiZ+5dEL6hFG1fBuVMc5t9l9bmvUeJX6neyut432IcVLdl4t3utmD10Lu8fbybJPRkHy1PVAbHWwQ==
|
integrity sha512-rAABsKlC1K/B4VfqT2SaVO29t+OV8deseSJ9l+hV7j9zkswTwiJ7h37tZ5SfnvMgCHemcNjXg8Gzg+0U1MCfEA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@sveltejs/vite-plugin-svelte" "^1.0.0-next.16"
|
"@sveltejs/vite-plugin-svelte" "^1.0.0-next.16"
|
||||||
cheap-watch "^1.0.3"
|
cheap-watch "^1.0.3"
|
||||||
|
|||||||
Reference in New Issue
Block a user