Browse Source

Formatting/Linting

main
Nicolai Ort 4 months ago
parent
commit
08520ac616
Signed by: niggl GPG Key ID: 13AFA55AF62F269F
  1. 1
      README.md
  2. 24
      manifest.json
  3. 41
      postcss.config.cjs
  4. 2
      src/app.postcss
  5. 68
      src/lib/Apiclient.js
  6. 304
      src/lib/Sidebar.svelte
  7. 29
      src/lib/Statscard.svelte
  8. 132
      src/routes/details.svelte
  9. 2
      src/routes/index.svelte
  10. 168
      src/routes/links.svelte
  11. 42
      svelte.config.js
  12. 24
      tailwind.config.cjs

1
README.md

@ -1,2 +1,3 @@
# LinkyLinky Extension
> The companion extension for LinkyLinky

24
manifest.json

@ -1,13 +1,11 @@
{
"manifest_version": 2,
"name": "LinkyLinky",
"version": "0.0.1",
"description": "A simple url shortener",
"short_name": "LinkyLinky",
"permissions": [
"activeTab"
],
"browser_action": {
"default_popup": "build/index.html"
}
}
{
"manifest_version": 2,
"name": "LinkyLinky",
"version": "0.0.1",
"description": "A simple url shortener",
"short_name": "LinkyLinky",
"permissions": ["activeTab"],
"browser_action": {
"default_popup": "build/index.html"
}
}

41
postcss.config.cjs

@ -1,20 +1,21 @@
const tailwindcss = require("tailwindcss");
const autoprefixer = require("autoprefixer");
const cssnano = require("cssnano");
const mode = process.env.NODE_ENV;
const dev = mode === "development";
const config = {
plugins: [
//Some plugins, like postcss-nested, need to run before Tailwind,
tailwindcss(),
//But others, like autoprefixer, need to run after,
autoprefixer(),
!dev && cssnano({
preset: "default",
})
],
};
module.exports = config;
const tailwindcss = require('tailwindcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const mode = process.env.NODE_ENV;
const dev = mode === 'development';
const config = {
plugins: [
//Some plugins, like postcss-nested, need to run before Tailwind,
tailwindcss(),
//But others, like autoprefixer, need to run after,
autoprefixer(),
!dev &&
cssnano({
preset: 'default'
})
]
};
module.exports = config;

2
src/app.postcss

@ -1,4 +1,4 @@
@tailwind base;
/* Write your global styles here, in PostCSS syntax */
@tailwind components;
@tailwind utilities
@tailwind utilities;

68
src/lib/Apiclient.js

@ -1,30 +1,38 @@
import axios from 'axios';
const config = {
username: "niggl",
password: "niggl"
}
export default class Apiclient {
static async getUrls() {
return (await axios.get("https://kauft.es/api?showVisits=true", {
auth: config
})).data
}
static async getUrlDetails(shortcode) {
return (await axios.get(`https://kauft.es/api/${shortcode}`, {
auth: config
})).data
}
static async getUrlVisits(shortcode) {
return (await axios.get(`https://kauft.es/api/${shortcode}/visits`, {
auth: config
})).data
}
static async deleteUrl(shortcode) {
return (await axios.delete(`https://kauft.es/api/${shortcode}`, {
auth: config
})).status
}
}
import axios from 'axios';
const config = {
username: 'niggl',
password: '9VEBc596T7tiPB7mNJukfeH9LfGzrrJN'
};
export default class Apiclient {
static async getUrls() {
return (
await axios.get('https://kauft.es/api?showVisits=true', {
auth: config
})
).data;
}
static async getUrlDetails(shortcode) {
return (
await axios.get(`https://kauft.es/api/${shortcode}`, {
auth: config
})
).data;
}
static async getUrlVisits(shortcode) {
return (
await axios.get(`https://kauft.es/api/${shortcode}/visits`, {
auth: config
})
).data;
}
static async deleteUrl(shortcode) {
return (
await axios.delete(`https://kauft.es/api/${shortcode}`, {
auth: config
})
).status;
}
}

304
src/lib/Sidebar.svelte

@ -1,152 +1,152 @@
<script>
export let logged_in = true;
</script>
<div
class="flex flex-col w-64 h-screen px-4 py-8 bg-white border-r dark:bg-gray-800 dark:border-gray-600"
>
<h2 class="text-3xl font-semibold text-gray-800 dark:text-white">LinkyLinky</h2>
<div class="relative mt-6">
<span class="absolute inset-y-0 left-0 flex items-center pl-3">
<svg class="w-5 h-5 text-gray-400" viewBox="0 0 24 24" fill="none">
<path
d="M21 21L15 15M17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10Z"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</span>
<input
type="text"
class="w-full py-3 pl-10 pr-4 text-gray-700 bg-white border border-gray-300 rounded-md dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 focus:border-blue-500 dark:focus:border-blue-500 focus:outline-none focus:ring"
placeholder="Search"
/>
</div>
<div class="flex flex-col justify-between flex-1 mt-6">
<nav>
<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"
href="/"
>
<svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M19 11H5M19 11C20.1046 11 21 11.8954 21 13V19C21 20.1046 20.1046 21 19 21H5C3.89543 21 3 20.1046 3 19V13C3 11.8954 3.89543 11 5 11M19 11V9C19 7.89543 18.1046 7 17 7M5 11V9C5 7.89543 5.89543 7 7 7M7 7V5C7 3.89543 7.89543 3 9 3H15C16.1046 3 17 3.89543 17 5V7M7 7H17"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<span class="mx-4 font-medium">Dashboard</span>
</a>
<hr class="my-6 dark:border-gray-600" />
{#if logged_in}
<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="/links"
>
<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="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"
/>
</svg>
<span class="mx-4 font-medium">Manage Links</span>
</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="#"
>
<svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M10.3246 4.31731C10.751 2.5609 13.249 2.5609 13.6754 4.31731C13.9508 5.45193 15.2507 5.99038 16.2478 5.38285C17.7913 4.44239 19.5576 6.2087 18.6172 7.75218C18.0096 8.74925 18.5481 10.0492 19.6827 10.3246C21.4391 10.751 21.4391 13.249 19.6827 13.6754C18.5481 13.9508 18.0096 15.2507 18.6172 16.2478C19.5576 17.7913 17.7913 19.5576 16.2478 18.6172C15.2507 18.0096 13.9508 18.5481 13.6754 19.6827C13.249 21.4391 10.751 21.4391 10.3246 19.6827C10.0492 18.5481 8.74926 18.0096 7.75219 18.6172C6.2087 19.5576 4.44239 17.7913 5.38285 16.2478C5.99038 15.2507 5.45193 13.9508 4.31731 13.6754C2.5609 13.249 2.5609 10.751 4.31731 10.3246C5.45193 10.0492 5.99037 8.74926 5.38285 7.75218C4.44239 6.2087 6.2087 4.44239 7.75219 5.38285C8.74926 5.99037 10.0492 5.45193 10.3246 4.31731Z"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M15 12C15 13.6569 13.6569 15 12 15C10.3431 15 9 13.6569 9 12C9 10.3431 10.3431 9 12 9C13.6569 9 15 10.3431 15 12Z"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<span class="mx-4 font-medium">Settings</span>
</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="#"
>
<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="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
/>
</svg>
<span class="mx-4 font-medium">Logout</span>
</a>
{:else}
<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="#"
>
<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="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1"
/>
</svg>
<span class="mx-4 font-medium">Login</span>
</a>
{/if}
</nav>
<div class="flex items-center px-4 -mx-2">
<img
class="object-cover mx-2 rounded-full h-9 w-9"
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>
</div>
</div>
<script>
export let logged_in = true;
</script>
<div
class="flex flex-col w-64 h-screen px-4 py-8 bg-white border-r dark:bg-gray-800 dark:border-gray-600"
>
<h2 class="text-3xl font-semibold text-gray-800 dark:text-white">LinkyLinky</h2>
<div class="relative mt-6">
<span class="absolute inset-y-0 left-0 flex items-center pl-3">
<svg class="w-5 h-5 text-gray-400" viewBox="0 0 24 24" fill="none">
<path
d="M21 21L15 15M17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10Z"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</span>
<input
type="text"
class="w-full py-3 pl-10 pr-4 text-gray-700 bg-white border border-gray-300 rounded-md dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 focus:border-blue-500 dark:focus:border-blue-500 focus:outline-none focus:ring"
placeholder="Search"
/>
</div>
<div class="flex flex-col justify-between flex-1 mt-6">
<nav>
<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"
href="/"
>
<svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M19 11H5M19 11C20.1046 11 21 11.8954 21 13V19C21 20.1046 20.1046 21 19 21H5C3.89543 21 3 20.1046 3 19V13C3 11.8954 3.89543 11 5 11M19 11V9C19 7.89543 18.1046 7 17 7M5 11V9C5 7.89543 5.89543 7 7 7M7 7V5C7 3.89543 7.89543 3 9 3H15C16.1046 3 17 3.89543 17 5V7M7 7H17"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<span class="mx-4 font-medium">Dashboard</span>
</a>
<hr class="my-6 dark:border-gray-600" />
{#if logged_in}
<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="/links"
>
<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="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"
/>
</svg>
<span class="mx-4 font-medium">Manage Links</span>
</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="#"
>
<svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M10.3246 4.31731C10.751 2.5609 13.249 2.5609 13.6754 4.31731C13.9508 5.45193 15.2507 5.99038 16.2478 5.38285C17.7913 4.44239 19.5576 6.2087 18.6172 7.75218C18.0096 8.74925 18.5481 10.0492 19.6827 10.3246C21.4391 10.751 21.4391 13.249 19.6827 13.6754C18.5481 13.9508 18.0096 15.2507 18.6172 16.2478C19.5576 17.7913 17.7913 19.5576 16.2478 18.6172C15.2507 18.0096 13.9508 18.5481 13.6754 19.6827C13.249 21.4391 10.751 21.4391 10.3246 19.6827C10.0492 18.5481 8.74926 18.0096 7.75219 18.6172C6.2087 19.5576 4.44239 17.7913 5.38285 16.2478C5.99038 15.2507 5.45193 13.9508 4.31731 13.6754C2.5609 13.249 2.5609 10.751 4.31731 10.3246C5.45193 10.0492 5.99037 8.74926 5.38285 7.75218C4.44239 6.2087 6.2087 4.44239 7.75219 5.38285C8.74926 5.99037 10.0492 5.45193 10.3246 4.31731Z"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M15 12C15 13.6569 13.6569 15 12 15C10.3431 15 9 13.6569 9 12C9 10.3431 10.3431 9 12 9C13.6569 9 15 10.3431 15 12Z"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<span class="mx-4 font-medium">Settings</span>
</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="#"
>
<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="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
/>
</svg>
<span class="mx-4 font-medium">Logout</span>
</a>
{:else}
<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="#"
>
<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="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1"
/>
</svg>
<span class="mx-4 font-medium">Login</span>
</a>
{/if}
</nav>
<div class="flex items-center px-4 -mx-2">
<img
class="object-cover mx-2 rounded-full h-9 w-9"
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>
</div>
</div>

29
src/lib/Statscard.svelte

@ -1,15 +1,14 @@
<script>
export let title = 'Title';
export let count = 0;
</script>
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-900">
<div
class="p-3 mr-4 text-red-500 bg-red-100 rounded-full dark:text-red-100 dark:bg-red-500"
>
<slot></slot>
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">{title}</p>
<p class="text-lg font-semibold text-gray-700 dark:text-gray-200">{count}</p>
</div>
</div>
<script>
export let title = 'Title';
export let count = 0;
</script>
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-900">
<div class="p-3 mr-4 text-red-500 bg-red-100 rounded-full dark:text-red-100 dark:bg-red-500">
<slot />
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">{title}</p>
<p class="text-lg font-semibold text-gray-700 dark:text-gray-200">{count}</p>
</div>
</div>

132
src/routes/details.svelte

@ -1,66 +1,66 @@
<script>
import { page } from '$app/stores';
import Apiclient from '$lib/Apiclient';
let shortcode = $page.query.get('shortcode');
$: urlDetails = {
shortcode: 'Loading...',
url: 'Loading...',
target: 'Loading...',
visits: 'Loading...'
};
$: urlVisists = [];
Apiclient.getUrlDetails(shortcode).then((res) => {
urlDetails = res;
});
let visitQuery = Apiclient.getUrlVisits(shortcode).then((res) => {
urlVisists = res;
});
</script>
<h2 class="text-3xl font-bold text-gray-800 dark:text-gray-100 pb-6">Details: {shortcode}</h2>
<div class="text-gray-800 dark:text-gray-100">
<span>Shortcode:</span>
{urlDetails.shortcode} <br />
<span>URL:</span>
{urlDetails.url} <br />
<span>Target:</span>
{urlDetails.target} <br />
<span>Visits:</span>
{urlDetails.visits}
</div>
<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">
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>
</tr>
{:then}
{#each urlVisists as visit}
<tr>
<td
class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-200"
>
{visit.timestamp}
</td>
</tr>
{/each}
{/await}
</tbody>
</table>
</div>
<script>
import { page } from '$app/stores';
import Apiclient from '$lib/Apiclient';
let shortcode = $page.query.get('shortcode');
$: urlDetails = {
shortcode: 'Loading...',
url: 'Loading...',
target: 'Loading...',
visits: 'Loading...'
};
$: urlVisists = [];
Apiclient.getUrlDetails(shortcode).then((res) => {
urlDetails = res;
});
let visitQuery = Apiclient.getUrlVisits(shortcode).then((res) => {
urlVisists = res;
});
</script>
<h2 class="text-3xl font-bold text-gray-800 dark:text-gray-100 pb-6">Details: {shortcode}</h2>
<div class="text-gray-800 dark:text-gray-100">
<span>Shortcode:</span>
{urlDetails.shortcode} <br />
<span>URL:</span>
{urlDetails.url} <br />
<span>Target:</span>
{urlDetails.target} <br />
<span>Visits:</span>
{urlDetails.visits}
</div>
<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">
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>
</tr>
{:then}
{#each urlVisists as visit}
<tr>
<td
class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-200"
>
{visit.timestamp}
</td>
</tr>
{/each}
{/await}
</tbody>
</table>
</div>

2
src/routes/index.svelte

@ -36,4 +36,4 @@
/>
</svg>
</Statscard>
</div>
</div>

168
src/routes/links.svelte

@ -1,84 +1,84 @@
<script>
import Apiclient from '$lib/Apiclient';
$: urls = [];
let urlQuery = Apiclient.getUrls().then((res) => {
urls = res;
});
function deleteUrl(shortcode) {
Apiclient.deleteUrl(shortcode).then((res) => {
urls = urls.filter((url) => url.shortcode != shortcode);
});
}
</script>
<h2 class="text-3xl font-bold text-gray-800 dark:text-gray-100 pb-6">Manage all links</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">
Target
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
Visits
</th>
<th scope="col" class="relative px-6 py-3">
<span class="sr-only">Edit</span>
</th>
</tr>
</thead>
<tbody class="bg-white dark:bg-gray-700 divide-y divide-gray-200 dark:text-gray-100" x-max="1">
{#await urlQuery}
<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">
<a href="#">Loading data...</a>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm"> Loading data... </td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button
class="text-indigo-600 dark:text-red-600 hover:text-indigo-900 dark:hover:text-red-900"
>Delete</button
>
</td>
</tr>
{:then}
{#each urls as url}
<tr>
<td
class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-200"
>
{url.shortcode}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm">
<a href={url.target}>{url.target}</a>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm"> {url.visits} </td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button
on:click={deleteUrl(url.shortcode)}
class="px-4 py-2 font-medium tracking-wide text-white capitalize transition-colors duration-200 transform bg-red-600 rounded-md hover:bg-red-700 focus:outline-none focus:bg-red-700"
>
Delete
</button>
<a
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"
>
Details
</a>
</td>
</tr>
{/each}
{/await}
</tbody>
</table>
</div>
<script>
import Apiclient from '$lib/Apiclient';
$: urls = [];
let urlQuery = Apiclient.getUrls().then((res) => {
urls = res;
});
function deleteUrl(shortcode) {
Apiclient.deleteUrl(shortcode).then(() => {
urls = urls.filter((url) => url.shortcode != shortcode);
});
}
</script>
<h2 class="text-3xl font-bold text-gray-800 dark:text-gray-100 pb-6">Manage all links</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">
Target
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
Visits
</th>
<th scope="col" class="relative px-6 py-3">
<span class="sr-only">Edit</span>
</th>
</tr>
</thead>
<tbody class="bg-white dark:bg-gray-700 divide-y divide-gray-200 dark:text-gray-100" x-max="1">
{#await urlQuery}
<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">
<a href="#">Loading data...</a>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm"> Loading data... </td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button
class="text-indigo-600 dark:text-red-600 hover:text-indigo-900 dark:hover:text-red-900"
>Delete</button
>
</td>
</tr>
{:then}
{#each urls as url}
<tr>
<td
class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-gray-200"
>
{url.shortcode}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm">
<a href={url.target}>{url.target}</a>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm"> {url.visits} </td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button
on:click={deleteUrl(url.shortcode)}
class="px-4 py-2 font-medium tracking-wide text-white capitalize transition-colors duration-200 transform bg-red-600 rounded-md hover:bg-red-700 focus:outline-none focus:bg-red-700"
>
Delete
</button>
<a
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"
>
Details
</a>
</td>
</tr>
{/each}
{/await}
</tbody>
</table>
</div>

42
svelte.config.js

@ -1,20 +1,22 @@
import preprocess from "svelte-preprocess";
import staticAdapter from '@sveltejs/adapter-static';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte',
adapter: staticAdapter(),
files: {
assets: 'static'
}
},
preprocess: [preprocess({
"postcss": true
})]
};
export default config;
import preprocess from 'svelte-preprocess';
import staticAdapter from '@sveltejs/adapter-static';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte',
adapter: staticAdapter(),
files: {
assets: 'static'
}
},
preprocess: [
preprocess({
postcss: true
})
]
};
export default config;

24
tailwind.config.cjs

@ -1,13 +1,11 @@
const config = {
mode: "jit",
darkMode: 'media',
purge: [
"./src/**/*.{html,js,svelte,ts}",
],
theme: {
extend: {},
},
plugins: [],
};
module.exports = config;
const config = {
mode: 'jit',
darkMode: 'media',
purge: ['./src/**/*.{html,js,svelte,ts}'],
theme: {
extend: {}
},
plugins: []
};
module.exports = config;

Loading…
Cancel
Save