Skip to content

Commit

Permalink
clan create, update and delete + flash changes (#522)
Browse files Browse the repository at this point in the history
  • Loading branch information
fcaps authored Dec 5, 2023
1 parent bf4f505 commit 4e1b874
Show file tree
Hide file tree
Showing 22 changed files with 496 additions and 701 deletions.
11 changes: 11 additions & 0 deletions public/styles/site/clans.sass
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,14 @@
tbody
td
text-align: left

.clanManagement textarea
margin: 1em 1em 2px 1em
background-color: #3f3f3f
color: #ffffff
font-size: var(--paragraph-font-size)
border: 0.5em solid #262626
border-radius: 10px
z-index: 2
position: relative

14 changes: 12 additions & 2 deletions src/backend/AppKernel.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,18 @@ class AppKernel {
})

this.expressApp.use(flash())
this.expressApp.use((req, res, next) => {
res.locals.message = req.flash()
this.expressApp.use(function (req, res, next) {
req.asyncFlash = async function () {
const result = req.flash(...arguments)
await new Promise(resolve => req.session.save(resolve))

return result
}

return next()
})
this.expressApp.use(async (req, res, next) => {
res.locals.connectFlash = () => req.flash()
next()
})

Expand Down
19 changes: 19 additions & 0 deletions src/backend/dependency-injection/RequestContainer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const { ContainerBuilder, Reference } = require('node-dependency-injection')
const { UserRepository } = require('../services/UserRepository')
const { UserService } = require('../services/UserService')
const { ClanManagementService } = require('../services/ClanManagementService')
const { ClanManagementRepository } = require('../services/ClanManagementRepository')

module.exports.RequestContainer = (appContainer, request) => {
const container = new ContainerBuilder()
Expand All @@ -11,9 +13,26 @@ module.exports.RequestContainer = (appContainer, request) => {
.addArgument(new Reference('JavaApiClient'))
.lazy = true

container.register('ClanManagementService', ClanManagementService)
.addArgument(new Reference('UserService'))
.addArgument(new Reference('ClanManagementRepository'))
.lazy = true

container.register('ClanManagementRepository', ClanManagementRepository)
.addArgument(new Reference('JavaApiClient'))
.lazy = true

container.register('ClanManagementService', ClanManagementService)
.addArgument(new Reference('UserService'))
.addArgument(new Reference('ClanManagementRepository'))
.addArgument(appContainer.get('ClanService'))
.lazy = true

container.register('JavaApiClient')
.synthetic = true

container.register('UserService', UserService)
.lazy = true

return container
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class RequestContainerCompilerPass {
if (this.request.user) {
container.get('UserService').setUserFromRequest(this.request)
container.set('JavaApiClient', JavaApiClientFactory.createInstance(container.get('UserService'), this.appConfig.apiUrl, this.request.user.oAuthPassport, this.appConfig.oauth.strategy))
container.get('UserService').setUserRepository(container.get('UserRepository'))
}

return container
Expand Down
8 changes: 8 additions & 0 deletions src/backend/routes/views/clanRouter.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const create = require('../views/clans/create')
const express = require('../../ExpressApp')
const router = express.Router()
const middlewares = require('../middleware')

// This will be replaced soon, therefor I did not spend time on it
router.get('/', (req, res) => res.render('clans/clans'))
Expand All @@ -12,6 +14,12 @@ router.get('/view/:id', async (req, res) => {
return res.render('clans/clan', { clan: await req.appContainer.get('ClanService').getClan(clanId) })
})

router.get('/create', create)
router.post('/create', create)
router.get('/manage', middlewares.isAuthenticated(), require('./clans/get/manage'))
router.post('/update', middlewares.isAuthenticated(), require('./clans/post/update'))
router.post('/destroy', middlewares.isAuthenticated(), require('./clans/post/destroy'))

router.get('*', (req, res) => res.status(503).render('errors/503-known-issue'))

module.exports = router
64 changes: 64 additions & 0 deletions src/backend/routes/views/clans/create.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const { body, validationResult, matchedData } = require('express-validator')
const { JavaApiError } = require('../../../services/ApiErrors')

module.exports =
[
body('clan_tag', 'Please indicate the clan tag - No special characters and 3 characters maximum').notEmpty().isLength({ max: 3 }),
body('clan_description', 'Please add a description for your clan').notEmpty().isLength({ max: 1000 }),
body('clan_name', "Please indicate your clan's name").notEmpty().isLength({ max: 40 }),
async (req, res) => {
if (req.requestContainer.get('UserService').getUser()?.clan) {
return res.redirect('/clans/manage')
}

if (req.method === 'POST') {
const errors = validationResult(req)

if (!errors.isEmpty()) {
return res.render('clans/create', {
errors: {
class: 'alert-danger',
messages: errors,
type: 'Error!'
},
clan_tag: req.body.clan_tag,
clan_name: req.body.clan_name,
clan_description: req.body.clan_description
})
}

try {
const data = matchedData(req)
await req.requestContainer.get('ClanManagementService').create(data.clan_tag, data.clan_name, data.clan_description)

await req.asyncFlash('info', 'Clan created')

return res.redirect('/clans/view/' + req.requestContainer.get('UserService').getUser().clan.id)
} catch (e) {
let messages = { errors: [{ msg: 'Server-Error while creating the clan' }] }

console.error(e.stack)
if (e instanceof JavaApiError && e.error.errors[0]) {
messages = { errors: [{ msg: e.error.errors[0].detail }] }
}

return res.render('clans/create', {
clan_tag: req.body.clan_tag,
clan_name: req.body.clan_name,
clan_description: req.body.clan_description,
errors: {
class: 'alert-danger',
messages,
type: 'Error!'
}
})
}
}

res.render('clans/create', {
clan_tag: '',
clan_name: '',
clan_description: ''
})
}
]
53 changes: 0 additions & 53 deletions src/backend/routes/views/clans/get/create.js

This file was deleted.

139 changes: 16 additions & 123 deletions src/backend/routes/views/clans/get/manage.js
Original file line number Diff line number Diff line change
@@ -1,129 +1,22 @@
const request = require('request')

exports = module.exports = function (req, res) {
const locals = res.locals

// locals.section is used to set the currently selected
// item in the header navigation.
locals.section = 'clan'

let flash = null

let clanMembershipId = null
try {
clanMembershipId = req.user.data.attributes.clan.membershipId
} catch {
// The user doesnt belong to a clan
res.redirect('/clans')
return
const { JavaApiError } = require('../../../../services/ApiErrors')
exports = module.exports = async (req, res) => {
const clanMembershipId = req.requestContainer.get('UserService').getUser()?.clan?.membershipId || null
if (!clanMembershipId) {
return res.redirect('/clans')
}

// In case the user has just generated an invite link
if (req.query.invitation_id) {
flash = {}
flash.class = 'alert-invite'

flash.messages = [
{
msg:
`<p><a id='inviteLink' onclick='return false' href='${process.env.HOST}/clans/accept_invite?i=${req.query.invitation_id}'> Right click on me and copy the invitation link</a></p>Note: It only works for the user you typed.`
}
]
flash.type = ''
}

request.get(
{
url:
process.env.API_URL +
'/data/clanMembership/' + clanMembershipId + '/clan' +
'?include=memberships.player' +
'&fields[clan]=createTime,description,name,tag,updateTime,websiteUrl,founder,leader' +
'&fields[player]=login,updateTime' +
'&fields[clanMembership]=createTime,player',
headers: {
Authorization: 'Bearer ' + req.user.data.attributes.token
}
},
function (err, childRes, body) {
const clan = JSON.parse(body)

if (err || !clan.data) {
flash = {}
flash.class = 'alert-danger'
flash.messages = [{ msg: 'Unknown error while retrieving your clan information' }]
flash.type = 'Error!'

const buff = Buffer.from(JSON.stringify(flash))
const data = buff.toString('base64')

return res.redirect('/clans?flash=' + data)
}

if (clan.data.relationships.leader.data.id !== req.user.data.id) {
// Not the leader! Shouldn't be able to manage stuff
res.redirect(`/clans/${req.user.data.attributes.clan.tag}?member=true`)
return
}

locals.clan_name = clan.data.attributes.name
locals.clan_tag = clan.data.attributes.tag
locals.clan_description = clan.data.attributes.description
locals.clan_create_time = clan.data.attributes.createTime
locals.me = req.user.data.id
locals.clan_id = clan.data.id
locals.clan_link = process.env.HOST + '/clans/see?id=' + clan.data.id

const members = {}
let player = null
let membership = null
let member = null

for (const k in clan.included) {
switch (clan.included[k].type) {
case 'player':
player = clan.included[k]
if (!members[player.id]) members[player.id] = {}
members[player.id].id = player.id
members[player.id].name = player.attributes.login

if (clan.data.relationships.founder.data.id === player.id) {
locals.founder_name = player.attributes.login
}
break

case 'clanMembership':
membership = clan.included[k]
member = membership.relationships.player.data
if (!members[member.id]) members[member.id] = {}
members[member.id].id = member.id
members[member.id].membershipId = membership.id
members[member.id].joinedAt = membership.attributes.createTime
break
}
}
try {
const clan = await req.appContainer.get('ClanService').getClanMembership(clanMembershipId)

locals.clan_members = members
return res.render('clans/manage', { clan_description: clan.clan_description, clan_name: clan.clan_name, clan_tag: clan.clan_tag })
} catch (e) {
let message = e.toString()
if (e instanceof JavaApiError && e.error?.errors) {
message = e.error.errors[0].detail
}

if (req.originalUrl === '/clan_created') {
flash = {}
flash.class = 'alert-success'
flash.messages = [{ msg: 'You have successfully created your clan' }]
flash.type = 'Success!'
} else if (req.query.flash) {
const buff = Buffer.from(req.query.flash, 'base64')
const text = buff.toString('ascii')
try {
flash = JSON.parse(text)
} catch (e) {
console.error('Parsing error while trying to decode a flash error: ' + text)
console.error(e)
flash = [{ msg: 'Unknown error' }]
}
}
await req.asyncFlash('error', message)

// Render the view
res.render('clans/manage', { flash })
}
)
return res.redirect('/')
}
}
Loading

0 comments on commit 4e1b874

Please sign in to comment.