diff --git a/backend/controllers/clubController.js b/backend/controllers/clubController.js index d03b69c..515ff48 100644 --- a/backend/controllers/clubController.js +++ b/backend/controllers/clubController.js @@ -198,8 +198,7 @@ exports.createClub = async (req, res) => { // 클럽 정보 업데이트 exports.updateClub = async (req, res) => { try { - const { id, name, location, description, contact, ownerEmail, status } = req.body; - const clubId = id || req.params.id; + const { clubId, name, location, description, contact, ownerEmail, status, femaleHandicap } = req.body; const club = await Club.findByPk(clubId); if (!club) { @@ -226,6 +225,7 @@ exports.updateClub = async (req, res) => { description: description !== undefined ? description : club.description, contact: contact !== undefined ? contact : club.contact, status: status || club.status, + femaleHandicap: femaleHandicap || club.femaleHandicap, ownerId: newOwnerId }); @@ -421,7 +421,7 @@ exports.addClubMember = async (req, res) => { // 클럽 회원 정보 수정 exports.updateClubMember = async (req, res) => { try { - const { clubId, memberId, name, gender, memberType, email, phone, status } = req.body; + const { clubId, memberId, name, gender, memberType, email, phone, handicap, status } = req.body; if (!clubId || !memberId) { return res.status(400).json({ message: '잘못된 클럽 또는 회원 ID입니다.' }); @@ -461,6 +461,7 @@ exports.updateClubMember = async (req, res) => { memberType: memberType || member.memberType, email: email || member.email, phone: phone || member.phone, + handicap: handicap || member.handicap, status: status || member.status }); diff --git a/backend/controllers/publicController.js b/backend/controllers/publicController.js index b2844a9..e1c0e93 100644 --- a/backend/controllers/publicController.js +++ b/backend/controllers/publicController.js @@ -265,6 +265,10 @@ exports.addPublicGuest = async (req, res) => { // 클럽의 회원 수와 구독 플랜의 최대 회원 수 확인 const memberCount = await Member.count({ where: { clubId: event.clubId } }); + // 클럽 정보 가져오기 (여성 기본 핸디캡 확인을 위해) + const club = await Club.findByPk(event.clubId); + if (!club) return res.status(404).json({ message: '클럽 정보를 찾을 수 없습니다.' }); + // 클럽의 구독 정보 가져오기 - 가장 최근 구독 정보 const clubSubscription = await sequelize.models.ClubSubscription.findOne({ where: { clubId: event.clubId }, @@ -288,6 +292,12 @@ exports.addPublicGuest = async (req, res) => { } } + // 여성 핸디캡 적용 + let handicap = null; + if (gender === '여성' && club.femaleHandicap) { + handicap = club.femaleHandicap; + } + // publicAuth 미들웨어로 인증됨 const member = await Member.create({ name, @@ -295,7 +305,8 @@ exports.addPublicGuest = async (req, res) => { gender, clubId: event.clubId, memberType: '게스트', - average: average || 0 + average: average || 0, + handicap: handicap // 여성 핸디캡 적용 }); const participant = await EventParticipant.create({ eventId: event.id, memberId: member.id }); res.json({ diff --git a/backend/models/Club.js b/backend/models/Club.js index b35bf9a..0df1cba 100644 --- a/backend/models/Club.js +++ b/backend/models/Club.js @@ -49,6 +49,12 @@ const Club = sequelize.define('Club', { defaultValue: 0, comment: '회원 수' }, + femaleHandicap: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 15, + comment: '여성 기본 핸디캡' + }, createdAt: { type: DataTypes.DATE, allowNull: false, diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 4e21c96..50abe00 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -12,7 +12,15 @@
-

{{ selectedClub.name }}

+
+

{{ selectedClub.name }}

+ + + +

{{ selectedClub.location }}

@@ -121,6 +129,7 @@ const ownerName = ref(''); const isRouterReady = ref(false); const userRole = computed(() => user.value?.role || ''); const isAdmin = computed(() => userRole.value === 'admin' || userRole.value === 'superadmin'); +const userClubRole = ref(localStorage.getItem('userClubRole') || ''); // 화면 크기 변경 감지 const handleResize = () => { @@ -430,12 +439,29 @@ body { margin-bottom: 10px; } +.club-title { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 5px; +} + .club-header h3 { margin: 0; font-size: 1.2em; font-weight: bold; } +.settings-icon { + color: #6c757d; + font-size: 1.1em; + transition: color 0.3s ease; +} + +.settings-icon:hover { + color: #007bff; +} + .club-location { margin: 0; font-size: 0.9em; diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js index 604bfab..1ec33f7 100644 --- a/frontend/src/router/index.js +++ b/frontend/src/router/index.js @@ -19,6 +19,7 @@ const EventManagement = () => import('@/views/club/EventManagement.vue'); const EventCalendar = () => import('@/views/club/EventCalendar.vue'); const ScoreManagement = () => import('@/views/club/ScoreManagement.vue'); const UserClubCreate = () => import('@/views/club/ClubCreate.vue'); +const ClubSettings = () => import('@/views/club/ClubSettings.vue'); // 구독 관리 컴포넌트 import const ClubSubscriptionManagement = () => import('@/views/club/subscription/SubscriptionManagement.vue'); @@ -133,6 +134,15 @@ const routes = [ requiresAuth: true, requiredRoles: ['admin', '모임장', '운영진'] } + }, + { + path: 'settings', + name: 'ClubSettings', + component: ClubSettings, + meta: { + requiresAuth: true, + requiredRoles: ['admin', '모임장', '운영진'] + } } ] }, @@ -201,8 +211,9 @@ router.beforeEach(async (to, from, next) => { return; } - // 클럽 구독 관리 페이지에 접근하려는 경우, 권한 확인 - if (to.name === 'ClubSubscription' && (userClubRole !== 'admin' && userClubRole !== '모임장' && userClubRole !== '운영진')) { + // 클럽 구독 관리 또는 설정 페이지에 접근하려는 경우, 권한 확인 + if ((to.name === 'ClubSubscription' || to.name === 'ClubSettings') && + (userClubRole !== 'admin' && userClubRole !== '모임장' && userClubRole !== '운영진')) { next({ name: 'ClubDashboard' }); return; } diff --git a/frontend/src/views/club/ClubSettings.vue b/frontend/src/views/club/ClubSettings.vue new file mode 100644 index 0000000..5fda256 --- /dev/null +++ b/frontend/src/views/club/ClubSettings.vue @@ -0,0 +1,606 @@ + + + + + diff --git a/frontend/src/views/club/EventManagement.vue b/frontend/src/views/club/EventManagement.vue index d2a1ea0..d396f7f 100644 --- a/frontend/src/views/club/EventManagement.vue +++ b/frontend/src/views/club/EventManagement.vue @@ -21,6 +21,8 @@ stripedRows filterDisplay="menu" v-model:filters="filters" + sort-field="startDate" + :sort-order="-1" class="mt-4" > diff --git a/frontend/src/views/club/MemberManagement.vue b/frontend/src/views/club/MemberManagement.vue index 59935a1..963e901 100644 --- a/frontend/src/views/club/MemberManagement.vue +++ b/frontend/src/views/club/MemberManagement.vue @@ -22,6 +22,8 @@ @@ -62,29 +64,35 @@ :header="dialogMode === 'new' ? '새 회원 추가' : '회원 정보 수정'" :modal="true" class="p-fluid"> -
- - -
-
- - -
-
- - -
-
- - -
-
- - +
+
+ + +