diff --git a/backend/controllers/diaryDateTagController.js b/backend/controllers/diaryDateTagController.js new file mode 100644 index 0000000..a6cb707 --- /dev/null +++ b/backend/controllers/diaryDateTagController.js @@ -0,0 +1,29 @@ +import diaryDateTagService from "../services/diaryDateTagService.js" + +export const getDiaryDateMemberTags = async (req, res) => { + console.log("getDiaryDateMemberTags"); + try { + const { authcode: userToken } = req.headers; + const { clubId, memberId } = req.params; + const tags = await diaryDateTagService.getDiaryDateMemberTags(userToken, clubId, memberId); + res.status(200).json(tags); + } catch (err) { + console.error(err); + res.status(500).json({ error: "Error retrieving diary date tags" }); + } +} + +export const addDiaryDateTag = async (req, res) => { + console.log("addDiaryDateTag"); + try { + const { authcode: userToken } = req.headers; + const { clubId } = req.params; + const { dateId, memberId, tag } = req.body; + const tags = await diaryDateTagService.addDiaryDateTag(userToken, clubId, dateId, memberId, tag); + res.status(201).json(tags); + } catch (err) { + console.error(err); + res.status(500).json({ error: "Error adding diary date tag" }); + } +} + diff --git a/backend/controllers/memberController.js b/backend/controllers/memberController.js index 9e364d0..2e9864e 100644 --- a/backend/controllers/memberController.js +++ b/backend/controllers/memberController.js @@ -7,7 +7,6 @@ const getClubMembers = async(req, res) => { if (showAll === null) { showAll = false; } - console.log('-------------- clubid:', clubId); res.status(200).json(await MemberService.getClubMembers(userToken, clubId, showAll)); } catch(error) { console.log('[getClubMembers] - Error: ', error); @@ -34,11 +33,12 @@ const getWaitingApprovals = async(req, res) => { const setClubMembers = async (req, res) => { try { - const { id: memberId, firstname: firstName, lastname: lastName, street, city, birthdate, phone, email, active, testMembership } = req.body; + const { id: memberId, firstname: firstName, lastname: lastName, street, city, birthdate, phone, email, active, + testMembership, picsInInternetAllowed } = req.body; const { id: clubId } = req.params; const { authcode: userToken } = req.headers; const addResult = await MemberService.setClubMember(userToken, clubId, memberId, firstName, lastName, street, city, birthdate, - phone, email, active, testMembership); + phone, email, active, testMembership, picsInInternetAllowed); res.status(addResult.status || 500).json(addResult.response); } catch (error) { console.error('[setClubMembers] - Error:', error); diff --git a/backend/models/Member.js b/backend/models/Member.js index 4609344..c1417e9 100644 --- a/backend/models/Member.js +++ b/backend/models/Member.js @@ -116,6 +116,11 @@ const Member = sequelize.define('User', { type: DataTypes.BOOLEAN, allowNull: false, default: false, + }, + picsInInternetAllowed: { + type: DataTypes.BOOLEAN, + allowNull: false, + default: false, } }, { underscored: true, diff --git a/backend/models/index.js b/backend/models/index.js index d3bdfad..2d3486c 100644 --- a/backend/models/index.js +++ b/backend/models/index.js @@ -111,6 +111,9 @@ PredefinedActivity.hasMany(GroupActivity, { foreignKey: 'predefinedActivityId', DiaryTag.hasMany(DiaryDateTag, { foreignKey: 'tagId', as: 'diaryDateTags' }); DiaryDateTag.belongsTo(DiaryTag, { foreignKey: 'tagId', as: 'tag' }); +DiaryMemberTag.belongsTo(DiaryDate, { foreignKey: 'diaryDateId', as: 'diaryDates' }); +DiaryDate.hasMany(DiaryMemberTag, { foreignKey: 'diaryDateId', as: 'diaryMemberTags' }); + export { User, Log, diff --git a/backend/routes/diaryDateActivityRoutes.js b/backend/routes/diaryDateActivityRoutes.js index b781292..545e468 100644 --- a/backend/routes/diaryDateActivityRoutes.js +++ b/backend/routes/diaryDateActivityRoutes.js @@ -11,11 +11,13 @@ import { authenticate } from '../middleware/authMiddleware.js'; const router = express.Router(); -router.post('/group', authenticate, addGroupActivity); -router.post('/:clubId/', authenticate, createDiaryDateActivity); -router.put('/:clubId/:id/order', authenticate, updateDiaryDateActivityOrder); -router.put('/:clubId/:id', authenticate, updateDiaryDateActivity); -router.delete('/:clubId/:id', authenticate, deleteDiaryDateActivity); -router.get('/:clubId/:diaryDateId', authenticate, getDiaryDateActivities); +router.use(authenticate); + +router.post('/group', addGroupActivity); +router.post('/:clubId/', createDiaryDateActivity); +router.put('/:clubId/:id/order', updateDiaryDateActivityOrder); +router.put('/:clubId/:id', updateDiaryDateActivity); +router.delete('/:clubId/:id', deleteDiaryDateActivity); +router.get('/:clubId/:diaryDateId', getDiaryDateActivities); export default router; diff --git a/backend/routes/diaryDateTagRoutes.js b/backend/routes/diaryDateTagRoutes.js new file mode 100644 index 0000000..50ef739 --- /dev/null +++ b/backend/routes/diaryDateTagRoutes.js @@ -0,0 +1,12 @@ +import express from 'express'; +import { getDiaryDateMemberTags, addDiaryDateTag } from '../controllers/diaryDateTagController.js'; +import { authenticate } from '../middleware/authMiddleware.js'; + +const router = express.Router(); + +router.use(authenticate); + +router.get('/:clubId/:memberId', getDiaryDateMemberTags); +router.post('/:clubId', addDiaryDateTag); + +export default router; diff --git a/backend/server.js b/backend/server.js index 3364662..8ffa6a8 100644 --- a/backend/server.js +++ b/backend/server.js @@ -25,6 +25,7 @@ import matchRoutes from './routes/matchRoutes.js'; import Season from './models/Season.js'; import Location from './models/Location.js'; import groupRoutes from './routes/groupRoutes.js'; +import diaryDateTagRoutes from './routes/diaryDateTagRoutes.js'; const app = express(); const port = process.env.PORT || 3000; @@ -49,6 +50,7 @@ app.use('/api/predefined-activities', predefinedActivityRoutes); app.use('/api/diary-date-activities', diaryDateActivityRoutes); app.use('/api/matches', matchRoutes); app.use('/api/group', groupRoutes); +app.use('/api/diarydatetags', diaryDateTagRoutes); app.use(express.static(path.join(__dirname, '../frontend/dist'))); diff --git a/backend/services/diaryDateTagService.js b/backend/services/diaryDateTagService.js new file mode 100644 index 0000000..74d517c --- /dev/null +++ b/backend/services/diaryDateTagService.js @@ -0,0 +1,60 @@ +import DiaryDate from "../models/DiaryDates.js"; +import DiaryDateTag from "../models/DiaryDateTag.js"; +import DiaryMemberTag from "../models/DiaryMemberTag.js"; +import { DiaryTag } from "../models/DiaryTag.js"; +import Member from "../models/Member.js"; +import { checkAccess } from '../utils/userUtils.js'; +import { Op, literal } from "sequelize"; + +class DiaryDateTagService { + async getDiaryDateMemberTags(userToken, clubId, memberId) { + await checkAccess(userToken, clubId); + return await DiaryTag.findAll({ + include: [ + { + model: DiaryMemberTag, + as: 'diaryMemberTags', + where: { memberId }, + required: true, + include: [ + { + model: DiaryDate, + as: 'diaryDates', + required: true, + on: { + '$diaryMemberTags.diary_date_id$': { [Op.eq]: literal('`diaryMemberTags->diaryDates`.`id`') } + } + } + ] + } + ], + order: [[literal('`diaryMemberTags->diaryDates`.`date`'), 'DESC']], + group: ['DiaryTag.id'], + having: literal('COUNT(DISTINCT `diaryMemberTags->diaryDates`.`id`) >= 1'), + }); + } + + async addDiaryDateTag(userToken, clubId, diaryDateId, memberId, tag) { + console.log(userToken, clubId, diaryDateId, memberId, tag); + await checkAccess(userToken, clubId); + const tagObject = await DiaryTag.findOne({ where: { id: tag.id } }); + if (!tagObject) { + throw new Error('Tag not found'); + } + const diaryDate = await DiaryDate.findByPk(diaryDateId); + if (!diaryDate) { + throw new Error('DiaryDate not found'); + } + const member = await Member.findByPk(memberId); + if (!member) { + throw new Error('Member not found'); + } + const existingTag = await DiaryMemberTag.findOne({ where: { diaryDateId, memberId, tagId: tag.id } }); + if (!existingTag) { + await DiaryMemberTag.create({ diaryDateId, memberId, tagId: tag.id }); + } + return await this.getDiaryDateMemberTags(userToken, clubId, memberId); + } +} + +export default new DiaryDateTagService(); diff --git a/backend/services/memberService.js b/backend/services/memberService.js index ee3728f..0e07a8b 100644 --- a/backend/services/memberService.js +++ b/backend/services/memberService.js @@ -53,7 +53,8 @@ class MemberService { }); } - async setClubMember(userToken, clubId, memberId, firstName, lastName, street, city, birthdate, phone, email, active = true, testMembership = false) { + async setClubMember(userToken, clubId, memberId, firstName, lastName, street, city, birthdate, phone, email, active = true, testMembership = false, + picsInInternetAllowed = false) { try { console.log('[setClubMembers] - Check access'); await checkAccess(userToken, clubId); @@ -73,7 +74,8 @@ class MemberService { member.phone = phone; member.email = email; member.active = active; - member.testMembership = testMembership + member.testMembership = testMembership; + member.picsInInternetAllowed = picsInInternetAllowed; await member.save(); } else { await Member.create({ @@ -86,7 +88,8 @@ class MemberService { email: email, clubId: clubId, active: active, - testMembership: testMembership + testMembership: testMembership, + picsInInternetAllowed: picsInInternetAllowed, }); } console.log('[setClubMembers] - return response'); diff --git a/frontend/src/views/DiaryView.vue b/frontend/src/views/DiaryView.vue index 269863d..b61542f 100644 --- a/frontend/src/views/DiaryView.vue +++ b/frontend/src/views/DiaryView.vue @@ -179,7 +179,7 @@ member.firstName }} {{ member.lastName }} - 📝 + 📝 ℹ️ @@ -192,7 +192,49 @@
+ + +