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 @@ + + + + + + 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...",