diff --git a/backend/src/index.js b/backend/src/index.js
index b9965de..c6447bc 100644
--- a/backend/src/index.js
+++ b/backend/src/index.js
@@ -52,6 +52,7 @@ checkAuth = passport.authenticate('jwt', { session: false });
app.use(checkAuth);
// ROUTES WITH AUTH
+app.use('/campaign', require('./routes/campaign'));
/*
app.use('/campaign', require('./routes/campaign'));
app.use('/maps', require('./routes/map'));
diff --git a/backend/src/models/Campaign.js b/backend/src/models/Campaign.js
new file mode 100644
index 0000000..7455ec4
--- /dev/null
+++ b/backend/src/models/Campaign.js
@@ -0,0 +1,17 @@
+const mongoose = require("mongoose");
+const Schema = mongoose.Schema;
+
+const CampaignSchema = new Schema({
+ name: {type: String, required: true},
+ description: {type: String},
+ color: {type: String},
+ createdBy: {
+ type: Schema.Types.ObjectId,
+ ref: 'User',
+ required: true
+ },
+ date: { type: Date, default: Date.now},
+ settings: { type: Object }
+});
+
+module.exports = mongoose.model('Campaign', CampaignSchema);
\ No newline at end of file
diff --git a/backend/src/routes/campaign.js b/backend/src/routes/campaign.js
new file mode 100644
index 0000000..99f1e07
--- /dev/null
+++ b/backend/src/routes/campaign.js
@@ -0,0 +1,32 @@
+const express = require('express')
+const router = express.Router();
+
+const Campaign = require("../models/Campaign");
+
+router.post('/create', async (req, res) => {
+ try {
+ const { name, description, color, settings } = req.body;
+ const newCampaign = new Campaign({
+ name,
+ description,
+ color,
+ settings,
+ createdBy: req.user.id
+ });
+ await newCampaign.save();
+ res.json({ status: "ok", campaign: newCampaign });
+ } catch (err) {
+ res.json({ status: "error", msg: "errors.internal" });
+ }
+});
+
+router.get('/list', async (req, res) => {
+ try {
+ const campaigns = await Campaign.find({ createdBy: req.user.id });
+ res.json({ status: "ok", campaigns });
+ } catch (err) {
+ res.json({ status: "error", msg: "errors.internal", err });
+ }
+});
+
+module.exports = router;
\ No newline at end of file
diff --git a/frontend/app/assets/css/main.scss b/frontend/app/assets/css/main.scss
index bb4a1fa..7087432 100644
--- a/frontend/app/assets/css/main.scss
+++ b/frontend/app/assets/css/main.scss
@@ -106,7 +106,8 @@ textarea {
background-color: var(--color-background-softer);
padding: 12px;
color: var(--color-text);
- border: none;
+ border-radius: 6px;
+ border: solid 1px var(--color-border);;
}
input[type=text]:focus, input[type=password]:focus, input[type=email]:focus {
diff --git a/frontend/app/components/partials/CampaignEntry.vue b/frontend/app/components/partials/CampaignEntry.vue
new file mode 100644
index 0000000..9dea9f7
--- /dev/null
+++ b/frontend/app/components/partials/CampaignEntry.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+

+
+ {{ title }}
Last session: {{ last_session }}
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/app/components/partials/ColorPicker.vue b/frontend/app/components/partials/ColorPicker.vue
new file mode 100644
index 0000000..477f8f2
--- /dev/null
+++ b/frontend/app/components/partials/ColorPicker.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/app/components/partials/VersionRender.vue b/frontend/app/components/partials/VersionRender.vue
index 76cb274..78dc911 100644
--- a/frontend/app/components/partials/VersionRender.vue
+++ b/frontend/app/components/partials/VersionRender.vue
@@ -17,6 +17,7 @@ const config = useRuntimeConfig()
bottom: 0;
left: 0;
user-select: none;
+ font-size: 14px;
}
span{
color: rgb(59, 59, 59);
diff --git a/frontend/app/components/windows/CreateCampaignWindow.vue b/frontend/app/components/windows/CreateCampaignWindow.vue
index 810b317..28c1b88 100644
--- a/frontend/app/components/windows/CreateCampaignWindow.vue
+++ b/frontend/app/components/windows/CreateCampaignWindow.vue
@@ -1,8 +1,11 @@
@@ -25,8 +44,28 @@ onMounted(() => {
@@ -36,7 +75,60 @@ onMounted(() => {
.window-wrapper {
display: flex;
align-items: center;
+ flex-direction: column;
}
+
+.body {
+ width: 100%;
+}
+
+.window-second-header {
+ width: 100%;
+ h2 {
+ font-family: MrEavesRemake;
+ }
+}
+
+form {
+ margin-top: 10px;
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+.form-field {
+ padding: 2px;
+ display: flex;
+ align-items: left;
+ flex-direction: row;
+ justify-content: space-between;
+ width: 100%;
+
+ > * {
+ flex-grow: 1;
+ }
+}
+
+label {
+ text-align: left;
+}
+
+textarea {
+ resize: none;
+ height: 200px;
+ font-size: 14px;
+}
+
+.form-actions {
+ display: flex;
+ justify-content: center; /* centers horizontally */
+ margin-top: 10px;
+}
+
+.form-actions button {
+ width: 100%; /* makes it expand */
+ max-width: 300px; /* optional: prevents it from being too wide */
+}
+
diff --git a/frontend/app/components/windows/MainMenuWindow.vue b/frontend/app/components/windows/MainMenuWindow.vue
index 411d141..802f094 100644
--- a/frontend/app/components/windows/MainMenuWindow.vue
+++ b/frontend/app/components/windows/MainMenuWindow.vue
@@ -5,6 +5,8 @@ import { SetupHandle, SetSize, ResetPosition, Top, CreateChildWindow, GetFirstWi
import WindowHandle from './partials/WindowHandle.vue';
import VersionRender from '../partials/VersionRender.vue';
import EditUserPartial from '../partials/EditUserPartial.vue';
+import CampaignEntry from '../partials/CampaignEntry.vue';
+import Server from '~/services/Server';
const handle = ref(null);
const wrapper = ref(null);
@@ -12,10 +14,20 @@ const wrapper = ref(null);
const props = defineProps(['data']);
const data = props.data;
+const campaings = ref([]);
+
let id = data.id;
function CreateCampaignWindow(){
- CreateChildWindow(GetFirstWindowId('main_menu'), 'create_campaign', {
+ CreateChildWindow(GetFirstWindowId('main_menu'), 'create_campaign');
+}
+
+function RefreshCampaigns(){
+ Server().get('/campaign/list').then((response) => {
+ console.log(response.data);
+ response.data.forEach((camp) => {
+ campaings.value.push(camp.campaign);
+ });
});
}
@@ -24,6 +36,8 @@ onMounted(() => {
SetupHandle(id, handle);
SetSize(id, {width: 580, height: 760});
ResetPosition(id, "center");
+
+ RefreshCampaigns();
});
@@ -37,13 +51,17 @@ onMounted(() => {
{{ $t("main-menu.main-menu")}}
+
+
+
+
+
-
diff --git a/frontend/i18n/locales/en.json b/frontend/i18n/locales/en.json
index d73dcb8..eaa964e 100644
--- a/frontend/i18n/locales/en.json
+++ b/frontend/i18n/locales/en.json
@@ -8,6 +8,22 @@
"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...",