mirror of https://github.com/wg-easy/wg-easy
42 changed files with 348 additions and 502 deletions
@ -1,11 +1,11 @@ |
|||
<script setup lang="ts"> |
|||
const { text } = defineProps<{ |
|||
text: string; |
|||
}>(); |
|||
</script> |
|||
|
|||
<template> |
|||
<h2 class="flex-1 text-2xl font-medium"> |
|||
{{ text }} |
|||
</h2> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
const { text } = defineProps<{ |
|||
text: string; |
|||
}>(); |
|||
</script> |
|||
|
@ -1,45 +0,0 @@ |
|||
<template> |
|||
<SelectRoot v-model="langProxy" :default-value="locale"> |
|||
<SelectTrigger |
|||
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="Customize language" |
|||
> |
|||
<SelectValue :placeholder="$t('setup.chooseLang')" /> |
|||
<IconsArrowDown class="size-4" /> |
|||
</SelectTrigger> |
|||
|
|||
<SelectPortal> |
|||
<SelectContent |
|||
class="min-w-[160px] rounded bg-white dark:bg-neutral-500" |
|||
:side-offset="5" |
|||
> |
|||
<SelectViewport class="p-[5px]"> |
|||
<SelectItem |
|||
v-for="(option, index) in langs" |
|||
:key="index" |
|||
:value="option.code" |
|||
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> |
|||
{{ option.name }} |
|||
</SelectItemText> |
|||
</SelectItem> |
|||
</SelectViewport> |
|||
</SelectContent> |
|||
</SelectPortal> |
|||
</SelectRoot> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
// TODO: improve |
|||
|
|||
const { locales, locale, setLocale } = useI18n(); |
|||
|
|||
const langProxy = ref(locale); |
|||
|
|||
watchEffect(() => { |
|||
setLocale(langProxy.value); |
|||
}); |
|||
|
|||
const langs = locales.value.sort((a, b) => a.code.localeCompare(b.code)); |
|||
</script> |
@ -1,83 +1,59 @@ |
|||
<template> |
|||
<div> |
|||
<p class="p-8 text-center text-lg"> |
|||
{{ $t('setup.messageSetupCreateAdminUser') }} |
|||
{{ $t('setup.createAdminDesc') }} |
|||
</p> |
|||
<form id="newAccount"></form> |
|||
<div> |
|||
<Label for="username">{{ $t('username') }}</Label> |
|||
<input |
|||
id="username" |
|||
v-model="username" |
|||
form="newAccount" |
|||
type="text" |
|||
autocomplete="username" |
|||
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 class="flex flex-col gap-3"> |
|||
<div class="flex flex-col"> |
|||
<FormNullTextField |
|||
id="username" |
|||
v-model="username" |
|||
autocomplete="username" |
|||
:label="$t('general.username')" |
|||
/> |
|||
</div> |
|||
<div class="flex flex-col"> |
|||
<FormPasswordField |
|||
id="password" |
|||
v-model="password" |
|||
autocomplete="new-password" |
|||
:label="$t('general.password')" |
|||
/> |
|||
</div> |
|||
<div> |
|||
<BaseButton @click="submit">{{ $t('setup.createAccount') }}</BaseButton> |
|||
</div> |
|||
</div> |
|||
<div> |
|||
<Label for="password">{{ $t('setup.newPassword') }}</Label> |
|||
<input |
|||
id="password" |
|||
v-model="password" |
|||
form="newAccount" |
|||
type="password" |
|||
autocomplete="new-password" |
|||
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> |
|||
<Label for="accept">{{ $t('setup.accept') }}</Label> |
|||
<input |
|||
id="accept" |
|||
v-model="accept" |
|||
form="newAccount" |
|||
type="checkbox" |
|||
class="ml-2" |
|||
/> |
|||
</div> |
|||
<BaseButton @click="newAccount">Create Account</BaseButton> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { FetchError } from 'ofetch'; |
|||
const { t } = useI18n(); |
|||
|
|||
definePageMeta({ |
|||
layout: 'setup', |
|||
}); |
|||
|
|||
const setupStore = useSetupStore(); |
|||
setupStore.setStep(2); |
|||
const router = useRouter(); |
|||
const username = ref<null | string>(null); |
|||
const password = ref<null | string>(null); |
|||
const accept = ref<boolean>(true); |
|||
|
|||
const toast = useToast(); |
|||
|
|||
async function newAccount() { |
|||
try { |
|||
if (!username.value || !password.value) { |
|||
toast.showToast({ |
|||
type: 'error', |
|||
title: t('setup.requirements'), |
|||
message: t('setup.emptyFields'), |
|||
}); |
|||
return; |
|||
} |
|||
const username = ref<null | string>(null); |
|||
const password = ref<string>(''); |
|||
|
|||
await setupStore.step2(username.value, password.value, accept.value); |
|||
await router.push('/setup/3'); |
|||
} catch (error) { |
|||
if (error instanceof FetchError) { |
|||
toast.showToast({ |
|||
type: 'error', |
|||
title: t('setup.requirements'), |
|||
message: error.data.message, |
|||
}); |
|||
} |
|||
const _submit = useSubmit( |
|||
'/api/setup/2', |
|||
{ |
|||
method: 'post', |
|||
}, |
|||
{ |
|||
revert: async (success) => { |
|||
if (success) { |
|||
await navigateTo('/setup/3'); |
|||
} |
|||
}, |
|||
noSuccessToast: true, |
|||
} |
|||
); |
|||
|
|||
function submit() { |
|||
return _submit({ username: username.value, password: password.value }); |
|||
} |
|||
</script> |
|||
|
@ -1,71 +1,59 @@ |
|||
<template> |
|||
<div> |
|||
<p class="p-8 text-center text-lg"> |
|||
{{ $t('setup.messageSetupHostPort') }} |
|||
{{ $t('setup.setupConfigDesc') }} |
|||
</p> |
|||
<div> |
|||
<Label for="host">{{ $t('setup.host') }}</Label> |
|||
<input |
|||
id="host" |
|||
v-model="host" |
|||
type="text" |
|||
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" |
|||
/> |
|||
<div class="flex flex-col gap-3"> |
|||
<div class="flex flex-col"> |
|||
<FormNullTextField |
|||
id="host" |
|||
v-model="host" |
|||
type="text" |
|||
:label="$t('general.host')" |
|||
placeholder="vpn.example.com" |
|||
/> |
|||
</div> |
|||
<div class="flex flex-col"> |
|||
<FormNumberField |
|||
id="port" |
|||
v-model="port" |
|||
type="number" |
|||
:label="$t('general.port')" |
|||
/> |
|||
</div> |
|||
<div> |
|||
<BaseButton @click="submit">{{ $t('general.continue') }}</BaseButton> |
|||
</div> |
|||
</div> |
|||
<div> |
|||
<Label for="port">{{ $t('setup.port') }}</Label> |
|||
<input |
|||
id="port" |
|||
v-model="port" |
|||
type="number" |
|||
:min="1" |
|||
:max="65535" |
|||
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> |
|||
<BaseButton @click="updateHostPort">Continue</BaseButton> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { FetchError } from 'ofetch'; |
|||
|
|||
definePageMeta({ |
|||
layout: 'setup', |
|||
}); |
|||
|
|||
const { t } = useI18n(); |
|||
|
|||
const setupStore = useSetupStore(); |
|||
setupStore.setStep(4); |
|||
const router = useRouter(); |
|||
|
|||
const host = ref<null | string>(null); |
|||
const port = ref<number>(51820); |
|||
|
|||
const toast = useToast(); |
|||
|
|||
async function updateHostPort() { |
|||
if (!host.value || !port.value) { |
|||
toast.showToast({ |
|||
type: 'error', |
|||
title: t('setup.requirements'), |
|||
message: t('setup.emptyFields'), |
|||
}); |
|||
return; |
|||
const _submit = useSubmit( |
|||
'/api/setup/4', |
|||
{ |
|||
method: 'post', |
|||
}, |
|||
{ |
|||
revert: async (success) => { |
|||
if (success) { |
|||
await navigateTo('/setup/5'); |
|||
} |
|||
}, |
|||
} |
|||
); |
|||
|
|||
try { |
|||
await setupStore.step4(host.value, port.value); |
|||
await router.push('/setup/success'); |
|||
} catch (error) { |
|||
if (error instanceof FetchError) { |
|||
toast.showToast({ |
|||
type: 'error', |
|||
title: t('setup.requirements'), |
|||
message: error.data.message, |
|||
}); |
|||
} |
|||
} |
|||
function submit() { |
|||
return _submit({ host: host.value, port: port.value }); |
|||
} |
|||
</script> |
|||
|
Loading…
Reference in new issue