Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0fd4135
chore: update packages
tobynguyen27 Feb 24, 2026
edf5088
style: sort TailwindCSS classes
tobynguyen27 Feb 24, 2026
6253d40
chore: setup Nuxt
tobynguyen27 Feb 24, 2026
e5f6fff
chore: update Nuxt config
tobynguyen27 Feb 24, 2026
eae55a4
chore: setup UnoCSS
tobynguyen27 Feb 24, 2026
76c3c6e
chore: add icon preset
tobynguyen27 Feb 24, 2026
36c6b1c
chore: add Header
tobynguyen27 Feb 25, 2026
1395c4b
chore: add Footer
tobynguyen27 Feb 25, 2026
75a28b2
fix: disable shortcut when typing
tobynguyen27 Feb 25, 2026
c05c286
chore: add qr page
tobynguyen27 Feb 26, 2026
de838ea
chore: update name
tobynguyen27 Feb 26, 2026
a5fc4ef
feat: add settings page
tobynguyen27 Feb 26, 2026
3a98169
chore: add border
tobynguyen27 Feb 26, 2026
579eca4
refactor: clean code
tobynguyen27 Feb 26, 2026
a9a9258
fix: generate qr code for not url data
tobynguyen27 Feb 26, 2026
2726eaf
fix: theme setting
tobynguyen27 Feb 26, 2026
6a11948
chore: update width
tobynguyen27 Feb 26, 2026
1f70116
chore: add hero component
tobynguyen27 Feb 26, 2026
83934ee
feat: make the navbar fixed
tobynguyen27 Feb 26, 2026
c4d9406
chore: add feature
tobynguyen27 Feb 27, 2026
6c21673
chore: add form validator
tobynguyen27 Feb 27, 2026
a2f1630
fix: responsive
tobynguyen27 Feb 27, 2026
62736b3
chore: update Nuxt settings
tobynguyen27 Feb 27, 2026
efb3c21
chore: add toast
tobynguyen27 Feb 27, 2026
02df8f3
chore: fetch statistic data for counter
tobynguyen27 Feb 27, 2026
d139662
fix: style
tobynguyen27 Feb 27, 2026
9811632
chore: add unlock page
tobynguyen27 Feb 27, 2026
504470d
build: add wrangler
tobynguyen27 Feb 27, 2026
924ff5d
refactor: clean code
tobynguyen27 Feb 27, 2026
0f1d026
chore: add @takumi-rs/wasm
tobynguyen27 Feb 27, 2026
660079a
feat: update og
tobynguyen27 Feb 27, 2026
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
7 changes: 1 addition & 6 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
{
"recommendations": [
"oxc.oxc-vscode",
"Vue.volar",
"bradlc.vscode-tailwindcss",
"arktypeio.arkdark"
]
"recommendations": ["oxc.oxc-vscode", "Vue.volar", "antfu.unocss", "arktypeio.arkdark"]
}
7 changes: 1 addition & 6 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@
"workbench.editorAssociations": {
"*.svg": "default"
},
"files.associations": {
"*.css": "tailwindcss"
},
"typescript.preferences.autoImportSpecifierExcludeRegexes": ["^(node:)?os$"],

"tailwindCSS.classAttributes": ["class", "ui"],
"tailwindCSS.experimental.classRegex": [["ui:\\s*{([^)]*)\\s*}", "(?:'|\"|`)([^']*)(?:'|\"|`)"]]
"cSpell.words": ["Solitär"]
}
2 changes: 1 addition & 1 deletion apps/frontend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ NUXT_PUBLIC_SITE_URL=
NUXT_PUBLIC_SITE_NAME=

# Must be: development, staging or production
NUXT_PUBLIC_SITE_ENV=
NUXT_PUBLIC_SITE_ENV=
2 changes: 1 addition & 1 deletion apps/frontend/.env.local
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ NUXT_PUBLIC_API_BASE_URL=http://localhost:8080

NUXT_PUBLIC_SITE_URL=http://localhost:3000
NUXT_PUBLIC_SITE_NAME=Solitar
NUXT_PUBLIC_SITE_ENV=development
NUXT_PUBLIC_SITE_ENV=development
44 changes: 31 additions & 13 deletions apps/frontend/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
export default defineNuxtConfig({
modules: ["@nuxt/ui", "@vueuse/nuxt", "@nuxt/image", "@nuxtjs/seo"],
modules: [
"@unocss/nuxt",
"@nuxt/fonts",
"@nuxtjs/color-mode",
"@vueuse/nuxt",
"@regle/nuxt",
"nuxt-og-image",
"vue-sonner/nuxt",
],
css: ["~/assets/css/main.css"],
srcDir: "src/app",
dir: {
Expand All @@ -11,8 +19,25 @@ export default defineNuxtConfig({
pathPrefix: false,
},
],
// Routes
routeRules: {},
fonts: {
families: [
{
name: "Geist",
weights: ["400", "500", "600", "700", "800"],
global: true,
},
{
name: "Geist Mono",
weights: ["400", "500", "600", "700", "800"],
global: true,
},
{
name: "Orbitron",
weights: ["400"],
global: true,
},
],
},
// Runtime
runtimeConfig: {
public: {
Expand All @@ -24,7 +49,7 @@ export default defineNuxtConfig({
},
},
},
// Deploy
// Build
nitro: {
prerender: {
autoSubfolderIndex: false,
Expand All @@ -34,15 +59,8 @@ export default defineNuxtConfig({
nodeCompat: true,
},
},
// SEO
robots: {
blockAiBots: true,
blockNonSeoBots: true,
},
ogImage: {
enabled: false,
},

// Development
compatibilityDate: "2025-07-15",
devtools: { enabled: true },
compatibilityDate: "2025-07-15",
});
25 changes: 15 additions & 10 deletions apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,32 @@
"lint:fix": "oxlint --fix"
},
"dependencies": {
"@nuxt/image": "^2.0.0",
"@nuxt/ui": "^4.4.0",
"@nuxtjs/seo": "^3.4.0",
"@nuxt/fonts": "^0.14.0",
"@nuxtjs/color-mode": "^4.0.0",
"@regle/core": "^1.19.13",
"@regle/nuxt": "^1.19.13",
"@regle/rules": "^1.19.13",
"@takumi-rs/core": "^0.69.2",
"@vueuse/integrations": "^14.2.1",
"arktype": "^2.1.29",
"dayjs": "^1.11.19",
"nuxt": "^4.3.1",
"qrcode": "^1.5.4",
"tailwindcss": "^4.2.0",
"ufo": "^1.6.3",
"vue": "^3.5.28",
"vue-router": "^4.6.4"
"vue-router": "^4.6.4",
"vue-sonner": "^2.0.9"
},
"devDependencies": {
"@iconify-json/carbon": "^1.2.18",
"@iconify-json/lucide": "^1.2.92",
"@iconify-json/tabler": "^1.2.26",
"@iconify-json/tabler": "^1.2.27",
"@takumi-rs/wasm": "^0.69.2",
"@unocss/nuxt": "^66.6.0",
"@vueuse/core": "^14.2.1",
"@vueuse/nuxt": "^14.2.1",
"oxlint": "^1.48.0",
"nuxt-og-image": "6.0.0-beta.41",
"oxlint": "^1.50.0",
"oxlint-tsgolint": "^0.14.2",
"wrangler": "^4.67.0"
"unocss": "^66.6.0",
"wrangler": "^4.69.0"
}
}
7 changes: 0 additions & 7 deletions apps/frontend/src/app/app.config.ts

This file was deleted.

45 changes: 13 additions & 32 deletions apps/frontend/src/app/app.vue
Original file line number Diff line number Diff line change
@@ -1,34 +1,15 @@
<script setup lang="ts">
import type { ToasterProps } from "@nuxt/ui";

const toaster: ToasterProps = { position: "top-right" };

const siteConfig = useSiteConfig();

useSeoMeta({
title: "Solitar",
description: "The only URL toolbox that you need",
ogTitle: "Solitar",
ogDescription: "The only URL toolbox that you need",
ogImage: "/og.png",
twitterCard: "summary_large_image",
});
</script>

<template>
<UApp :toaster="toaster">
<UBanner
v-if="siteConfig.env === 'staging'"
icon="i-carbon:warning-alt"
title="Your are viewing Solitar's staging environment"
color="warning" />
<Header />

<UMain>
<NuxtPage />
</UMain>

<USeparator />
<Footer />
</UApp>
<Toaster
position="top-right"
:toast-options="{
unstyled: true,
classes: {
error: 'bg-red-800 rounded-lg p-3',
success: 'bg-green-800 rounded-lg p-3',
icon: 'hidden',
},
}" />
<Header />
<NuxtPage />
<Footer />
</template>
106 changes: 98 additions & 8 deletions apps/frontend/src/app/assets/css/main.css
Original file line number Diff line number Diff line change
@@ -1,12 +1,102 @@
@import "tailwindcss";
@import "@nuxt/ui";
:root {
--bg: hsla(0, 0%, 100%, 1);
--bg-muted: hsla(0, 0%, 98%, 1);

--gray-100: hsla(0, 0%, 95%, 1);
--gray-200: hsla(0, 0%, 92%, 1);
--gray-300: hsla(0, 0%, 90%, 1);
--gray-400: hsla(0, 0%, 92%, 1);
--gray-500: hsla(0, 0%, 79%, 1);
--gray-600: hsla(0, 0%, 66%, 1);
--gray-700: hsla(0, 0%, 56%, 1);
--gray-800: hsla(0, 0%, 49%, 1);
--gray-900: hsla(0, 0%, 40%, 1);
--gray-1000: hsla(0, 0%, 9%, 1);

--red-100: hsla(0, 100%, 97%, 1);
--red-200: hsla(0, 100%, 96%, 1);
--red-300: hsla(0, 100%, 95%, 1);
--red-400: hsla(0, 90%, 92%, 1);
--red-500: hsla(0, 82%, 85%, 1);
--red-600: hsla(359, 90%, 71%, 1);
--red-700: hsla(358, 75%, 59%, 1);
--red-800: hsla(358, 70%, 52%, 1);
--red-900: hsla(358, 66%, 48%, 1);
--red-1000: hsla(355, 49%, 15%, 1);

@theme {
--font-sans: "Geist", system-ui, sans-serif;
--font-mono: "JetBrains Mono", monospace;
--font-brand: "Orbitron", sans-serif;
--amber-100: hsla(39, 100%, 95%, 1);
--amber-200: hsla(44, 100%, 92%, 1);
--amber-300: hsla(43, 96%, 90%, 1);
--amber-400: hsla(42, 100%, 78%, 1);
--amber-500: hsla(38, 100%, 71%, 1);
--amber-600: hsla(36, 90%, 62%, 1);
--amber-700: hsla(39, 100%, 57%, 1);
--amber-800: hsla(35, 100%, 52%, 1);
--amber-900: hsla(30, 100%, 32%, 1);
--amber-1000: hsla(20, 79%, 17%, 1);

--green-100: hsla(120, 60%, 96%, 1);
--green-200: hsla(120, 60%, 95%, 1);
--green-300: hsla(120, 60%, 91%, 1);
--green-400: hsla(122, 60%, 86%, 1);
--green-500: hsla(124, 60%, 75%, 1);
--green-600: hsla(125, 60%, 64%, 1);
--green-700: hsla(131, 41%, 46%, 1);
--green-800: hsla(132, 43%, 39%, 1);
--green-900: hsla(133, 50%, 32%, 1);
--green-1000: hsla(128, 29%, 15%, 1);
}

:root {
--ui-radius: 0.375rem;
:root.dark {
--bg: hsla(0, 0%, 0%, 1);
--bg-muted: hsla(0, 0%, 4%, 1);

--gray-100: hsla(0, 0%, 10%, 1);
--gray-200: hsla(0, 0%, 12%, 1);
--gray-300: hsla(0, 0%, 16%, 1);
--gray-400: hsla(0, 0%, 18%, 1);
--gray-500: hsla(0, 0%, 27%, 1);
--gray-600: hsla(0, 0%, 53%, 1);
--gray-700: hsla(0, 0%, 56%, 1);
--gray-800: hsla(0, 0%, 49%, 1);
--gray-900: hsla(0, 0%, 63%, 1);
--gray-1000: hsla(0, 0%, 93%, 1);

--red-100: hsla(357, 37%, 12%, 1);
--red-200: hsla(357, 46%, 16%, 1);
--red-300: hsla(356, 54%, 22%, 1);
--red-400: hsla(357, 55%, 26%, 1);
--red-500: hsla(357, 60%, 32%, 1);
--red-600: hsla(358, 75%, 59%, 1);
--red-700: hsla(358, 75%, 59%, 1);
--red-800: hsla(358, 69%, 52%, 1);
--red-900: hsla(358, 100%, 69%, 1);
--red-1000: hsla(353, 90%, 96%, 1);

--amber-100: hsla(35, 100%, 8%, 1);
--amber-200: hsla(32, 100%, 10%, 1);
--amber-300: hsla(33, 100%, 15%, 1);
--amber-400: hsla(35, 100%, 17%, 1);
--amber-500: hsla(35, 91%, 22%, 1);
--amber-600: hsla(39, 85%, 49%, 1);
--amber-700: hsla(39, 100%, 57%, 1);
--amber-800: hsla(35, 100%, 52%, 1);
--amber-900: hsla(39, 90%, 50%, 1);
--amber-1000: hsla(40, 94%, 93%, 1);

--green-100: hsla(136, 50%, 9%, 1);
--green-200: hsla(137, 50%, 12%, 1);
--green-300: hsla(136, 50%, 14%, 1);
--green-400: hsla(135, 70%, 16%, 1);
--green-500: hsla(135, 70%, 23%, 1);
--green-600: hsla(135, 70%, 34%, 1);
--green-700: hsla(131, 41%, 46%, 1);
--green-800: hsla(132, 43%, 39%, 1);
--green-900: hsla(131, 43%, 57%, 1);
--green-1000: hsla(136, 73%, 94%, 1);
}

body {
background-color: var(--bg);
color: var(--gray-1000);
}
21 changes: 8 additions & 13 deletions apps/frontend/src/app/components/Counter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,16 @@ const statisticRepo = repository($api);

const { pending, data } = await useAsyncData(() => statisticRepo.getStatisticData());

const totalLinks = data.value?.totalLinks ?? 0;
const totalClicks = data.value?.totalClicks ?? 0;
const totalLinks = computed(() => data.value?.totalLinks ?? 0);
const totalClicks = computed(() => data.value?.totalClicks ?? 0);
</script>

<template>
<div class="flex flex-col sm:flex-row justify-center items-center sm:gap-5">
<template v-if="pending"
><USkeleton class="w-full h-7" /> <USkeleton class="w-full h-7"
/></template>

<template v-else>
<p class="sm:text-xl font-semibold text-center sm:text-left">
<span class="text-2xl text-primary">{{ totalLinks }}</span> links created that have
been accessed <span class="text-2xl text-primary">{{ totalClicks }}</span> times
</p>
</template>
<div class="">
<div class="w-full bg-gray-200 h-7 rounded-lg" v-if="pending" />
<p class="font-semibold text-lg" v-else>
<span class="text-2xl text-primary">{{ totalLinks }}</span> links created that have been
accessed <span class="text-2xl text-primary">{{ totalClicks }}</span> times
</p>
</div>
</template>
Loading