Browse Source

reorder tailwind classes

pull/1397/head
Bernd Storath 9 months ago
parent
commit
b500a92cf5
  1. 3
      src/.prettierrc.json
  2. 2
      src/app/app.vue
  3. 10
      src/app/components/ClientCard/Avatar.vue
  4. 4
      src/app/components/ClientCard/Charts.vue
  5. 14
      src/app/components/ClientCard/ClientCard.vue
  6. 4
      src/app/components/ClientCard/Config.vue
  7. 2
      src/app/components/ClientCard/Edit.vue
  8. 2
      src/app/components/ClientCard/ExpireDate.vue
  9. 4
      src/app/components/ClientCard/InlineTransfer.vue
  10. 2
      src/app/components/ClientCard/LastSeen.vue
  11. 4
      src/app/components/ClientCard/Name.vue
  12. 2
      src/app/components/ClientCard/OneTimeLink.vue
  13. 4
      src/app/components/ClientCard/OneTimeLinkBtn.vue
  14. 4
      src/app/components/ClientCard/QRCode.vue
  15. 8
      src/app/components/ClientCard/Switch.vue
  16. 4
      src/app/components/ClientCard/Transfer.vue
  17. 2
      src/app/components/Clients/BackupConfig.vue
  18. 2
      src/app/components/Clients/Clients.vue
  19. 32
      src/app/components/Clients/CreateDialog.vue
  20. 24
      src/app/components/Clients/DeleteDialog.vue
  21. 6
      src/app/components/Clients/Empty.vue
  22. 2
      src/app/components/Clients/New.vue
  23. 6
      src/app/components/Clients/QRCodeDialog.vue
  24. 2
      src/app/components/Clients/RestoreConfig.vue
  25. 4
      src/app/components/Clients/Sort.vue
  26. 2
      src/app/components/base/Button.vue
  27. 4
      src/app/components/base/Switch.vue
  28. 4
      src/app/components/error/Toast.vue
  29. 2
      src/app/components/form/ActionField.vue
  30. 2
      src/app/components/form/ArrayField.vue
  31. 2
      src/app/components/form/Group.vue
  32. 2
      src/app/components/form/Heading.vue
  33. 2
      src/app/components/form/NumberField.vue
  34. 2
      src/app/components/form/TextField.vue
  35. 2
      src/app/components/panel/Panel.vue
  36. 2
      src/app/components/panel/head/Boat.vue
  37. 2
      src/app/components/panel/head/Head.vue
  38. 4
      src/app/components/ui/Banner.vue
  39. 6
      src/app/components/ui/ChooseLang.vue
  40. 2
      src/app/components/ui/StepProgress.vue
  41. 6
      src/app/components/ui/Toast.vue
  42. 8
      src/app/components/ui/UserMenu.vue
  43. 36
      src/app/layouts/default.vue
  44. 4
      src/app/layouts/setup.vue
  45. 12
      src/app/pages/admin.vue
  46. 2
      src/app/pages/admin/features.vue
  47. 12
      src/app/pages/admin/statistics.vue
  48. 4
      src/app/pages/index.vue
  49. 30
      src/app/pages/login.vue
  50. 16
      src/app/pages/me.vue
  51. 4
      src/app/pages/setup/1.vue
  52. 4
      src/app/pages/setup/2.vue
  53. 2
      src/app/pages/setup/3.vue
  54. 6
      src/app/pages/setup/4.vue
  55. 6
      src/app/pages/setup/5.vue
  56. 2
      src/app/pages/setup/migrate.vue
  57. 1
      src/package.json
  58. 62
      src/pnpm-lock.yaml

3
src/.prettierrc.json

@ -2,5 +2,6 @@
"trailingComma": "es5", "trailingComma": "es5",
"tabWidth": 2, "tabWidth": 2,
"semi": true, "semi": true,
"singleQuote": true "singleQuote": true,
"plugins": ["prettier-plugin-tailwindcss"]
} }

2
src/app/app.vue

@ -3,7 +3,7 @@
<NuxtLayout> <NuxtLayout>
<NuxtPage /> <NuxtPage />
<ToastViewport <ToastViewport
class="[--viewport-padding:_25px] fixed bottom-0 right-0 flex flex-col p-[var(--viewport-padding)] gap-[10px] w-[390px] max-w-[100vw] m-0 list-none z-[2147483647] outline-none" class="fixed bottom-0 right-0 z-[2147483647] m-0 flex w-[390px] max-w-[100vw] list-none flex-col gap-[10px] p-[var(--viewport-padding)] outline-none [--viewport-padding:_25px]"
/> />
</NuxtLayout> </NuxtLayout>
</ToastProvider> </ToastProvider>

10
src/app/components/ClientCard/Avatar.vue

@ -1,10 +1,10 @@
<template> <template>
<div class="h-10 w-10 mt-2 self-start rounded-full bg-gray-50 relative"> <div class="relative mt-2 h-10 w-10 self-start rounded-full bg-gray-50">
<IconsAvatar class="w-6 m-2 text-gray-300" /> <IconsAvatar class="m-2 w-6 text-gray-300" />
<img <img
v-if="client.avatar" v-if="client.avatar"
:src="client.avatar" :src="client.avatar"
class="w-10 rounded-full absolute top-0 left-0" class="absolute left-0 top-0 w-10 rounded-full"
/> />
<div <div
@ -15,10 +15,10 @@
" "
> >
<div <div
class="animate-ping w-4 h-4 p-1 bg-red-100 dark:bg-red-100 rounded-full absolute -bottom-1 -right-1" class="absolute -bottom-1 -right-1 h-4 w-4 animate-ping rounded-full bg-red-100 p-1 dark:bg-red-100"
/> />
<div <div
class="w-2 h-2 bg-red-800 dark:bg-red-600 rounded-full absolute bottom-0 right-0" class="absolute bottom-0 right-0 h-2 w-2 rounded-full bg-red-800 dark:bg-red-600"
/> />
</div> </div>
</div> </div>

4
src/app/components/ClientCard/Charts.vue

@ -1,13 +1,13 @@
<template> <template>
<div <div
v-if="globalStore.statistics.chartType" v-if="globalStore.statistics.chartType"
:class="`absolute z-0 bottom-0 left-0 right-0 h-6 ${globalStore.statistics.chartType === 1 && 'line-chart'}`" :class="`absolute bottom-0 left-0 right-0 z-0 h-6 ${globalStore.statistics.chartType === 1 && 'line-chart'}`"
> >
<UiChart :options="chartOptionsTX" :series="client.transferTxSeries" /> <UiChart :options="chartOptionsTX" :series="client.transferTxSeries" />
</div> </div>
<div <div
v-if="globalStore.statistics.chartType" v-if="globalStore.statistics.chartType"
:class="`absolute z-0 top-0 left-0 right-0 h-6 ${globalStore.statistics.chartType === 1 && 'line-chart'}`" :class="`absolute left-0 right-0 top-0 z-0 h-6 ${globalStore.statistics.chartType === 1 && 'line-chart'}`"
> >
<UiChart <UiChart
:options="chartOptionsRX" :options="chartOptionsRX"

14
src/app/components/ClientCard/ClientCard.vue

@ -1,16 +1,16 @@
<template> <template>
<ClientCardCharts :client="client" /> <ClientCardCharts :client="client" />
<div <div
class="relative py-3 md:py-5 px-3 z-10 flex flex-col sm:flex-row justify-between gap-3" class="relative z-10 flex flex-col justify-between gap-3 px-3 py-3 sm:flex-row md:py-5"
> >
<div class="flex gap-3 md:gap-4 w-full items-center"> <div class="flex w-full items-center gap-3 md:gap-4">
<ClientCardAvatar :client="client" /> <ClientCardAvatar :client="client" />
<!-- Name & Info --> <!-- Name & Info -->
<div class="flex flex-col xxs:flex-row w-full gap-2"> <div class="flex w-full flex-col gap-2 xxs:flex-row">
<div class="flex flex-col flex-grow gap-1"> <div class="flex flex-grow flex-col gap-1">
<ClientCardName :client="client" /> <ClientCardName :client="client" />
<div <div
class="block md:inline-block pb-1 md:pb-0 text-gray-500 dark:text-neutral-400 text-xs" class="block pb-1 text-xs text-gray-500 md:inline-block md:pb-0 dark:text-neutral-400"
> >
<ClientCardAddress4 :client="client" /> <ClientCardAddress4 :client="client" />
<ClientCardInlineTransfer <ClientCardInlineTransfer
@ -26,7 +26,7 @@
<!-- Info --> <!-- Info -->
<div <div
v-if="globalStore.statistics.enabled" v-if="globalStore.statistics.enabled"
class="flex gap-2 items-center shrink-0 text-gray-400 dark:text-neutral-400 text-xs mt-px justify-end" class="mt-px flex shrink-0 items-center justify-end gap-2 text-xs text-gray-400 dark:text-neutral-400"
> >
<ClientCardTransfer :client="client" /> <ClientCardTransfer :client="client" />
</div> </div>
@ -37,7 +37,7 @@
<div class="flex items-center justify-end"> <div class="flex items-center justify-end">
<div <div
class="text-gray-400 dark:text-neutral-400 flex gap-1 items-center justify-between" class="flex items-center justify-between gap-1 text-gray-400 dark:text-neutral-400"
> >
<ClientCardSwitch :client="client" /> <ClientCardSwitch :client="client" />
<ClientCardEdit :client="client" /> <ClientCardEdit :client="client" />

4
src/app/components/ClientCard/Config.vue

@ -3,9 +3,9 @@
:disabled="!client.downloadableConfig" :disabled="!client.downloadableConfig"
:href="'./api/client/' + client.id + '/configuration'" :href="'./api/client/' + client.id + '/configuration'"
:download="client.downloadableConfig ? 'configuration' : null" :download="client.downloadableConfig ? 'configuration' : null"
class="align-middle inline-block bg-gray-100 dark:bg-neutral-600 dark:text-neutral-300 p-2 rounded transition" class="inline-block rounded bg-gray-100 p-2 align-middle transition dark:bg-neutral-600 dark:text-neutral-300"
:class="{ :class="{
'hover:bg-red-800 dark:hover:bg-red-800 hover:text-white dark:hover:text-white': 'hover:bg-red-800 hover:text-white dark:hover:bg-red-800 dark:hover:text-white':
client.downloadableConfig, client.downloadableConfig,
'is-disabled': !client.downloadableConfig, 'is-disabled': !client.downloadableConfig,
}" }"

2
src/app/components/ClientCard/Edit.vue

@ -1,6 +1,6 @@
<template> <template>
<NuxtLink <NuxtLink
class="align-middle bg-gray-100 dark:bg-neutral-600 dark:text-neutral-300 p-2 rounded transition hover:bg-red-800 dark:hover:bg-red-800 hover:text-white dark:hover:text-white" class="rounded bg-gray-100 p-2 align-middle transition hover:bg-red-800 hover:text-white dark:bg-neutral-600 dark:text-neutral-300 dark:hover:bg-red-800 dark:hover:text-white"
:to="`/clients/${client.id}`" :to="`/clients/${client.id}`"
> >
<IconsEdit class="w-5" /> <IconsEdit class="w-5" />

2
src/app/components/ClientCard/ExpireDate.vue

@ -1,7 +1,7 @@
<template> <template>
<div <div
v-show="globalStore.features.clientExpiration.enabled" v-show="globalStore.features.clientExpiration.enabled"
class="block md:inline-block pb-1 md:pb-0 text-gray-500 dark:text-neutral-400 text-xs" class="block pb-1 text-xs text-gray-500 md:inline-block md:pb-0 dark:text-neutral-400"
> >
<span class="inline-block">{{ expiredDateFormat(client.expiresAt) }}</span> <span class="inline-block">{{ expiredDateFormat(client.expiresAt) }}</span>
</div> </div>

4
src/app/components/ClientCard/InlineTransfer.vue

@ -6,7 +6,7 @@
:title="$t('totalDownload') + bytes(client.transferTx)" :title="$t('totalDownload') + bytes(client.transferTx)"
> >
· ·
<IconsArrowDown class="align-middle h-3 inline" /> <IconsArrowDown class="inline h-3 align-middle" />
{{ bytes(client.transferTxCurrent) }}/s {{ bytes(client.transferTxCurrent) }}/s
</span> </span>
@ -17,7 +17,7 @@
:title="$t('totalUpload') + bytes(client.transferRx)" :title="$t('totalUpload') + bytes(client.transferRx)"
> >
· ·
<IconsArrowUp class="align-middle h-3 inline" /> <IconsArrowUp class="inline h-3 align-middle" />
{{ bytes(client.transferRxCurrent) }}/s {{ bytes(client.transferRxCurrent) }}/s
</span> </span>
</template> </template>

2
src/app/components/ClientCard/LastSeen.vue

@ -1,7 +1,7 @@
<template> <template>
<span <span
v-if="client.latestHandshakeAt" v-if="client.latestHandshakeAt"
class="text-gray-400 dark:text-neutral-500 whitespace-nowrap" class="whitespace-nowrap text-gray-400 dark:text-neutral-500"
:title="$t('lastSeen') + dateTime(new Date(client.latestHandshakeAt))" :title="$t('lastSeen') + dateTime(new Date(client.latestHandshakeAt))"
> >
{{ !globalStore.statistics.enabled ? ' · ' : '' {{ !globalStore.statistics.enabled ? ' · ' : ''

4
src/app/components/ClientCard/Name.vue

@ -1,9 +1,9 @@
<template> <template>
<div <div
class="text-gray-700 dark:text-neutral-200 group text-sm md:text-base" class="group text-sm text-gray-700 md:text-base dark:text-neutral-200"
:title="$t('createdOn') + dateTime(new Date(client.createdAt))" :title="$t('createdOn') + dateTime(new Date(client.createdAt))"
> >
<span class="border-t-2 border-b-2 border-transparent"> <span class="border-b-2 border-t-2 border-transparent">
{{ client.name }} {{ client.name }}
</span> </span>
</div> </div>

2
src/app/components/ClientCard/OneTimeLink.vue

@ -4,7 +4,7 @@
globalStore.features.oneTimeLinks.enabled && client.oneTimeLink !== null globalStore.features.oneTimeLinks.enabled && client.oneTimeLink !== null
" "
:ref="'client-' + client.id + '-link'" :ref="'client-' + client.id + '-link'"
class="text-gray-400 text-xs" class="text-xs text-gray-400"
> >
<a :href="'./cnf/' + client.oneTimeLink + ''">{{ path }}</a> <a :href="'./cnf/' + client.oneTimeLink + ''">{{ path }}</a>
</div> </div>

4
src/app/components/ClientCard/OneTimeLinkBtn.vue

@ -2,9 +2,9 @@
<button <button
v-if="globalStore.features.oneTimeLinks.enabled" v-if="globalStore.features.oneTimeLinks.enabled"
:disabled="!client.downloadableConfig" :disabled="!client.downloadableConfig"
class="align-middle inline-block bg-gray-100 dark:bg-neutral-600 dark:text-neutral-300 p-2 rounded transition" class="inline-block rounded bg-gray-100 p-2 align-middle transition dark:bg-neutral-600 dark:text-neutral-300"
:class="{ :class="{
'hover:bg-red-800 dark:hover:bg-red-800 hover:text-white dark:hover:text-white': 'hover:bg-red-800 hover:text-white dark:hover:bg-red-800 dark:hover:text-white':
client.downloadableConfig, client.downloadableConfig,
'is-disabled': !client.downloadableConfig, 'is-disabled': !client.downloadableConfig,
}" }"

4
src/app/components/ClientCard/QRCode.vue

@ -1,9 +1,9 @@
<template> <template>
<button <button
:disabled="!client.downloadableConfig" :disabled="!client.downloadableConfig"
class="align-middle bg-gray-100 dark:bg-neutral-600 dark:text-neutral-300 p-2 rounded transition" class="rounded bg-gray-100 p-2 align-middle transition dark:bg-neutral-600 dark:text-neutral-300"
:class="{ :class="{
'hover:bg-red-800 dark:hover:bg-red-800 hover:text-white dark:hover:text-white': 'hover:bg-red-800 hover:text-white dark:hover:bg-red-800 dark:hover:text-white':
client.downloadableConfig, client.downloadableConfig,
'is-disabled': !client.downloadableConfig, 'is-disabled': !client.downloadableConfig,
}" }"

8
src/app/components/ClientCard/Switch.vue

@ -2,19 +2,19 @@
<div <div
v-if="client.enabled === true" v-if="client.enabled === true"
:title="$t('disableClient')" :title="$t('disableClient')"
class="inline-block align-middle rounded-full w-10 h-6 mr-1 bg-red-800 cursor-pointer hover:bg-red-700 transition-all" class="mr-1 inline-block h-6 w-10 cursor-pointer rounded-full bg-red-800 align-middle transition-all hover:bg-red-700"
@click="disableClient(client)" @click="disableClient(client)"
> >
<div class="rounded-full w-4 h-4 m-1 ml-5 bg-white" /> <div class="m-1 ml-5 h-4 w-4 rounded-full bg-white" />
</div> </div>
<div <div
v-if="client.enabled === false" v-if="client.enabled === false"
:title="$t('enableClient')" :title="$t('enableClient')"
class="inline-block align-middle rounded-full w-10 h-6 mr-1 bg-gray-200 dark:bg-neutral-400 cursor-pointer hover:bg-gray-300 dark:hover:bg-neutral-500 transition-all" class="mr-1 inline-block h-6 w-10 cursor-pointer rounded-full bg-gray-200 align-middle transition-all hover:bg-gray-300 dark:bg-neutral-400 dark:hover:bg-neutral-500"
@click="enableClient(client)" @click="enableClient(client)"
> >
<div class="rounded-full w-4 h-4 m-1 bg-white" /> <div class="m-1 h-4 w-4 rounded-full bg-white" />
</div> </div>
</template> </template>

4
src/app/components/ClientCard/Transfer.vue

@ -5,7 +5,7 @@
class="flex gap-1" class="flex gap-1"
:title="$t('totalDownload') + bytes(client.transferTx)" :title="$t('totalDownload') + bytes(client.transferTx)"
> >
<IconsArrowDown class="align-middle h-3 inline mt-0.5" /> <IconsArrowDown class="mt-0.5 inline h-3 align-middle" />
<div> <div>
<span class="text-gray-700 dark:text-neutral-200" <span class="text-gray-700 dark:text-neutral-200"
>{{ bytes(client.transferTxCurrent) }}/s</span >{{ bytes(client.transferTxCurrent) }}/s</span
@ -24,7 +24,7 @@
class="flex gap-1" class="flex gap-1"
:title="$t('totalUpload') + bytes(client.transferRx)" :title="$t('totalUpload') + bytes(client.transferRx)"
> >
<IconsArrowUp class="align-middle h-3 inline mt-0.5" /> <IconsArrowUp class="mt-0.5 inline h-3 align-middle" />
<div> <div>
<span class="text-gray-700 dark:text-neutral-200" <span class="text-gray-700 dark:text-neutral-200"
>{{ bytes(client.transferRxCurrent) }}/s</span >{{ bytes(client.transferRxCurrent) }}/s</span

2
src/app/components/Clients/BackupConfig.vue

@ -5,6 +5,6 @@
:title="$t('titleBackupConfig')" :title="$t('titleBackupConfig')"
> >
<IconsStack class="w-4 md:mr-2" /> <IconsStack class="w-4 md:mr-2" />
<span class="max-md:hidden text-sm">{{ $t('backup') }}</span> <span class="text-sm max-md:hidden">{{ $t('backup') }}</span>
</BaseButton> </BaseButton>
</template> </template>

2
src/app/components/Clients/Clients.vue

@ -2,7 +2,7 @@
<div <div
v-for="client in clientsStore.clients" v-for="client in clientsStore.clients"
:key="client.id" :key="client.id"
class="relative overflow-hidden border-b last:border-b-0 border-gray-100 dark:border-neutral-600 border-solid" class="relative overflow-hidden border-b border-solid border-gray-100 last:border-b-0 dark:border-neutral-600"
> >
<ClientCard :client="client" /> <ClientCard :client="client" />
</div> </div>

32
src/app/components/Clients/CreateDialog.vue

@ -2,10 +2,10 @@
<!-- Create Dialog --> <!-- Create Dialog -->
<div <div
v-if="modalStore.clientCreate" v-if="modalStore.clientCreate"
class="fixed z-10 inset-0 overflow-y-auto" class="fixed inset-0 z-10 overflow-y-auto"
> >
<div <div
class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0" class="flex min-h-screen items-center justify-center px-4 pb-20 pt-4 text-center sm:block sm:p-0"
> >
<!-- <!--
Background overlay, show/hide based on modal state. Background overlay, show/hide based on modal state.
@ -19,13 +19,13 @@
--> -->
<div class="fixed inset-0 transition-opacity" aria-hidden="true"> <div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div <div
class="absolute inset-0 bg-gray-500 dark:bg-black opacity-75 dark:opacity-50" class="absolute inset-0 bg-gray-500 opacity-75 dark:bg-black dark:opacity-50"
/> />
</div> </div>
<!-- This element is to trick the browser into centering the modal contents. --> <!-- This element is to trick the browser into centering the modal contents. -->
<span <span
class="hidden sm:inline-block sm:align-middle sm:h-screen" class="hidden sm:inline-block sm:h-screen sm:align-middle"
aria-hidden="true" aria-hidden="true"
>&#8203;</span >&#8203;</span
> >
@ -40,24 +40,24 @@
To: "opacity-0 tranneutral-y-4 sm:tranneutral-y-0 sm:scale-95" To: "opacity-0 tranneutral-y-4 sm:tranneutral-y-0 sm:scale-95"
--> -->
<div <div
class="inline-block align-bottom bg-white dark:bg-neutral-700 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg w-full" class="inline-block w-full transform overflow-hidden rounded-lg bg-white text-left align-bottom shadow-xl transition-all sm:my-8 sm:max-w-lg sm:align-middle dark:bg-neutral-700"
role="dialog" role="dialog"
aria-modal="true" aria-modal="true"
aria-labelledby="modal-headline" aria-labelledby="modal-headline"
> >
<div class="bg-white dark:bg-neutral-700 px-4 pt-5 pb-4 sm:p-6 sm:pb-4"> <div class="bg-white px-4 pb-4 pt-5 sm:p-6 sm:pb-4 dark:bg-neutral-700">
<div class="sm:flex sm:items-start"> <div class="sm:flex sm:items-start">
<div <div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-800 sm:mx-0 sm:h-10 sm:w-10" class="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-red-800 sm:mx-0 sm:h-10 sm:w-10"
> >
<IconsPlus class="h-6 w-6 text-white" /> <IconsPlus class="h-6 w-6 text-white" />
</div> </div>
<div <div
class="flex-grow mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left" class="mt-3 flex-grow text-center sm:ml-4 sm:mt-0 sm:text-left"
> >
<h3 <h3
id="modal-headline" id="modal-headline"
class="text-lg leading-6 font-medium text-gray-900 dark:text-neutral-200" class="text-lg font-medium leading-6 text-gray-900 dark:text-neutral-200"
> >
{{ $t('newClient') }} {{ $t('newClient') }}
</h3> </h3>
@ -65,7 +65,7 @@
<p class="text-sm text-gray-500"> <p class="text-sm text-gray-500">
<input <input
v-model.trim="modalStore.clientCreateName" v-model.trim="modalStore.clientCreateName"
class="rounded p-2 border-2 dark:bg-neutral-700 dark:text-neutral-200 border-gray-100 dark:border-neutral-600 focus:border-gray-200 focus:dark:border-neutral-500 dark:placeholder:text-neutral-400 outline-none w-full" class="w-full rounded border-2 border-gray-100 p-2 outline-none focus:border-gray-200 dark:border-neutral-600 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400 focus:dark:border-neutral-500"
type="text" type="text"
:placeholder="$t('name')" :placeholder="$t('name')"
/> />
@ -77,14 +77,14 @@
> >
<p class="text-sm text-gray-500"> <p class="text-sm text-gray-500">
<label <label
class="block text-gray-900 dark:text-neutral-200 text-sm font-bold mb-2" class="mb-2 block text-sm font-bold text-gray-900 dark:text-neutral-200"
for="expireDate" for="expireDate"
> >
{{ $t('ExpireDate') }} {{ $t('ExpireDate') }}
</label> </label>
<input <input
v-model.trim="modalStore.clientExpireDate" v-model.trim="modalStore.clientExpireDate"
class="rounded p-2 border-2 dark:bg-neutral-700 dark:text-neutral-200 border-gray-100 dark:border-neutral-600 focus:border-gray-200 focus:dark:border-neutral-500 dark:placeholder:text-neutral-400 outline-none w-full" class="w-full rounded border-2 border-gray-100 p-2 outline-none focus:border-gray-200 dark:border-neutral-600 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400 focus:dark:border-neutral-500"
type="date" type="date"
:placeholder="$t('ExpireDate')" :placeholder="$t('ExpireDate')"
name="expireDate" name="expireDate"
@ -95,12 +95,12 @@
</div> </div>
</div> </div>
<div <div
class="bg-gray-50 dark:bg-neutral-700 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse" class="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6 dark:bg-neutral-700"
> >
<button <button
v-if="modalStore.clientCreateName.length" v-if="modalStore.clientCreateName.length"
type="button" type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-800 text-base font-medium text-white hover:bg-red-700 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm" class="inline-flex w-full justify-center rounded-md border border-transparent bg-red-800 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-red-700 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm"
@click=" @click="
modalStore.createClient(); modalStore.createClient();
modalStore.clientCreate = null; modalStore.clientCreate = null;
@ -111,13 +111,13 @@
<button <button
v-else v-else
type="button" type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-gray-200 dark:bg-neutral-400 text-base font-medium text-white dark:text-neutral-300 sm:ml-3 sm:w-auto sm:text-sm cursor-not-allowed" class="inline-flex w-full cursor-not-allowed justify-center rounded-md border border-transparent bg-gray-200 px-4 py-2 text-base font-medium text-white shadow-sm sm:ml-3 sm:w-auto sm:text-sm dark:bg-neutral-400 dark:text-neutral-300"
> >
{{ $t('create') }} {{ $t('create') }}
</button> </button>
<button <button
type="button" type="button"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-neutral-500 shadow-sm px-4 py-2 bg-white dark:bg-neutral-500 text-base font-medium text-gray-700 dark:text-neutral-50 hover:bg-gray-50 dark:hover:bg-neutral-600 dark:hover:border-neutral-600 focus:outline-none sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm" class="mt-3 inline-flex w-full justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-base font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none sm:ml-3 sm:mt-0 sm:w-auto sm:text-sm dark:border-neutral-500 dark:bg-neutral-500 dark:text-neutral-50 dark:hover:border-neutral-600 dark:hover:bg-neutral-600"
@click="modalStore.clientCreate = null" @click="modalStore.clientCreate = null"
> >
{{ $t('cancel') }} {{ $t('cancel') }}

24
src/app/components/Clients/DeleteDialog.vue

@ -1,10 +1,10 @@
<template> <template>
<div <div
v-if="modalStore.clientDelete" v-if="modalStore.clientDelete"
class="fixed z-10 inset-0 overflow-y-auto" class="fixed inset-0 z-10 overflow-y-auto"
> >
<div <div
class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0" class="flex min-h-screen items-center justify-center px-4 pb-20 pt-4 text-center sm:block sm:p-0"
> >
<!-- <!--
Background overlay, show/hide based on modal state. Background overlay, show/hide based on modal state.
@ -18,13 +18,13 @@
--> -->
<div class="fixed inset-0 transition-opacity" aria-hidden="true"> <div class="fixed inset-0 transition-opacity" aria-hidden="true">
<div <div
class="absolute inset-0 bg-gray-500 dark:bg-black opacity-75 dark:opacity-50" class="absolute inset-0 bg-gray-500 opacity-75 dark:bg-black dark:opacity-50"
/> />
</div> </div>
<!-- This element is to trick the browser into centering the modal contents. --> <!-- This element is to trick the browser into centering the modal contents. -->
<span <span
class="hidden sm:inline-block sm:align-middle sm:h-screen" class="hidden sm:inline-block sm:h-screen sm:align-middle"
aria-hidden="true" aria-hidden="true"
>&#8203;</span >&#8203;</span
> >
@ -39,22 +39,22 @@
To: "opacity-0 tranneutral-y-4 sm:tranneutral-y-0 sm:scale-95" To: "opacity-0 tranneutral-y-4 sm:tranneutral-y-0 sm:scale-95"
--> -->
<div <div
class="inline-block align-bottom bg-white dark:bg-neutral-700 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg w-full" class="inline-block w-full transform overflow-hidden rounded-lg bg-white text-left align-bottom shadow-xl transition-all sm:my-8 sm:max-w-lg sm:align-middle dark:bg-neutral-700"
role="dialog" role="dialog"
aria-modal="true" aria-modal="true"
aria-labelledby="modal-headline" aria-labelledby="modal-headline"
> >
<div class="bg-white dark:bg-neutral-700 px-4 pt-5 pb-4 sm:p-6 sm:pb-4"> <div class="bg-white px-4 pb-4 pt-5 sm:p-6 sm:pb-4 dark:bg-neutral-700">
<div class="sm:flex sm:items-start"> <div class="sm:flex sm:items-start">
<div <div
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10" class="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10"
> >
<IconsWarning class="h-6 w-6 text-red-600" /> <IconsWarning class="h-6 w-6 text-red-600" />
</div> </div>
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left"> <div class="mt-3 text-center sm:ml-4 sm:mt-0 sm:text-left">
<h3 <h3
id="modal-headline" id="modal-headline"
class="text-lg leading-6 font-medium text-gray-900 dark:text-neutral-200" class="text-lg font-medium leading-6 text-gray-900 dark:text-neutral-200"
> >
{{ $t('deleteClient') }} {{ $t('deleteClient') }}
</h3> </h3>
@ -69,11 +69,11 @@
</div> </div>
</div> </div>
<div <div
class="bg-gray-50 dark:bg-neutral-600 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse" class="bg-gray-50 px-4 py-3 sm:flex sm:flex-row-reverse sm:px-6 dark:bg-neutral-600"
> >
<button <button
type="button" type="button"
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 dark:bg-red-600 text-base font-medium text-white dark:text-white hover:bg-red-700 dark:hover:bg-red-700 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm" class="inline-flex w-full justify-center rounded-md border border-transparent bg-red-600 px-4 py-2 text-base font-medium text-white shadow-sm hover:bg-red-700 focus:outline-none sm:ml-3 sm:w-auto sm:text-sm dark:bg-red-600 dark:text-white dark:hover:bg-red-700"
@click=" @click="
modalStore.deleteClient(modalStore.clientDelete); modalStore.deleteClient(modalStore.clientDelete);
modalStore.clientDelete = null; modalStore.clientDelete = null;
@ -83,7 +83,7 @@
</button> </button>
<button <button
type="button" type="button"
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-neutral-500 shadow-sm px-4 py-2 bg-white dark:bg-neutral-500 text-base font-medium text-gray-700 dark:text-neutral-50 hover:bg-gray-50 dark:hover:bg-neutral-600 dark:hover:border-neutral-600 focus:outline-none sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm" class="mt-3 inline-flex w-full justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-base font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none sm:ml-3 sm:mt-0 sm:w-auto sm:text-sm dark:border-neutral-500 dark:bg-neutral-500 dark:text-neutral-50 dark:hover:border-neutral-600 dark:hover:bg-neutral-600"
@click="modalStore.clientDelete = null" @click="modalStore.clientDelete = null"
> >
{{ $t('cancel') }} {{ $t('cancel') }}

6
src/app/components/Clients/Empty.vue

@ -1,15 +1,15 @@
<template> <template>
<p class="text-center m-10 text-gray-400 dark:text-neutral-400 text-sm"> <p class="m-10 text-center text-sm text-gray-400 dark:text-neutral-400">
{{ $t('noClients') }}<br /><br /> {{ $t('noClients') }}<br /><br />
<button <button
class="bg-red-800 hover:bg-red-700 text-white border-2 border-none py-2 px-4 rounded inline-flex items-center transition" class="inline-flex items-center rounded border-2 border-none bg-red-800 px-4 py-2 text-white transition hover:bg-red-700"
@click=" @click="
modalStore.clientCreate = true; modalStore.clientCreate = true;
modalStore.clientCreateName = ''; modalStore.clientCreateName = '';
modalStore.clientExpireDate = ''; modalStore.clientExpireDate = '';
" "
> >
<IconsPlus class="w-4 mr-2" /> <IconsPlus class="mr-2 w-4" />
<span class="text-sm">{{ $t('newClient') }}</span> <span class="text-sm">{{ $t('newClient') }}</span>
</button> </button>
</p> </p>

2
src/app/components/Clients/New.vue

@ -7,7 +7,7 @@
" "
> >
<IconsPlus class="w-4 md:mr-2" /> <IconsPlus class="w-4 md:mr-2" />
<span class="max-md:hidden text-sm">{{ $t('new') }}</span> <span class="text-sm max-md:hidden">{{ $t('new') }}</span>
</BaseButton> </BaseButton>
</template> </template>

6
src/app/components/Clients/QRCodeDialog.vue

@ -1,11 +1,11 @@
<template> <template>
<div v-if="modalStore.qrcode"> <div v-if="modalStore.qrcode">
<div <div
class="bg-black bg-opacity-50 fixed top-0 right-0 left-0 bottom-0 flex items-center justify-center z-20" class="fixed bottom-0 left-0 right-0 top-0 z-20 flex items-center justify-center bg-black bg-opacity-50"
> >
<div class="bg-white rounded-md shadow-lg relative p-8"> <div class="relative rounded-md bg-white p-8 shadow-lg">
<button <button
class="absolute right-4 top-4 text-gray-600 dark:text-neutral-500 hover:text-gray-800 dark:hover:text-neutral-700" class="absolute right-4 top-4 text-gray-600 hover:text-gray-800 dark:text-neutral-500 dark:hover:text-neutral-700"
@click="modalStore.qrcode = null" @click="modalStore.qrcode = null"
> >
<IconsClose class="w-8" /> <IconsClose class="w-8" />

2
src/app/components/Clients/RestoreConfig.vue

@ -1,7 +1,7 @@
<template> <template>
<BaseButton as="label" for="inputRC" :title="$t('titleRestoreConfig')"> <BaseButton as="label" for="inputRC" :title="$t('titleRestoreConfig')">
<IconsArrowInf class="w-4 md:mr-2" /> <IconsArrowInf class="w-4 md:mr-2" />
<span class="max-md:hidden text-sm">{{ $t('restore') }}</span> <span class="text-sm max-md:hidden">{{ $t('restore') }}</span>
<input <input
id="inputRC" id="inputRC"
type="file" type="file"

4
src/app/components/Clients/Sort.vue

@ -1,7 +1,7 @@
<template> <template>
<button <button
v-if="globalStore.features.sortClients.enabled" v-if="globalStore.features.sortClients.enabled"
class="hover:bg-red-800 hover:border-red-800 hover:text-white text-gray-700 dark:text-neutral-200 max-md:border-x-0 border-2 border-gray-100 dark:border-neutral-600 py-2 px-4 md:rounded inline-flex items-center transition" class="inline-flex items-center border-2 border-gray-100 px-4 py-2 text-gray-700 transition hover:border-red-800 hover:bg-red-800 hover:text-white max-md:border-x-0 md:rounded dark:border-neutral-600 dark:text-neutral-200"
@click="globalStore.sortClient = !globalStore.sortClient" @click="globalStore.sortClient = !globalStore.sortClient"
> >
<svg <svg
@ -42,7 +42,7 @@
fill="#000000" fill="#000000"
/> />
</svg> </svg>
<span class="max-md:hidden text-sm">{{ $t('sort') }}</span> <span class="text-sm max-md:hidden">{{ $t('sort') }}</span>
</button> </button>
</template> </template>

2
src/app/components/base/Button.vue

@ -2,7 +2,7 @@
<component <component
:is="elementType" :is="elementType"
role="button" role="button"
class="hover:bg-red-800 hover:border-red-800 hover:text-white text-gray-700 dark:text-neutral-200 max-md:border-x-0 border-2 border-gray-100 dark:border-neutral-600 py-2 md:px-4 rounded max-md:rounded-full inline-flex items-center transition" class="inline-flex items-center rounded border-2 border-gray-100 py-2 text-gray-700 transition hover:border-red-800 hover:bg-red-800 hover:text-white max-md:rounded-full max-md:border-x-0 md:px-4 dark:border-neutral-600 dark:text-neutral-200"
v-bind="attrs" v-bind="attrs"
> >
<slot /> <slot />

4
src/app/components/base/Switch.vue

@ -2,10 +2,10 @@
<SwitchRoot <SwitchRoot
:id="id" :id="id"
v-model:checked="data" v-model:checked="data"
class="w-[40px] h-[24px] focus-within:outline focus-within:outline-red-700 flex bg-gray-200 dark:bg-neutral-400 shadow-sm rounded-full relative data-[state=checked]:bg-red-800 cursor-default" class="relative flex h-[24px] w-[40px] cursor-default rounded-full bg-gray-200 shadow-sm focus-within:outline focus-within:outline-red-700 data-[state=checked]:bg-red-800 dark:bg-neutral-400"
> >
<SwitchThumb <SwitchThumb
class="block w-[16px] h-[16px] my-auto bg-white shadow-sm rounded-full transition-transform duration-100 translate-x-1 will-change-transform data-[state=checked]:translate-x-[20px]" class="my-auto block h-[16px] w-[16px] translate-x-1 rounded-full bg-white shadow-sm transition-transform duration-100 will-change-transform data-[state=checked]:translate-x-[20px]"
/> />
</SwitchRoot> </SwitchRoot>
</template> </template>

4
src/app/components/error/Toast.vue

@ -9,9 +9,9 @@ const { title, message, duration } = defineProps<{
<template> <template>
<ToastRoot <ToastRoot
:duration="duration" :duration="duration"
class="bg-red-800 rounded-md p-2 text-neutral-200" class="rounded-md bg-red-800 p-2 text-neutral-200"
> >
<ToastTitle class="mb-4 font-medium text-lg">{{ title }} </ToastTitle> <ToastTitle class="mb-4 text-lg font-medium">{{ title }} </ToastTitle>
<ToastDescription as-child>{{ message }}</ToastDescription> <ToastDescription as-child>{{ message }}</ToastDescription>
</ToastRoot> </ToastRoot>
</template> </template>

2
src/app/components/form/ActionField.vue

@ -2,7 +2,7 @@
<input <input
:value="label" :value="label"
type="button" type="button"
class="dark:bg-neutral-700 text-gray-500 col-span-2 py-2 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-800 rounded-lg focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="col-span-2 rounded-lg border-2 border-gray-100 py-2 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
/> />
</template> </template>

2
src/app/components/form/ArrayField.vue

@ -4,7 +4,7 @@
<input <input
:value="item" :value="item"
type="text" type="text"
class="dark:bg-neutral-700 text-gray-500 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-800 rounded-lg focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
@input="update(i)" @input="update(i)"
/> />
<input type="button" value="-" @click="del(i)" /> <input type="button" value="-" @click="del(i)" />

2
src/app/components/form/Group.vue

@ -3,7 +3,7 @@
<slot /> <slot />
<Separator <Separator
decorative decorative
class="w-full h-px bg-gray-100 dark:bg-neutral-600 col-span-2" class="col-span-2 h-px w-full bg-gray-100 dark:bg-neutral-600"
/> />
</section> </section>
</template> </template>

2
src/app/components/form/Heading.vue

@ -1,5 +1,5 @@
<template> <template>
<h4 class="text-2xl col-span-full py-6"> <h4 class="col-span-full py-6 text-2xl">
<slot /> <slot />
</h4> </h4>
</template> </template>

2
src/app/components/form/NumberField.vue

@ -6,7 +6,7 @@
:id="id" :id="id"
v-model.number="data" v-model.number="data"
type="number" type="number"
class="dark:bg-neutral-700 text-gray-500 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-800 rounded-lg focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
/> />
</template> </template>

2
src/app/components/form/TextField.vue

@ -6,7 +6,7 @@
:id="id" :id="id"
v-model="data" v-model="data"
type="text" type="text"
class="dark:bg-neutral-700 text-gray-500 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-800 rounded-lg focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
/> />
</template> </template>

2
src/app/components/panel/Panel.vue

@ -1,6 +1,6 @@
<template> <template>
<div <div
class="container mx-auto max-w-3xl px-3 md:px-0 shadow-md rounded-lg bg-white dark:bg-neutral-700 text-gray-700 dark:text-neutral-200 overflow-hidden" class="container mx-auto max-w-3xl overflow-hidden rounded-lg bg-white px-3 text-gray-700 shadow-md md:px-0 dark:bg-neutral-700 dark:text-neutral-200"
> >
<slot /> <slot />
</div> </div>

2
src/app/components/panel/head/Boat.vue

@ -1,5 +1,5 @@
<template> <template>
<div class="flex md:block flex-shrink-0 space-x-1"> <div class="flex flex-shrink-0 space-x-1 md:block">
<slot /> <slot />
</div> </div>
</template> </template>

2
src/app/components/panel/head/Head.vue

@ -1,6 +1,6 @@
<template> <template>
<div <div
class="flex flex-row flex-grow flex-auto items-center p-3 px-5 border-b-2 border-gray-100 dark:border-neutral-600" class="flex flex-auto flex-grow flex-row items-center border-b-2 border-gray-100 p-3 px-5 dark:border-neutral-600"
> >
<slot /> <slot />
</div> </div>

4
src/app/components/ui/Banner.vue

@ -1,8 +1,8 @@
<template> <template>
<h1 <h1
class="text-4xl font-medium my-16 text-center text-gray-700 dark:text-neutral-200" class="my-16 text-center text-4xl font-medium text-gray-700 dark:text-neutral-200"
> >
<img src="/logo.png" width="32" class="inline align-middle dark:bg" /> <img src="/logo.png" width="32" class="dark:bg inline align-middle" />
<span class="align-middle">WireGuard</span> <span class="align-middle">WireGuard</span>
</h1> </h1>
</template> </template>

6
src/app/components/ui/ChooseLang.vue

@ -1,7 +1,7 @@
<template> <template>
<SelectRoot v-model="langProxy" :default-value="locale"> <SelectRoot v-model="langProxy" :default-value="locale">
<SelectTrigger <SelectTrigger
class="inline-flex min-w-[160px] items-center justify-between rounded px-[15px] text-[13px] dark:text-white leading-none h-[35px] gap-[5px] dark:bg-neutral-500" class="inline-flex h-[35px] min-w-[160px] items-center justify-between gap-[5px] rounded px-[15px] text-[13px] leading-none dark:bg-neutral-500 dark:text-white"
aria-label="Customise language" aria-label="Customise language"
> >
<SelectValue :placeholder="$t('setup.chooseLang')" /> <SelectValue :placeholder="$t('setup.chooseLang')" />
@ -10,7 +10,7 @@
<SelectPortal> <SelectPortal>
<SelectContent <SelectContent
class="min-w-[160px] bg-white dark:bg-neutral-500 rounded" class="min-w-[160px] rounded bg-white dark:bg-neutral-500"
:side-offset="5" :side-offset="5"
> >
<SelectViewport class="p-[5px]"> <SelectViewport class="p-[5px]">
@ -18,7 +18,7 @@
v-for="(option, index) in langs" v-for="(option, index) in langs"
:key="index" :key="index"
:value="option.value" :value="option.value"
class="text-[13px] leading-none text-grass11 hover:bg-red-800 dark:text-white hover:text-white rounded-[3px] flex items-center h-[25px] pr-[35px] pl-[25px] relative" class="text-grass11 relative flex h-[25px] items-center rounded-[3px] pl-[25px] pr-[35px] text-[13px] leading-none hover:bg-red-800 hover:text-white dark:text-white"
> >
<SelectItemText> <SelectItemText>
{{ option.name }} {{ option.name }}

2
src/app/components/ui/StepProgress.vue

@ -3,7 +3,7 @@
v-for="n in totalSteps" v-for="n in totalSteps"
:key="n" :key="n"
:class="[ :class="[
'step grow h-[3px] mx-3', 'step mx-3 h-[3px] grow',
step >= n ? 'bg-red-800 dark:bg-white' : 'bg-gray-500', step >= n ? 'bg-red-800 dark:bg-white' : 'bg-gray-500',
]" ]"
></div> ></div>

6
src/app/components/ui/Toast.vue

@ -15,16 +15,16 @@ defineProps<{
<template> <template>
<ToastRoot <ToastRoot
class="bg-white rounded-md shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,_hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] p-[15px] grid [grid-template-areas:_'title_action'_'description_action'] grid-cols-[auto_max-content] gap-x-[15px] items-center data-[state=open]:animate-slideIn data-[state=closed]:animate-hide data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=cancel]:translate-x-0 data-[swipe=cancel]:transition-[transform_200ms_ease-out] data-[swipe=end]:animate-swipeOut" class="data-[state=open]:animate-slideIn data-[state=closed]:animate-hide data-[swipe=end]:animate-swipeOut grid grid-cols-[auto_max-content] items-center gap-x-[15px] rounded-md bg-white p-[15px] shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,_hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] [grid-template-areas:_'title_action'_'description_action'] data-[swipe=cancel]:translate-x-0 data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=cancel]:transition-[transform_200ms_ease-out]"
> >
<ToastTitle <ToastTitle
v-if="title" v-if="title"
class="[grid-area:_title] mb-[5px] font-medium text-slate12 text-[15px]" class="text-slate12 mb-[5px] text-[15px] font-medium [grid-area:_title]"
> >
{{ title }} {{ title }}
</ToastTitle> </ToastTitle>
<ToastDescription <ToastDescription
class="[grid-area:_description] m-0 text-slate11 text-[13px] leading-[1.3]" class="text-slate11 m-0 text-[13px] leading-[1.3] [grid-area:_description]"
>{{ content }}</ToastDescription >{{ content }}</ToastDescription
> >
<ToastAction as-child alt-text="toast" class="[grid-area:_action]"> <ToastAction as-child alt-text="toast" class="[grid-area:_action]">

8
src/app/components/ui/UserMenu.vue

@ -2,11 +2,11 @@
<DropdownMenuRoot v-model:open="toggleState"> <DropdownMenuRoot v-model:open="toggleState">
<DropdownMenuTrigger> <DropdownMenuTrigger>
<button <button
class="flex items-center pe-1 font-medium text-sm text-gray-400 rounded-full hover:text-red-800 dark:hover:text-red-800 md:me-0 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:text-neutral-400" class="flex items-center rounded-full pe-1 text-sm font-medium text-gray-400 hover:text-red-800 focus:ring-4 focus:ring-gray-100 md:me-0 dark:text-neutral-400 dark:hover:text-red-800 dark:focus:ring-gray-700"
type="button" type="button"
> >
<AvatarRoot <AvatarRoot
class="inline-flex h-8 w-8 select-none items-center justify-center overflow-hidden rounded-full align-middle mr-2" class="mr-2 inline-flex h-8 w-8 select-none items-center justify-center overflow-hidden rounded-full align-middle"
> >
<AvatarFallback <AvatarFallback
class="leading-1 flex h-full w-full items-center justify-center bg-white text-[15px] font-medium" class="leading-1 flex h-full w-full items-center justify-center bg-white text-[15px] font-medium"
@ -22,7 +22,7 @@
<DropdownMenuPortal> <DropdownMenuPortal>
<DropdownMenuContent <DropdownMenuContent
:side-offset="5" :side-offset="5"
class="z-10 bg-white divide-y divide-gray-100 rounded-lg shadow w-44 dark:bg-neutral-700 dark:divide-neutral-800 text-gray-700 dark:text-gray-200" class="z-10 w-44 divide-y divide-gray-100 rounded-lg bg-white text-gray-700 shadow dark:divide-neutral-800 dark:bg-neutral-700 dark:text-gray-200"
> >
<DropdownMenuItem> <DropdownMenuItem>
<div class="truncate">{{ authStore.userData?.name }}</div> <div class="truncate">{{ authStore.userData?.name }}</div>
@ -54,7 +54,7 @@
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuItem> <DropdownMenuItem>
<button <button
class="flex items-center gap-2 w-full px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 dark:text-gray-200 dark:hover:text-white" class="flex w-full items-center gap-2 px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-600 dark:hover:text-white"
@click.prevent="logout" @click.prevent="logout"
> >
<IconsLogout class="h-5" /> <IconsLogout class="h-5" />

36
src/app/layouts/default.vue

@ -1,69 +1,69 @@
<template> <template>
<div> <div>
<header class="container mx-auto max-w-3xl px-3 md:px-0 mt-4 xs:mt-6"> <header class="container mx-auto mt-4 max-w-3xl px-3 xs:mt-6 md:px-0">
<div <div
:class=" :class="
hasOwnLogo hasOwnLogo
? 'flex justify-end' ? 'flex justify-end'
: 'flex flex-col-reverse xxs:flex-row flex-auto items-center gap-3' : 'flex flex-auto flex-col-reverse items-center gap-3 xxs:flex-row'
" "
> >
<NuxtLink to="/" class="flex-grow self-start mb-4"> <NuxtLink to="/" class="mb-4 flex-grow self-start">
<h1 <h1
v-if="!hasOwnLogo" v-if="!hasOwnLogo"
class="text-4xl dark:text-neutral-200 font-medium" class="text-4xl font-medium dark:text-neutral-200"
> >
<img <img
src="/logo.png" src="/logo.png"
width="32" width="32"
class="inline align-middle dark:bg mr-2" class="dark:bg mr-2 inline align-middle"
/><span class="align-middle">WireGuard</span> /><span class="align-middle">WireGuard</span>
</h1> </h1>
</NuxtLink> </NuxtLink>
<div class="flex items-center grow-0 gap-3 self-end xxs:self-center"> <div class="flex grow-0 items-center gap-3 self-end xxs:self-center">
<!-- Dark / light theme --> <!-- Dark / light theme -->
<button <button
class="flex items-center justify-center w-8 h-8 rounded-full bg-gray-200 hover:bg-gray-300 dark:bg-neutral-700 dark:hover:bg-neutral-600 transition" class="flex h-8 w-8 items-center justify-center rounded-full bg-gray-200 transition hover:bg-gray-300 dark:bg-neutral-700 dark:hover:bg-neutral-600"
:title="$t(`theme.${theme.preference}`)" :title="$t(`theme.${theme.preference}`)"
@click="toggleTheme" @click="toggleTheme"
> >
<IconsSun v-if="theme.preference === 'light'" class="w-5 h-5" /> <IconsSun v-if="theme.preference === 'light'" class="h-5 w-5" />
<IconsMoon <IconsMoon
v-else-if="theme.preference === 'dark'" v-else-if="theme.preference === 'dark'"
class="w-5 h-5 text-neutral-400" class="h-5 w-5 text-neutral-400"
/> />
<IconsHalfMoon <IconsHalfMoon
v-else v-else
class="w-5 h-5 fill-gray-600 dark:fill-neutral-400" class="h-5 w-5 fill-gray-600 dark:fill-neutral-400"
/> />
</button> </button>
<!-- Show / hide charts --> <!-- Show / hide charts -->
<label <label
v-if="globalStore.statistics.chartType > 0" v-if="globalStore.statistics.chartType > 0"
class="inline-flex items-center justify-center cursor-pointer w-8 h-8 rounded-full bg-gray-200 hover:bg-gray-300 dark:bg-neutral-700 dark:hover:bg-neutral-600 whitespace-nowrap transition group" class="group inline-flex h-8 w-8 cursor-pointer items-center justify-center whitespace-nowrap rounded-full bg-gray-200 transition hover:bg-gray-300 dark:bg-neutral-700 dark:hover:bg-neutral-600"
:title="$t('toggleCharts')" :title="$t('toggleCharts')"
> >
<input <input
v-model="uiShowCharts" v-model="uiShowCharts"
type="checkbox" type="checkbox"
value="" value=""
class="sr-only peer" class="peer sr-only"
@change="toggleCharts" @change="toggleCharts"
/> />
<IconsChart <IconsChart
class="w-5 h-5 peer fill-gray-400 peer-checked:fill-gray-600 dark:fill-neutral-600 peer-checked:dark:fill-neutral-400 group-hover:dark:fill-neutral-500 transition" class="peer h-5 w-5 fill-gray-400 transition peer-checked:fill-gray-600 dark:fill-neutral-600 group-hover:dark:fill-neutral-500 peer-checked:dark:fill-neutral-400"
/> />
</label> </label>
<UiUserMenu v-if="loggedIn" /> <UiUserMenu v-if="loggedIn" />
</div> </div>
</div> </div>
<div class="text-sm text-gray-400 dark:text-neutral-400 mb-5" /> <div class="mb-5 text-sm text-gray-400 dark:text-neutral-400" />
<div <div
v-if="globalStore.updateAvailable && globalStore.latestRelease" v-if="globalStore.updateAvailable && globalStore.latestRelease"
class="bg-red-800 dark:bg-red-100 p-4 text-white dark:text-red-600 text-sm font-small mb-10 rounded-md shadow-lg" class="font-small mb-10 rounded-md bg-red-800 p-4 text-sm text-white shadow-lg dark:bg-red-100 dark:text-red-600"
:title="`v${globalStore.currentRelease} → v${globalStore.latestRelease.version}`" :title="`v${globalStore.currentRelease} → v${globalStore.latestRelease.version}`"
> >
<div class="container mx-auto flex flex-row flex-auto items-center"> <div class="container mx-auto flex flex-auto flex-row items-center">
<div class="flex-grow"> <div class="flex-grow">
<p class="font-bold">{{ $t('updateAvailable') }}</p> <p class="font-bold">{{ $t('updateAvailable') }}</p>
<p>{{ globalStore.latestRelease.changelog }}</p> <p>{{ globalStore.latestRelease.changelog }}</p>
@ -72,7 +72,7 @@
<a <a
:href="`https://github.com/wg-easy/wg-easy/releases/tag/${globalStore.latestRelease.version}`" :href="`https://github.com/wg-easy/wg-easy/releases/tag/${globalStore.latestRelease.version}`"
target="_blank" target="_blank"
class="p-3 rounded-md bg-white dark:bg-red-100 float-right font-sm font-semibold text-red-800 dark:text-red-600 flex-shrink-0 border-2 border-red-800 dark:border-red-600 hover:border-white dark:hover:border-red-600 hover:text-white dark:hover:text-red-100 hover:bg-red-800 dark:hover:bg-red-600 transition-all" class="font-sm float-right flex-shrink-0 rounded-md border-2 border-red-800 bg-white p-3 font-semibold text-red-800 transition-all hover:border-white hover:bg-red-800 hover:text-white dark:border-red-600 dark:bg-red-100 dark:text-red-600 dark:hover:border-red-600 dark:hover:bg-red-600 dark:hover:text-red-100"
> >
{{ $t('update') }} {{ $t('update') }}
</a> </a>
@ -81,7 +81,7 @@
</header> </header>
<slot /> <slot />
<footer> <footer>
<p class="text-center m-10 text-gray-300 dark:text-neutral-600 text-xs"> <p class="m-10 text-center text-xs text-gray-300 dark:text-neutral-600">
<a <a
class="hover:underline" class="hover:underline"
target="_blank" target="_blank"

4
src/app/layouts/setup.vue

@ -2,8 +2,8 @@
<main class="container mx-auto px-4"> <main class="container mx-auto px-4">
<UiBanner /> <UiBanner />
<Panel> <Panel>
<PanelBody class="md:w-[70%] lg:w-[60%] mx-auto mt-10 p-4"> <PanelBody class="mx-auto mt-10 p-4 md:w-[70%] lg:w-[60%]">
<h2 class="mt-8 mb-16 text-3xl font-medium"> <h2 class="mb-16 mt-8 text-3xl font-medium">
{{ $t('setup.welcome') }} {{ $t('setup.welcome') }}
</h2> </h2>

12
src/app/pages/admin.vue

@ -2,20 +2,20 @@
<div> <div>
<div class="container mx-auto p-4"> <div class="container mx-auto p-4">
<div class="flex"> <div class="flex">
<div class="w-64 bg-white dark:bg-neutral-700 rounded-lg p-4 mr-4"> <div class="mr-4 w-64 rounded-lg bg-white p-4 dark:bg-neutral-700">
<NuxtLink to="/admin"> <NuxtLink to="/admin">
<h2 class="text-xl font-bold dark:text-neutral-200 mb-4"> <h2 class="mb-4 text-xl font-bold dark:text-neutral-200">
Admin Panel Admin Panel
</h2> </h2>
</NuxtLink> </NuxtLink>
<div class="space-y-2 flex flex-col"> <div class="flex flex-col space-y-2">
<NuxtLink <NuxtLink
v-for="(item, index) in menuItems" v-for="(item, index) in menuItems"
:key="index" :key="index"
:to="`/admin/${item.id}`" :to="`/admin/${item.id}`"
> >
<BaseButton <BaseButton
class="font-medium dark:text-neutral-200 p-2 rounded cursor-pointer hover:bg-red-800 transition-colors duration-200 w-full" class="w-full cursor-pointer rounded p-2 font-medium transition-colors duration-200 hover:bg-red-800 dark:text-neutral-200"
> >
{{ item.name }} {{ item.name }}
</BaseButton> </BaseButton>
@ -24,9 +24,9 @@
</div> </div>
<div <div
class="flex-1 bg-white dark:text-neutral-200 dark:bg-neutral-700 rounded-lg p-6" class="flex-1 rounded-lg bg-white p-6 dark:bg-neutral-700 dark:text-neutral-200"
> >
<h1 class="text-3xl font-bold mb-6">{{ activeMenuItem?.name }}</h1> <h1 class="mb-6 text-3xl font-bold">{{ activeMenuItem?.name }}</h1>
<NuxtPage /> <NuxtPage />
</div> </div>
</div> </div>

2
src/app/pages/admin/features.vue

@ -12,7 +12,7 @@
</div> </div>
<SwitchRoot <SwitchRoot
:checked="feature.enabled" :checked="feature.enabled"
class="relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-800" class="relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-red-800 focus:ring-offset-2"
:class="feature.enabled ? 'bg-red-800' : 'bg-gray-200'" :class="feature.enabled ? 'bg-red-800' : 'bg-gray-200'"
@update:checked="toggleFeature(key)" @update:checked="toggleFeature(key)"
> >

12
src/app/pages/admin/statistics.vue

@ -11,7 +11,7 @@
</div> </div>
<SwitchRoot <SwitchRoot
v-model:checked="enabled" v-model:checked="enabled"
class="relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-800" class="relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-red-800 focus:ring-offset-2"
:class="enabled ? 'bg-red-800' : 'bg-gray-200'" :class="enabled ? 'bg-red-800' : 'bg-gray-200'"
> >
<SwitchThumb <SwitchThumb
@ -31,7 +31,7 @@
</div> </div>
<SelectRoot v-model="chartType"> <SelectRoot v-model="chartType">
<SelectTrigger <SelectTrigger
class="inline-flex min-w-[160px] items-center justify-between rounded px-[15px] text-[13px] leading-none h-[35px] gap-[5px] bg-white text-grass11 shadow-[0_2px_10px] shadow-black/10 hover:bg-mauve3 focus:shadow-[0_0_0_2px] focus:shadow-black data-[placeholder]:text-green9 outline-none" class="text-grass11 hover:bg-mauve3 data-[placeholder]:text-green9 inline-flex h-[35px] min-w-[160px] items-center justify-between gap-[5px] rounded bg-white px-[15px] text-[13px] leading-none shadow-[0_2px_10px] shadow-black/10 outline-none focus:shadow-[0_0_0_2px] focus:shadow-black"
aria-label="Customize options" aria-label="Customize options"
> >
<SelectValue placeholder="Select a fruit..." /> <SelectValue placeholder="Select a fruit..." />
@ -40,11 +40,11 @@
<SelectPortal> <SelectPortal>
<SelectContent <SelectContent
class="min-w-[160px] bg-white rounded shadow-[0px_10px_38px_-10px_rgba(22,_23,_24,_0.35),_0px_10px_20px_-15px_rgba(22,_23,_24,_0.2)] will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade z-[100]" class="data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade z-[100] min-w-[160px] rounded bg-white shadow-[0px_10px_38px_-10px_rgba(22,_23,_24,_0.35),_0px_10px_20px_-15px_rgba(22,_23,_24,_0.2)] will-change-[opacity,transform]"
:side-offset="5" :side-offset="5"
> >
<SelectScrollUpButton <SelectScrollUpButton
class="flex items-center justify-center h-[25px] bg-white text-violet11 cursor-default" class="text-violet11 flex h-[25px] cursor-default items-center justify-center bg-white"
> >
<IconsArrowUp /> <IconsArrowUp />
</SelectScrollUpButton> </SelectScrollUpButton>
@ -52,7 +52,7 @@
<SelectItem <SelectItem
v-for="(option, index) in options" v-for="(option, index) in options"
:key="index" :key="index"
class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] pr-[35px] pl-[25px] relative select-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:outline-none data-[highlighted]:bg-green9 data-[highlighted]:text-green1" class="text-grass11 data-[disabled]:text-mauve8 data-[highlighted]:bg-green9 data-[highlighted]:text-green1 relative flex h-[25px] select-none items-center rounded-[3px] pl-[25px] pr-[35px] text-[13px] leading-none data-[disabled]:pointer-events-none data-[highlighted]:outline-none"
:value="option" :value="option"
> >
<SelectItemText> <SelectItemText>
@ -61,7 +61,7 @@
</SelectItem> </SelectItem>
</SelectViewport> </SelectViewport>
<SelectScrollDownButton <SelectScrollDownButton
class="flex items-center justify-center h-[25px] bg-white text-violet11 cursor-default" class="text-violet11 flex h-[25px] cursor-default items-center justify-center bg-white"
> >
<IconsArrowDown /> <IconsArrowDown />
</SelectScrollDownButton> </SelectScrollDownButton>

4
src/app/pages/index.vue

@ -21,9 +21,9 @@
/> />
<div <div
v-if="clientsStore.clients === null" v-if="clientsStore.clients === null"
class="text-gray-200 dark:text-red-300 p-5" class="p-5 text-gray-200 dark:text-red-300"
> >
<IconsLoading class="w-5 animate-spin mx-auto" /> <IconsLoading class="mx-auto w-5 animate-spin" />
</div> </div>
</Panel> </Panel>

30
src/app/pages/login.vue

@ -2,14 +2,14 @@
<main> <main>
<UiBanner /> <UiBanner />
<form <form
class="shadow rounded-md bg-white dark:bg-neutral-700 text-gray-700 dark:text-neutral-200 mx-auto w-64 p-5 overflow-hidden mt-10" class="mx-auto mt-10 w-64 overflow-hidden rounded-md bg-white p-5 text-gray-700 shadow dark:bg-neutral-700 dark:text-neutral-200"
@submit="login" @submit="login"
> >
<!-- Avatar --> <!-- Avatar -->
<div <div
class="h-20 w-20 mb-10 mt-5 mx-auto rounded-full bg-red-800 dark:bg-red-800 relative overflow-hidden" class="relative mx-auto mb-10 mt-5 h-20 w-20 overflow-hidden rounded-full bg-red-800 dark:bg-red-800"
> >
<IconsAvatar class="w-10 h-10 m-5 text-white dark:text-white" /> <IconsAvatar class="m-5 h-10 w-10 text-white dark:text-white" />
</div> </div>
<input <input
@ -19,7 +19,7 @@
:placeholder="$t('username')" :placeholder="$t('username')"
autocomplete="username" autocomplete="username"
autofocus autofocus
class="px-3 py-2 text-sm dark:bg-neutral-700 text-gray-500 dark:text-gray-500 mb-5 border-2 border-gray-100 dark:border-neutral-800 rounded-lg w-full focus:border-red-800 dark:focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="mb-5 w-full rounded-lg border-2 border-gray-100 px-3 py-2 text-sm text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-gray-500 dark:placeholder:text-neutral-400 dark:focus:border-red-800"
/> />
<input <input
@ -28,27 +28,27 @@
name="password" name="password"
:placeholder="$t('password')" :placeholder="$t('password')"
autocomplete="current-password" autocomplete="current-password"
class="px-3 py-2 text-sm dark:bg-neutral-700 text-gray-500 dark:text-gray-500 mb-5 border-2 border-gray-100 dark:border-neutral-800 rounded-lg w-full focus:border-red-800 dark:focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="mb-5 w-full rounded-lg border-2 border-gray-100 px-3 py-2 text-sm text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-gray-500 dark:placeholder:text-neutral-400 dark:focus:border-red-800"
/> />
<label <label
class="inline-block mb-5 cursor-pointer whitespace-nowrap" class="mb-5 inline-block cursor-pointer whitespace-nowrap"
:title="$t('titleRememberMe')" :title="$t('titleRememberMe')"
> >
<input v-model="remember" type="checkbox" class="sr-only" /> <input v-model="remember" type="checkbox" class="sr-only" />
<div <div
v-if="remember" v-if="remember"
class="inline-block align-middle rounded-full w-10 h-6 mr-1 bg-red-800 cursor-pointer hover:bg-red-700 transition-all" class="mr-1 inline-block h-6 w-10 cursor-pointer rounded-full bg-red-800 align-middle transition-all hover:bg-red-700"
> >
<div class="rounded-full w-4 h-4 m-1 ml-5 bg-white"></div> <div class="m-1 ml-5 h-4 w-4 rounded-full bg-white"></div>
</div> </div>
<div <div
v-if="!remember" v-if="!remember"
class="inline-block align-middle rounded-full w-10 h-6 mr-1 bg-gray-200 dark:bg-neutral-400 cursor-pointer hover:bg-gray-300 dark:hover:bg-neutral-500 transition-all" class="mr-1 inline-block h-6 w-10 cursor-pointer rounded-full bg-gray-200 align-middle transition-all hover:bg-gray-300 dark:bg-neutral-400 dark:hover:bg-neutral-500"
> >
<div class="rounded-full w-4 h-4 m-1 bg-white"></div> <div class="m-1 h-4 w-4 rounded-full bg-white"></div>
</div> </div>
<span class="text-sm">{{ $t('rememberMe') }}</span> <span class="text-sm">{{ $t('rememberMe') }}</span>
@ -56,20 +56,20 @@
<button <button
v-if="authenticating" v-if="authenticating"
class="bg-red-800 dark:bg-red-800 w-full rounded shadow py-2 text-sm text-white dark:text-white cursor-not-allowed" class="w-full cursor-not-allowed rounded bg-red-800 py-2 text-sm text-white shadow dark:bg-red-800 dark:text-white"
> >
<IconsLoading class="w-5 animate-spin mx-auto" /> <IconsLoading class="mx-auto w-5 animate-spin" />
</button> </button>
<input <input
v-else v-else
type="submit" type="submit"
:class="[ :class="[
{ {
'bg-red-800 dark:bg-red-800 hover:bg-red-700 dark:hover:bg-red-700 transition cursor-pointer': 'cursor-pointer bg-red-800 transition hover:bg-red-700 dark:bg-red-800 dark:hover:bg-red-700':
password, password,
'bg-gray-200 dark:bg-neutral-800 cursor-not-allowed': !password, 'cursor-not-allowed bg-gray-200 dark:bg-neutral-800': !password,
}, },
'w-full rounded shadow py-2 text-sm text-white dark:text-white', 'w-full rounded py-2 text-sm text-white shadow dark:text-white',
]" ]"
:value="$t('signIn')" :value="$t('signIn')"
/> />

16
src/app/pages/me.vue

@ -6,7 +6,7 @@
</PanelHead> </PanelHead>
<PanelBody class="dark:text-neutral-200"> <PanelBody class="dark:text-neutral-200">
<section class="grid grid-cols-1 gap-4 md:grid-cols-2"> <section class="grid grid-cols-1 gap-4 md:grid-cols-2">
<h4 class="text-2xl col-span-full py-6"> <h4 class="col-span-full py-6 text-2xl">
{{ $t('me.sectionGeneral') }} {{ $t('me.sectionGeneral') }}
</h4> </h4>
<Label <Label
@ -19,7 +19,7 @@
id="username" id="username"
v-model.trim="username" v-model.trim="username"
type="text" type="text"
class="dark:bg-neutral-700 text-gray-500 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-800 rounded-lg focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
/> />
<Label for="name" class="font-semibold md:align-middle md:leading-10"> <Label for="name" class="font-semibold md:align-middle md:leading-10">
{{ $t('name') }} {{ $t('name') }}
@ -28,7 +28,7 @@
id="name" id="name"
v-model.trim="name" v-model.trim="name"
type="text" type="text"
class="dark:bg-neutral-700 text-gray-500 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-800 rounded-lg focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
/> />
<Label <Label
for="email" for="email"
@ -40,14 +40,14 @@
id="email" id="email"
v-model.trim="email" v-model.trim="email"
type="email" type="email"
class="dark:bg-neutral-700 text-gray-500 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-800 rounded-lg focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
/> />
<div class="col-span-full"> <div class="col-span-full">
<BaseButton @click="submit">{{ $t('save') }}</BaseButton> <BaseButton @click="submit">{{ $t('save') }}</BaseButton>
</div> </div>
</section> </section>
<section class="grid grid-cols-1 gap-4 md:grid-cols-2"> <section class="grid grid-cols-1 gap-4 md:grid-cols-2">
<h4 class="text-2xl col-span-full py-6"> <h4 class="col-span-full py-6 text-2xl">
{{ $t('me.sectionPassword') }} {{ $t('me.sectionPassword') }}
</h4> </h4>
<Label <Label
@ -61,7 +61,7 @@
v-model.trim="currentPassword" v-model.trim="currentPassword"
type="password" type="password"
autocomplete="current-password" autocomplete="current-password"
class="dark:bg-neutral-700 text-gray-500 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-800 rounded-lg focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
/> />
<Label <Label
for="new-password" for="new-password"
@ -74,7 +74,7 @@
v-model.trim="newPassword" v-model.trim="newPassword"
type="password" type="password"
autocomplete="new-password" autocomplete="new-password"
class="dark:bg-neutral-700 text-gray-500 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-800 rounded-lg focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
/> />
<Label <Label
for="confirm-password" for="confirm-password"
@ -87,7 +87,7 @@
v-model.trim="confirmPassword" v-model.trim="confirmPassword"
type="password" type="password"
autocomplete="new-password" autocomplete="new-password"
class="dark:bg-neutral-700 text-gray-500 dark:text-neutral-200 border-2 border-gray-100 dark:border-neutral-800 rounded-lg focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="rounded-lg border-2 border-gray-100 text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-neutral-200 dark:placeholder:text-neutral-400"
/> />
<div class="col-span-full"> <div class="col-span-full">
<BaseButton @click="updatePassword">{{ <BaseButton @click="updatePassword">{{

4
src/app/pages/setup/1.vue

@ -1,9 +1,9 @@
<template> <template>
<div> <div>
<p class="text-lg p-8 text-center"> <p class="p-8 text-center text-lg">
{{ $t('setup.messageSetupLanguage') }} {{ $t('setup.messageSetupLanguage') }}
</p> </p>
<div class="flex justify-center mb-8"> <div class="mb-8 flex justify-center">
<UiChooseLang @update:lang="handleEventUpdateLang" /> <UiChooseLang @update:lang="handleEventUpdateLang" />
</div> </div>
<div><BaseButton @click="updateLang">Continue</BaseButton></div> <div><BaseButton @click="updateLang">Continue</BaseButton></div>

4
src/app/pages/setup/2.vue

@ -1,9 +1,9 @@
<template> <template>
<div> <div>
<p class="text-lg p-8 text-center"> <p class="p-8 text-center text-lg">
{{ 'Do you have a existing Setup?' }} {{ 'Do you have a existing Setup?' }}
</p> </p>
<div class="flex justify-center mb-8"> <div class="mb-8 flex justify-center">
<NuxtLink to="/setup/3"><BaseButton>No</BaseButton></NuxtLink> <NuxtLink to="/setup/3"><BaseButton>No</BaseButton></NuxtLink>
<NuxtLink to="/setup/migrate"><BaseButton>Yes</BaseButton></NuxtLink> <NuxtLink to="/setup/migrate"><BaseButton>Yes</BaseButton></NuxtLink>
</div> </div>

2
src/app/pages/setup/3.vue

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<p class="text-2xl pt-8 px-8 text-center"> <p class="px-8 pt-8 text-center text-2xl">
{{ $t('setup.messageWelcome.whatIs') }} {{ $t('setup.messageWelcome.whatIs') }}
</p> </p>
<NuxtLink to="/setup/4"><BaseButton>Continue</BaseButton></NuxtLink> <NuxtLink to="/setup/4"><BaseButton>Continue</BaseButton></NuxtLink>

6
src/app/pages/setup/4.vue

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<p class="text-lg p-8 text-center"> <p class="p-8 text-center text-lg">
{{ $t('setup.messageSetupCreateAdminUser') }} {{ $t('setup.messageSetupCreateAdminUser') }}
</p> </p>
<form id="newAccount"></form> <form id="newAccount"></form>
@ -12,7 +12,7 @@
form="newAccount" form="newAccount"
type="text" type="text"
autocomplete="username" autocomplete="username"
class="px-3 py-2 text-sm dark:bg-neutral-700 text-gray-500 dark:text-gray-200 mb-5 border-2 border-gray-100 dark:border-neutral-800 rounded-lg w-full focus:border-red-800 dark:focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="mb-5 w-full rounded-lg border-2 border-gray-100 px-3 py-2 text-sm text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-gray-200 dark:placeholder:text-neutral-400 dark:focus:border-red-800"
/> />
</div> </div>
<div> <div>
@ -23,7 +23,7 @@
form="newAccount" form="newAccount"
type="password" type="password"
autocomplete="new-password" autocomplete="new-password"
class="px-3 py-2 text-sm dark:bg-neutral-700 text-gray-500 dark:text-gray-200 mb-5 border-2 border-gray-100 dark:border-neutral-800 rounded-lg w-full focus:border-red-800 dark:focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="mb-5 w-full rounded-lg border-2 border-gray-100 px-3 py-2 text-sm text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-gray-200 dark:placeholder:text-neutral-400 dark:focus:border-red-800"
/> />
</div> </div>
<div> <div>

6
src/app/pages/setup/5.vue

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<p class="text-lg p-8 text-center"> <p class="p-8 text-center text-lg">
{{ $t('setup.messageSetupHostPort') }} {{ $t('setup.messageSetupHostPort') }}
</p> </p>
<div> <div>
@ -9,7 +9,7 @@
id="host" id="host"
v-model="host" v-model="host"
type="text" type="text"
class="px-3 py-2 text-sm dark:bg-neutral-700 text-gray-500 dark:text-gray-200 mb-5 border-2 border-gray-100 dark:border-neutral-800 rounded-lg w-full focus:border-red-800 dark:focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="mb-5 w-full rounded-lg border-2 border-gray-100 px-3 py-2 text-sm text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-gray-200 dark:placeholder:text-neutral-400 dark:focus:border-red-800"
placeholder="vpn.example.com" placeholder="vpn.example.com"
/> />
</div> </div>
@ -21,7 +21,7 @@
type="number" type="number"
:min="1" :min="1"
:max="65535" :max="65535"
class="px-3 py-2 text-sm dark:bg-neutral-700 text-gray-500 dark:text-gray-200 mb-5 border-2 border-gray-100 dark:border-neutral-800 rounded-lg w-full focus:border-red-800 dark:focus:border-red-800 dark:placeholder:text-neutral-400 focus:outline-0 focus:ring-0" class="mb-5 w-full rounded-lg border-2 border-gray-100 px-3 py-2 text-sm text-gray-500 focus:border-red-800 focus:outline-0 focus:ring-0 dark:border-neutral-800 dark:bg-neutral-700 dark:text-gray-200 dark:placeholder:text-neutral-400 dark:focus:border-red-800"
/> />
</div> </div>
<BaseButton @click="updateHostPort">Continue</BaseButton> <BaseButton @click="updateHostPort">Continue</BaseButton>

2
src/app/pages/setup/migrate.vue

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<p class="text-lg p-8 text-center"> <p class="p-8 text-center text-lg">
{{ $t('setup.messageSetupMigration') }} {{ $t('setup.messageSetupMigration') }}
</p> </p>
<div> <div>

1
src/package.json

@ -51,6 +51,7 @@
"eslint": "^9.9.1", "eslint": "^9.9.1",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"prettier": "^3.3.3", "prettier": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.8",
"typescript": "^5.5.4", "typescript": "^5.5.4",
"vue-tsc": "^2.1.4" "vue-tsc": "^2.1.4"
}, },

62
src/pnpm-lock.yaml

@ -105,6 +105,9 @@ importers:
prettier: prettier:
specifier: ^3.3.3 specifier: ^3.3.3
version: 3.3.3 version: 3.3.3
prettier-plugin-tailwindcss:
specifier: ^0.6.8
version: 0.6.8(prettier@3.3.3)
typescript: typescript:
specifier: ^5.5.4 specifier: ^5.5.4
version: 5.5.4 version: 5.5.4
@ -3563,6 +3566,61 @@ packages:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
prettier-plugin-tailwindcss@0.6.8:
resolution: {integrity: sha512-dGu3kdm7SXPkiW4nzeWKCl3uoImdd5CTZEJGxyypEPL37Wj0HT2pLqjrvSei1nTeuQfO4PUfjeW5cTUNRLZ4sA==}
engines: {node: '>=14.21.3'}
peerDependencies:
'@ianvs/prettier-plugin-sort-imports': '*'
'@prettier/plugin-pug': '*'
'@shopify/prettier-plugin-liquid': '*'
'@trivago/prettier-plugin-sort-imports': '*'
'@zackad/prettier-plugin-twig-melody': '*'
prettier: ^3.0
prettier-plugin-astro: '*'
prettier-plugin-css-order: '*'
prettier-plugin-import-sort: '*'
prettier-plugin-jsdoc: '*'
prettier-plugin-marko: '*'
prettier-plugin-multiline-arrays: '*'
prettier-plugin-organize-attributes: '*'
prettier-plugin-organize-imports: '*'
prettier-plugin-sort-imports: '*'
prettier-plugin-style-order: '*'
prettier-plugin-svelte: '*'
peerDependenciesMeta:
'@ianvs/prettier-plugin-sort-imports':
optional: true
'@prettier/plugin-pug':
optional: true
'@shopify/prettier-plugin-liquid':
optional: true
'@trivago/prettier-plugin-sort-imports':
optional: true
'@zackad/prettier-plugin-twig-melody':
optional: true
prettier-plugin-astro:
optional: true
prettier-plugin-css-order:
optional: true
prettier-plugin-import-sort:
optional: true
prettier-plugin-jsdoc:
optional: true
prettier-plugin-marko:
optional: true
prettier-plugin-multiline-arrays:
optional: true
prettier-plugin-organize-attributes:
optional: true
prettier-plugin-organize-imports:
optional: true
prettier-plugin-sort-imports:
optional: true
prettier-plugin-style-order:
optional: true
prettier-plugin-svelte:
optional: true
prettier@3.3.3: prettier@3.3.3:
resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==}
engines: {node: '>=14'} engines: {node: '>=14'}
@ -8399,6 +8457,10 @@ snapshots:
prelude-ls@1.2.1: {} prelude-ls@1.2.1: {}
prettier-plugin-tailwindcss@0.6.8(prettier@3.3.3):
dependencies:
prettier: 3.3.3
prettier@3.3.3: {} prettier@3.3.3: {}
pretty-bytes@6.1.1: {} pretty-bytes@6.1.1: {}

Loading…
Cancel
Save