A lot of progress
All checks were successful
Build and Deploy Nuxt / build (push) Successful in 36s

This commit is contained in:
2026-04-28 00:20:15 +02:00
parent b928212608
commit 76bb9fbb30
38 changed files with 382 additions and 460 deletions

View File

@@ -16,6 +16,7 @@ router.post('/create', async (req, res) => {
await newCampaign.save(); await newCampaign.save();
res.json({ status: "ok", campaign: newCampaign }); res.json({ status: "ok", campaign: newCampaign });
} catch (err) { } catch (err) {
console.error(err);
res.json({ status: "error", msg: "errors.internal" }); res.json({ status: "error", msg: "errors.internal" });
} }
}); });

View File

@@ -1,75 +0,0 @@
# Nuxt Minimal Starter
Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
## Setup
Make sure to install dependencies:
```bash
# npm
npm install
# pnpm
pnpm install
# yarn
yarn install
# bun
bun install
```
## Development Server
Start the development server on `http://localhost:3000`:
```bash
# npm
npm run dev
# pnpm
pnpm dev
# yarn
yarn dev
# bun
bun run dev
```
## Production
Build the application for production:
```bash
# npm
npm run build
# pnpm
pnpm build
# yarn
yarn build
# bun
bun run build
```
Locally preview production build:
```bash
# npm
npm run preview
# pnpm
pnpm preview
# yarn
yarn preview
# bun
bun run preview
```
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.

View File

@@ -6,6 +6,7 @@ $themes: (
background-light: #202020, background-light: #202020,
background-line: #202324, background-line: #202324,
background-fore: #10141f, background-fore: #10141f,
background-soft: #20202077,
window-handle-background: #191919, window-handle-background: #191919,
window-background: #141414, window-background: #141414,

View File

@@ -4,17 +4,16 @@ import { AddContextMenu, HideContextMenu } from '@/services/ContextMenu';
const props = defineProps(['options', 'onselect', 'selected', 'keyFunc']); const props = defineProps(['options', 'onselect', 'selected', 'keyFunc']);
const options = props.options; const options = props.options;
const selectCallback = props.onselect; const selectCallback = props.onselect;
const initialSelect = props.selected; const initialSelect = props.selected;
const dropdown = ref(null); const dropdown = ref(null);
const selected = ref(null);
const selected = ref(initialSelect);
onMounted(() => { onMounted(() => {
if(props.keyFunc == undefined) props.keyFunc = (option) => option; if(props.keyFunc == undefined) props.keyFunc = (option) => option;
else selected.value = props.keyFunc(initialSelect); selected.value = props.keyFunc(initialSelect);
let context = []; let context = [];
if(props.selected == undefined) selected.value = "undefined";
watch(() => props.selected, () => { watch(() => props.selected, () => {
selected.value = props.keyFunc(props.selected); selected.value = props.keyFunc(props.selected);
}); });

View File

@@ -8,14 +8,15 @@ const props = defineProps(['data']);
const data = props.data; const data = props.data;
const title = ref(""); const title = ref("");
const last_session = ref("");
const container = ref(null); const container = ref(null);
onMounted(() => { onMounted(() => {
title.value = data.name; title.value = data.name;
last_session.value = new Date(data.last_opened).toISOString().slice(0, 10); if (data.color && container.value) {
container.value.style.background = `linear-gradient(90deg, ${data.color}, ${data.color}44)`;
}
AddSound(container.value) AddSound(container.value)
}); });
@@ -31,11 +32,11 @@ function ViewCampaign(){
<div class="main-campaign-entry-container-inner"> <div class="main-campaign-entry-container-inner">
<img class="campaign-icon" src="/img/def-avatar.jpg" draggable="false"> <img class="campaign-icon" src="/img/def-avatar.jpg" draggable="false">
<div class="campaign-info"> <div class="campaign-info">
<b>{{ title }}</b><br>Last session: <span>{{ last_session }}</span> <b>{{ title }}</b>
</div> </div>
<div class="campaign-user-actions"> <div class="campaign-user-actions">
<button class="btn-primary button-small sound-click" v-on:click.prevent="ViewCampaign">{{ $t('general.view')}}</button> <button class="btn-primary button-small sound-click" v-on:click.prevent="ViewCampaign">{{ $t('general.open')}}</button>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -21,7 +21,7 @@ onMounted(() => {
}); });
}); });
let GetColor = () => color; let GetColor = () => color.value;
defineExpose({ GetColor }); defineExpose({ GetColor });
</script> </script>

View File

@@ -48,12 +48,6 @@ function LogOut(){
CreateWindow('login'); CreateWindow('login');
} }
function EditProfile(){
CreateChildWindow(GetFirstWindowId('main_menu'), 'edit_profile', {
user: GetUser()
});
}
function EditSettings(){ function EditSettings(){
CreateChildWindow(GetFirstWindowId('main_menu'), 'settings', { CreateChildWindow(GetFirstWindowId('main_menu'), 'settings', {
user: GetUser() user: GetUser()
@@ -102,7 +96,6 @@ onMounted(() => {
</div> </div>
<div class="main-user-actions"> <div class="main-user-actions">
<button class="btn-primary button-small sound-click" v-on:click.prevent="EditProfile">{{ $t("main-menu.edit-profile") }}</button>
<button class="btn-primary button-small sound-click" v-on:click.prevent="EditSettings">{{ $t("main-menu.settings") }}</button> <button class="btn-primary button-small sound-click" v-on:click.prevent="EditSettings">{{ $t("main-menu.settings") }}</button>
<button class="btn-primary button-small sound-click" v-on:click.prevent="LogOut">{{ $t("main-menu.log-out") }}</button> <button class="btn-primary button-small sound-click" v-on:click.prevent="LogOut">{{ $t("main-menu.log-out") }}</button>
</div> </div>

View File

@@ -27,6 +27,8 @@ const campaignDescription = ref("");
const colorPicker = ref(null); const colorPicker = ref(null);
function NewCampaign(){ function NewCampaign(){
const color = colorPicker.value.GetColor();
console.log(color);
Server().post('/campaign/create', { Server().post('/campaign/create', {
name: campaignName.value, name: campaignName.value,
description: campaignDescription.value, description: campaignDescription.value,

View File

@@ -1,91 +0,0 @@
<script setup>
import { onMounted, ref } from 'vue';
import { SetupHandle, SetSize, ResetPosition, Top } from '@/services/Windows';
import Server from '@/services/Server'
import { SetMinSize, SetResizable } from '@/services/Windows';
import { backendUrl } from '@/services/BackendURL';
import { GetUser } from '@/services/User';
import WindowHandle from './partials/WindowHandle.vue';
import BigIconTemplate from './partials/BigIconTemplate.vue';
import FixedBottomButtons from './partials/FixedBottomButtons.vue';
const props = defineProps(['data']);
const data = props.data;
const userIcon = ref("");
const handle = ref(null);
const wrapper = ref(null);
const isAdmin = ref(false);
let id = data.id;
console.log(data);
onMounted(() => {
Top(wrapper);
SetupHandle(id, handle);
SetSize(id, {width: 500, height: 480});
ResetPosition(id, "center");
SetResizable(id, true);
SetMinSize(id, {width: 350, height: 280});
isAdmin.value = GetUser().admin;
Server().get('/user/retrieve-avatar?username=' + data.user.username).then((response) => {
if(response.data.image) userIcon.value = backendUrl + "public/" + response.data.image;
else userIcon.value = "public/img/def-avatar.jpg";
}).catch((err) => console.log("Internal error"));
});
function RemoveUser(){
alert("Remove")
}
</script>
<template>
<div class="window-wrapper" :id="'window-wrapper-' + id" ref="wrapper">
<WindowHandle :window="id" ref="handle"></WindowHandle>
<BigIconTemplate :title="data.user.username" :img="userIcon">
<div v-if="props.data.editable || isAdmin">
</div>
<div v-else>
</div>
</BigIconTemplate>
<FixedBottomButtons v-if="isAdmin" :remove="RemoveUser"></FixedBottomButtons>
</div>
</template>
<style scoped>
.window-wrapper {
display: flex;
align-items: center;
}
.splash-image {
width: 600px;
height: 250px;
}
.form-field {
padding: 10px;
display: flex;
align-items: left;
flex-direction: column;
justify-content: left;
width: 600px;
}
label {
text-align: left;
}
</style>

View File

@@ -24,9 +24,9 @@ function CreateCampaignWindow(){
function RefreshCampaigns(){ function RefreshCampaigns(){
Server().get('/campaign/list').then((response) => { Server().get('/campaign/list').then((response) => {
console.log(response.data); if(response.data.status !== "ok") return;
response.data.forEach((camp) => { response.data.campaigns.forEach((camp) => {
campaings.value.push(camp.campaign); campaings.value.push(camp);
}); });
}); });
} }
@@ -34,7 +34,7 @@ function RefreshCampaigns(){
onMounted(() => { onMounted(() => {
Top(wrapper); Top(wrapper);
SetupHandle(id, handle); SetupHandle(id, handle);
SetSize(id, {width: 580, height: 760}); SetSize(id, {width: 880, height: 760});
ResetPosition(id, "center"); ResetPosition(id, "center");
RefreshCampaigns(); RefreshCampaigns();
@@ -46,21 +46,38 @@ onMounted(() => {
<div class="window-wrapper" :id="'window-wrapper-' + id" ref="wrapper"> <div class="window-wrapper" :id="'window-wrapper-' + id" ref="wrapper">
<WindowHandle :window="id" ref="handle"></WindowHandle> <WindowHandle :window="id" ref="handle"></WindowHandle>
<EditUserPartial></EditUserPartial> <div class="two-column">
<!-- Body --> <div class="vert-expand secondary">
<div class="vert-expand"> <div class="image-container">
<div class="vert top"> <img alt="Dragonroll logo" src="/img/logo-splash.png" draggable="false" width="100%">
<h1>{{ $t("main-menu.main-menu")}}</h1>
<!-- HERE -->
<div class="campaign-list">
<CampaignEntry v-for="camp in myCampaigns" :key="camp._id" :data="camp"></CampaignEntry>
</div> </div>
<div class="patch-notes-container">
<h1>Welcome to dragonroll!</h1>
<h2>Version 0.1</h2>
<p>This is totally under construction. This is a review of how the patch notes will be displayed.</p>
<p>There is also a lot of heavy development here.</p>
</div>
<VersionRender></VersionRender>
</div> </div>
<div class="vert bot"> <div class="vert-expand" style="max-width: 450px;">
<div class="button-container"> <EditUserPartial></EditUserPartial>
<button class="btn-primary button-expand sound-click" v-on:click="CreateCampaignWindow" ref="campaignButton">{{ $t("main-menu.create-campaign") }}</button> <!-- Body -->
<div class="vert-expand">
<div class="vert top">
<h1>{{ $t("main-menu.main-menu")}}</h1>
<!-- HERE -->
<div class="campaign-list">
<CampaignEntry v-for="camp in campaings" :key="camp._id" :data="camp"></CampaignEntry>
</div>
</div>
<div class="vert bot">
<div class="button-container">
<button class="btn-primary button-expand sound-click" v-on:click="CreateCampaignWindow" ref="campaignButton">{{ $t("main-menu.create-campaign") }}</button>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -72,6 +89,29 @@ onMounted(() => {
h1 { h1 {
margin-top: 20px; margin-top: 20px;
font-family: MrEavesRemake; font-family: MrEavesRemake;
text-align: center;
}
h2, h3 {
font-family: MrEavesRemake;
}
.patch-notes-container {
margin: 10px;
padding: 10px;
border-radius: 5px;
flex-grow: 1;
}
.two-column {
display: flex;
flex-direction: row;
width: 100%;
height: 100%;
}
.secondary {
background-color: var(--color-background-soft);
} }
.expand { .expand {
@@ -89,7 +129,8 @@ h1 {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
height: 100%; flex-grow: 1;
width: 100%;
} }
@@ -99,8 +140,7 @@ h1 {
.button-container { .button-container {
display: flex; display: flex;
width: 100%; margin: 20px;
padding: 20px;
flex-direction: column; flex-direction: column;
} }

View File

@@ -6,6 +6,7 @@ import Tabs from '../layouts/Tabs.vue';
import Dropdown from '../layouts/Dropdown.vue'; import Dropdown from '../layouts/Dropdown.vue';
import { GetUser, GetUserSetting, SetUserSetting } from '@/services/User'; import { GetUser, GetUserSetting, SetUserSetting } from '@/services/User';
import { SetupHandle, SetSize, ResetPosition, Top, ClearWindow, CreateWindow, SetMinSize, SetResizable } from '@/services/Windows'; import { SetupHandle, SetSize, ResetPosition, Top, ClearWindow, CreateWindow, SetMinSize, SetResizable } from '@/services/Windows';
import { locales } from '~~/i18n/locales';
const handle = ref(null); const handle = ref(null);
const wrapper = ref(null); const wrapper = ref(null);
@@ -13,11 +14,12 @@ const wrapper = ref(null);
const props = defineProps(['data']); const props = defineProps(['data']);
const data = props.data; const data = props.data;
const { locales, setLocale, locale } = useI18n(); const { locale } = useI18n();
const changeLocale = (lang) => { const changeLocale = (lang) => {
console.log(lang); console.log(lang);
setLocale(lang.code); locale.value = lang.code;
SetUserSetting('lang', lang.code); SetUserSetting('lang', lang.code);
} }
@@ -28,12 +30,18 @@ const rows = ref([{id: "account-settings", value: "settings.tabs.account-setting
/* TODO /* TODO
const languageOptions = ref(["English", "Spanish", "Catalan"]) const languageOptions = ref(["English", "Spanish", "Catalan"])
const langSelector = ref(null); const langSelector = ref(null);
const currentLanguage = ref("");
*/ */
function getLocaleFromCode(code){
for(let i = 0; i < locales.length; i++){
if(locales[i].code == code) return locales[i];
}
}
const selectedLocale = ref("");
onBeforeMount(() => { onBeforeMount(() => {
GetUserSetting('lang').then(value => { GetUserSetting('lang').then(value => {
currentLanguage.value = codes[value ?? 'en'] locale.value = value;
console.log(currentLanguage.value) selectedLocale.value = getLocaleFromCode(value); // Set selected in dropdown
}); });
if(GetUser().admin) rows.value.push({ if(GetUser().admin) rows.value.push({
id: "site-administration", id: "site-administration",
@@ -44,11 +52,11 @@ onBeforeMount(() => {
onMounted(() => { onMounted(() => {
Top(wrapper); Top(wrapper);
SetupHandle(id, handle); SetupHandle(id, handle);
SetSize(id, {width: 400, height: 480}); SetSize(id, {width: 600, height: 480});
ResetPosition(id, "center"); ResetPosition(id, "center");
SetResizable(id, true); SetResizable(id, true);
SetMinSize(id, {width: 350, height: 280}); SetMinSize(id, {width: 450, height: 280});
}); });
function OpenManageAccounts(){ function OpenManageAccounts(){
@@ -86,7 +94,7 @@ const getLocaleName = (locale) => {
<div class="form-container"> <div class="form-container">
<div class="form-element"> <div class="form-element">
<label>{{ $t('settings.account-settings.language') }}</label> <label>{{ $t('settings.account-settings.language') }}</label>
<Dropdown :options="locales" :keyFunc="getLocaleName" :onselect="changeLocale" :selected="locale"></Dropdown> <Dropdown :options="locales" :keyFunc="getLocaleName" :onselect="changeLocale" :selected="selectedLocale"></Dropdown>
</div> </div>
</div> </div>
</template> </template>

View File

@@ -126,6 +126,11 @@ defineExpose({
justify-content: right; justify-content: right;
} }
.center {
display: flex;
align-items: center;
}
span { span {
font-family: MrEavesRemake; font-family: MrEavesRemake;
} }

View File

@@ -0,0 +1,33 @@
import { createI18n } from 'vue-i18n'
function loadLocaleMessages() {
const locales = import.meta.glob('../../i18n/locales/**/*.json', { eager: true })
const messages: Record<string, any> = {}
for (const path in locales) {
console.log(path);
const matched = path.match(/i18n\/locales\/(\w+)\/(.*)\.json$/)
if (!matched) continue
const [, locale, file] = matched
if (!messages[locale]) {
messages[locale] = {}
}
messages[locale][file] = (locales[path] as any).default
}
console.log(messages);
return messages
}
export default defineNuxtPlugin((nuxtApp) => {
const i18n = createI18n({
legacy: false,
locale: 'en',
messages: loadLocaleMessages()
})
nuxtApp.vueApp.use(i18n)
})

View File

@@ -23,12 +23,6 @@ const defWindows = {
component: () => import('~/components/windows/MainMenuWindow.vue'), component: () => import('~/components/windows/MainMenuWindow.vue'),
movable: true movable: true
}, },
edit_profile: {
title: "windows.edit-profile",
component: () => import('~/components/windows/EditProfileWindow.vue'),
close: () => ClearWindow({type: 'edit_profile'}),
movable: true
},
settings: { settings: {
title: "windows.settings", title: "windows.settings",
component: () => import('~/components/windows/SettingsWindow.vue'), component: () => import('~/components/windows/SettingsWindow.vue'),

View File

@@ -224,7 +224,6 @@ function CreateChildWindow(parentId, type, data = {}) {
if (parent.children) parent.children.push(newId); // We will create the child window right now if (parent.children) parent.children.push(newId); // We will create the child window right now
else parent.children = [newId]; else parent.children = [newId];
CreateWindow(type, data); CreateWindow(type, data);
console.log(windows.value);
} }
function GetFirstWindowId(type) { function GetFirstWindowId(type) {

17
frontend/i18n/locales.ts Normal file
View File

@@ -0,0 +1,17 @@
export const locales = [
{
code: 'en',
name: 'English',
flag: '🇬🇧'
},
{
code: 'es',
name: 'Español',
flag: '🇪🇸'
},
{
code: 'ca',
name: 'Català',
flag: '<27>🇸'
}
]

View File

@@ -1,75 +1 @@
{ {}
"windows": {
"login": "Inicia sessió",
"register": "Registra't",
"main-menu": "Dragonroll",
"example": "Finestra d'exemple",
"edit-profile": "Editar perfil",
"settings": "Configuració",
"create-campaign": "Crear campanya"
},
"login": {
"username": "Usuari o correu electrònic",
"username-placeholder": "Introdueix el teu usuari o correu electrònic...",
"password": "Contrasenya",
"password-placeholder": "Introdueix la teva contrasenya...",
"log-in": "Inicia sessió",
"no-account": "No tens un compte?",
"register": "Registra't",
"errors": {
"invalid-credentials": "Usuari/correu o contrasenya incorrectes.",
"params": "Si us plau, introdueix usuari/correu i contrasenya."
},
"success": "Inici de sessió correcte!"
},
"register": {
"name": "Nom",
"name-placeholder": "Introdueix el teu nom...",
"email": "Correu electrònic",
"email-placeholder": "Introdueix el teu correu electrònic...",
"username": "Usuari",
"username-placeholder": "Introdueix el teu nom d'usuari...",
"password": "Contrasenya",
"password-placeholder": "Introdueix la teva contrasenya...",
"confirm-password": "Confirma la contrasenya",
"confirm-password-placeholder": "Torna a introduir la contrasenya...",
"register": "Registra't",
"have-account": "Ja tens un compte?",
"login": "Inicia sessió",
"password-confirm-placeholder": "Confirma la teva contrasenya...",
"welcome": "Benvingut a DragonRoll!",
"message": "Si us plau, introdueix el nom d'usuari i la contrasenya que desitges per crear un compte.",
"first-register-message": "Estàs a punt de crear el primer compte en aquesta instància de DragonRoll. Aquest compte tindrà privilegis d'administrador.",
"errors": {
"name-empty": "Si us plau, introdueix el teu nom.",
"email-empty": "Si us plau, introdueix un correu electrònic vàlid.",
"username-empty": "Si us plau, introdueix un nom d'usuari.",
"passwords-no-match": "Les contrasenyes no coincideixen.",
"email-username-exists": "Ja existeix un compte amb aquest correu electrònic o nom d'usuari."
},
"success": "Registre correcte! Ara pots iniciar sessió."
},
"errors": {
"internal": "S'ha produït un error intern."
},
"main-menu": {
"main-menu": "Menú principal",
"edit-profile": "Editar perfil",
"create-campaign": "Crear campanya",
"log-out": "Tanca la sessió",
"settings": "Configuració"
},
"settings": {
"tabs": {
"account-settings": "Configuració del compte",
"site-administration": "Administració del lloc"
},
"account-settings": {
"appearance": "Aparença",
"language": "Idioma"
},
"site-administration": {
"manage-accounts": "Gestiona els comptes"
}
}
}

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1,14 @@
{
"username": "Usuari o correu electrònic",
"username-placeholder": "Introdueix el teu usuari o correu electrònic...",
"password": "Contrasenya",
"password-placeholder": "Introdueix la teva contrasenya...",
"log-in": "Inicia sessió",
"no-account": "No tens un compte?",
"register": "Registra't",
"errors": {
"invalid-credentials": "Usuari/correu o contrasenya incorrectes.",
"params": "Si us plau, introdueix usuari/correu i contrasenya."
},
"success": "Inici de sessió correcte!"
}

View File

@@ -0,0 +1,7 @@
{
"main-menu": "Menú principal",
"edit-profile": "Editar perfil",
"create-campaign": "Crear campanya",
"log-out": "Tanca la sessió",
"settings": "Configuració"
}

View File

@@ -0,0 +1,27 @@
{
"name": "Nom",
"name-placeholder": "Introdueix el teu nom...",
"email": "Correu electrònic",
"email-placeholder": "Introdueix el teu correu electrònic...",
"username": "Usuari",
"username-placeholder": "Introdueix el teu nom d'usuari...",
"password": "Contrasenya",
"password-placeholder": "Introdueix la teva contrasenya...",
"confirm-password": "Confirma la contrasenya",
"confirm-password-placeholder": "Torna a introduir la contrasenya...",
"register": "Registra't",
"have-account": "Ja tens un compte?",
"login": "Inicia sessió",
"password-confirm-placeholder": "Confirma la teva contrasenya...",
"welcome": "Benvingut a DragonRoll!",
"message": "Si us plau, introdueix el nom d'usuari i la contrasenya que desitges per crear un compte.",
"first-register-message": "Estàs a punt de crear el primer compte en aquesta instància de DragonRoll. Aquest compte tindrà privilegis d'administrador.",
"errors": {
"name-empty": "Si us plau, introdueix el teu nom.",
"email-empty": "Si us plau, introdueix un correu electrònic vàlid.",
"username-empty": "Si us plau, introdueix un nom d'usuari.",
"passwords-no-match": "Les contrasenyes no coincideixen.",
"email-username-exists": "Ja existeix un compte amb aquest correu electrònic o nom d'usuari."
},
"success": "Registre correcte! Ara pots iniciar sessió."
}

View File

@@ -0,0 +1,13 @@
{
"tabs": {
"account-settings": "Configuració del compte",
"site-administration": "Administració del lloc"
},
"account-settings": {
"appearance": "Aparença",
"language": "Idioma"
},
"site-administration": {
"manage-accounts": "Gestiona els comptes"
}
}

View File

@@ -0,0 +1,9 @@
{
"login": "Inicia sessió",
"register": "Registra't",
"main-menu": "Dragonroll",
"example": "Finestra d'exemple",
"edit-profile": "Editar perfil",
"settings": "Configuració",
"create-campaign": "Crear campanya"
}

View File

@@ -1,91 +1 @@
{ {}
"windows": {
"login": "Login",
"register": "Register",
"main-menu": "Dragonroll",
"example": "Example Window",
"edit-profile": "Edit Profile",
"settings": "Settings",
"create-campaign": "Create Campaign"
},
"general": {
"create": "Create",
"save": "Save",
"cancel": "Cancel",
"delete": "Delete"
},
"campaigns": {
"create": {
"name": "Name",
"description": "Description",
"description-placeholder": "Enter a brief description for your campaign...",
"enter": "Enter campaign name here...",
"color": "Accent color",
"success": "Campaign created successfully!"
}
},
"login": {
"username": "Username or email",
"username-placeholder": "Enter your username or email here...",
"password": "Password",
"password-placeholder": "Enter your password...",
"log-in": "Log in",
"no-account": "You don't have an account?",
"register": "Register",
"errors": {
"invalid-credentials": "Invalid username/email or password.",
"params": "Please enter both username/email and password."
},
"success": "Login successful!"
},
"register": {
"name": "Name",
"name-placeholder": "Enter your name here...",
"email": "Email",
"email-placeholder": "Enter your email here...",
"username": "Username",
"username-placeholder": "Enter your username here...",
"password": "Password",
"password-placeholder": "Enter your password...",
"confirm-password": "Confirm Password",
"confirm-password-placeholder": "Re-enter your password...",
"register": "Register",
"have-account": "Already have an account?",
"login": "Login",
"password-confirm-placeholder": "Confirm your password...",
"welcome": "Welcome to DragonRoll!",
"message": "Please enter your desired username and password to create an account.",
"first-register-message": "You are about to create the first account on this DragonRoll instance. This account will be granted administrator privileges.",
"errors": {
"name-empty": "Please enter your name.",
"email-empty": "Please enter a valid email address.",
"username-empty": "Please enter a username.",
"passwords-no-match": "The passwords you entered do not match.",
"email-username-exists": "An account with this email or username already exists."
},
"success": "Registration successful! You can now log in."
},
"errors": {
"internal": "An internal error occurred."
},
"main-menu": {
"main-menu": "Main menu",
"edit-profile": "Edit profile",
"create-campaign": "Create Campaign",
"log-out": "Log out",
"settings": "Settings"
},
"settings": {
"tabs": {
"account-settings": "Account settings",
"site-administration": "Site administration"
},
"account-settings": {
"appearance": "Appearance",
"language": "Language"
},
"site-administration": {
"manage-accounts": "Manage accounts"
}
}
}

View File

@@ -0,0 +1,10 @@
{
"create": {
"name": "Name",
"description": "Description",
"description-placeholder": "Enter a brief description for your campaign...",
"enter": "Enter campaign name here...",
"color": "Accent color",
"success": "Campaign created successfully!"
}
}

View File

@@ -0,0 +1,10 @@
{
"errors": {
"internal": "An internal error occurred."
},
"create": "Create",
"save": "Save",
"cancel": "Cancel",
"delete": "Delete",
"open": "Open"
}

View File

@@ -0,0 +1,15 @@
{
"username": "Username or email",
"username-placeholder": "Enter your username or email here...",
"password": "Password",
"password-placeholder": "Enter your password...",
"log-in": "Log in",
"no-account": "You don't have an account?",
"register": "Register",
"errors": {
"invalid-credentials": "Invalid username/email or password.",
"params": "Please enter both username/email and password."
},
"success": "Login successful!"
}

View File

@@ -0,0 +1,7 @@
{
"main-menu": "Main menu",
"edit-profile": "Edit profile",
"create-campaign": "Create Campaign",
"log-out": "Log out",
"settings": "Settings"
}

View File

@@ -0,0 +1,27 @@
{
"name": "Name",
"name-placeholder": "Enter your name here...",
"email": "Email",
"email-placeholder": "Enter your email here...",
"username": "Username",
"username-placeholder": "Enter your username here...",
"password": "Password",
"password-placeholder": "Enter your password...",
"confirm-password": "Confirm Password",
"confirm-password-placeholder": "Re-enter your password...",
"register": "Register",
"have-account": "Already have an account?",
"login": "Login",
"password-confirm-placeholder": "Confirm your password...",
"welcome": "Welcome to DragonRoll!",
"message": "Please enter your desired username and password to create an account.",
"first-register-message": "You are about to create the first account on this DragonRoll instance. This account will be granted administrator privileges.",
"errors": {
"name-empty": "Please enter your name.",
"email-empty": "Please enter a valid email address.",
"username-empty": "Please enter a username.",
"passwords-no-match": "The passwords you entered do not match.",
"email-username-exists": "An account with this email or username already exists."
},
"success": "Registration successful! You can now log in."
}

View File

@@ -0,0 +1,13 @@
{
"tabs": {
"account-settings": "Account settings",
"site-administration": "Site administration"
},
"account-settings": {
"appearance": "Appearance",
"language": "Language"
},
"site-administration": {
"manage-accounts": "Manage accounts"
}
}

View File

@@ -0,0 +1,9 @@
{
"login": "Login",
"register": "Register",
"main-menu": "Dragonroll",
"example": "Example Window",
"edit-profile": "Edit Profile",
"settings": "Settings",
"create-campaign": "Create Campaign"
}

View File

@@ -1,75 +1 @@
{ {}
"windows": {
"login": "Iniciar sesión",
"register": "Registrarse",
"main-menu": "Dragonroll",
"example": "Ventana de ejemplo",
"edit-profile": "Editar perfil",
"settings": "Configuración",
"create-campaign": "Crear campanya"
},
"login": {
"username": "Usuario o correo electrónico",
"username-placeholder": "Introduce tu usuario o correo electrónico...",
"password": "Contraseña",
"password-placeholder": "Introduce tu contraseña...",
"log-in": "Iniciar sesión",
"no-account": "¿No tienes una cuenta?",
"register": "Registrarse",
"errors": {
"invalid-credentials": "Usuario/correo o contraseña incorrectos.",
"params": "Por favor, introduce usuario/correo y contraseña."
},
"success": "¡Inicio de sesión exitoso!"
},
"register": {
"name": "Nombre",
"name-placeholder": "Introduce tu nombre...",
"email": "Correo electrónico",
"email-placeholder": "Introduce tu correo electrónico...",
"username": "Usuario",
"username-placeholder": "Introduce tu nombre de usuario...",
"password": "Contraseña",
"password-placeholder": "Introduce tu contraseña...",
"confirm-password": "Confirmar contraseña",
"confirm-password-placeholder": "Vuelve a introducir tu contraseña...",
"register": "Registrarse",
"have-account": "¿Ya tienes una cuenta?",
"login": "Iniciar sesión",
"password-confirm-placeholder": "Confirma tu contraseña...",
"welcome": "¡Bienvenido a DragonRoll!",
"message": "Por favor, introduce el usuario y la contraseña que deseas para crear una cuenta.",
"first-register-message": "Estás a punto de crear la primera cuenta en esta instancia de DragonRoll. Esta cuenta tendrá privilegios de administrador.",
"errors": {
"name-empty": "Por favor, introduce tu nombre.",
"email-empty": "Por favor, introduce un correo electrónico válido.",
"username-empty": "Por favor, introduce un nombre de usuario.",
"passwords-no-match": "Las contraseñas no coinciden.",
"email-username-exists": "Ya existe una cuenta con este correo electrónico o nombre de usuario."
},
"success": "¡Registro exitoso! Ahora puedes iniciar sesión."
},
"errors": {
"internal": "Ha ocurrido un error interno."
},
"main-menu": {
"main-menu": "Menú principal",
"edit-profile": "Editar perfil",
"create-campaign": "Crear campanya",
"log-out": "Cerrar sesión",
"settings": "Configuración"
},
"settings": {
"tabs": {
"account-settings": "Configuración de la cuenta",
"site-administration": "Administración del sitio"
},
"account-settings": {
"appearance": "Apariencia",
"language": "Idioma"
},
"site-administration": {
"manage-accounts": "Gestionar cuentas"
}
}
}

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1,14 @@
{
"username": "Usuario o correo electrónico",
"username-placeholder": "Introduce tu usuario o correo electrónico...",
"password": "Contraseña",
"password-placeholder": "Introduce tu contraseña...",
"log-in": "Iniciar sesión",
"no-account": "¿No tienes una cuenta?",
"register": "Registrarse",
"errors": {
"invalid-credentials": "Usuario/correo o contraseña incorrectos.",
"params": "Por favor, introduce usuario/correo y contraseña."
},
"success": "¡Inicio de sesión exitoso!"
}

View File

@@ -0,0 +1,7 @@
{
"main-menu": "Menú principal",
"edit-profile": "Editar perfil",
"create-campaign": "Crear campanya",
"log-out": "Cerrar sesión",
"settings": "Configuración"
}

View File

@@ -0,0 +1,27 @@
{
"name": "Nombre",
"name-placeholder": "Introduce tu nombre...",
"email": "Correo electrónico",
"email-placeholder": "Introduce tu correo electrónico...",
"username": "Usuario",
"username-placeholder": "Introduce tu nombre de usuario...",
"password": "Contraseña",
"password-placeholder": "Introduce tu contraseña...",
"confirm-password": "Confirmar contraseña",
"confirm-password-placeholder": "Vuelve a introducir tu contraseña...",
"register": "Registrarse",
"have-account": "¿Ya tienes una cuenta?",
"login": "Iniciar sesión",
"password-confirm-placeholder": "Confirma tu contraseña...",
"welcome": "¡Bienvenido a DragonRoll!",
"message": "Por favor, introduce el usuario y la contraseña que deseas para crear una cuenta.",
"first-register-message": "Estás a punto de crear la primera cuenta en esta instancia de DragonRoll. Esta cuenta tendrá privilegios de administrador.",
"errors": {
"name-empty": "Por favor, introduce tu nombre.",
"email-empty": "Por favor, introduce un correo electrónico válido.",
"username-empty": "Por favor, introduce un nombre de usuario.",
"passwords-no-match": "Las contraseñas no coinciden.",
"email-username-exists": "Ya existe una cuenta con este correo electrónico o nombre de usuario."
},
"success": "¡Registro exitoso! Ahora puedes iniciar sesión."
}

View File

@@ -0,0 +1,13 @@
{
"tabs": {
"account-settings": "Configuración de la cuenta",
"site-administration": "Administración del sitio"
},
"account-settings": {
"appearance": "Apariencia",
"language": "Idioma"
},
"site-administration": {
"manage-accounts": "Gestionar cuentas"
}
}

View File

@@ -0,0 +1,9 @@
{
"login": "Iniciar sesión",
"register": "Registrarse",
"main-menu": "Dragonroll",
"example": "Ventana de ejemplo",
"edit-profile": "Editar perfil",
"settings": "Configuración",
"create-campaign": "Crear campanya"
}