Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/nextjs-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,15 @@ jobs:
fi

echo "=== Current PM2 processes ==="
pm2 list || echo "PM2 list failed"
sudo pm2 list || echo "PM2 list failed"

echo "=== Reloading nuon process ==="
pm2 reload nuon || pm2 start "sudo npm run start" --name "nuon" --time
echo "=== Restarting nuon process ==="
sudo pm2 restart nuon || sudo pm2 start "npm run start" --name "nuon" --time

echo "=== Final PM2 processes ==="
pm2 list
sudo pm2 list

echo "=== PM2 logs (last 10 lines) ==="
timeout 10s pm2 logs nuon --lines 10 || echo "Could not fetch logs or timeout"
timeout 10s sudo pm2 logs nuon --lines 10 || echo "Could not fetch logs or timeout"

echo "=== Server restart completed ==="
10 changes: 5 additions & 5 deletions .github/workflows/nextjs-dev-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,15 @@ jobs:
fi

echo "=== Current PM2 processes ==="
pm2 list || echo "PM2 list failed"
sudo pm2 list || echo "PM2 list failed"

echo "=== Reloading nuon-dev process ==="
pm2 reload nuon-dev || pm2 start "sudo npm run start " --name "nuon-dev" --time
echo "=== Restarting nuon-dev process ==="
sudo pm2 restart nuon-dev || sudo pm2 start "npm run start " --name "nuon-dev" --time

echo "=== Final PM2 processes ==="
pm2 list
sudo pm2 list

echo "=== PM2 logs (last 10 lines) ==="
timeout 10s pm2 logs nuon-dev --lines 10 || echo "Could not fetch logs or timeout"
timeout 10s sudo pm2 logs nuon-dev --lines 10 || echo "Could not fetch logs or timeout"

echo "=== Server restart completed ==="
4 changes: 2 additions & 2 deletions client/src/app/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
CircularProgress,
} from "@mui/material"
import { useSetAtom } from "jotai"
import { get } from "@/config/api"
import axios from "@/config/axios"
import useAuth from "@/hooks/useAuth"
import { useEffect, useState } from "react"
import { useRouter } from "next/navigation"
Expand Down Expand Up @@ -95,7 +95,7 @@ function index() {

async function fetchDashboardData() {
try {
const data = await get("/admin/dashboard")
const { data } = await axios.get("/admin/dashboard")
setDashboardData(data)
} catch (err) {
setError("대시보드 데이터를 불러오는 중 오류가 발생했습니다.")
Expand Down
1 change: 0 additions & 1 deletion client/src/app/admin/soon/attendance/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import axios from "@/config/axios"
import { get } from "@/config/api"
import CommunityBox from "./CommunityBox"
import { User } from "@server/entity/user"
import AdminHeader from "@/components/AdminHeader"
import { Stack, Box, Card, CardContent, Typography } from "@mui/material"
import { Community } from "@server/entity/community"
import { useEffect, useMemo, useState } from "react"
Expand Down
110 changes: 109 additions & 1 deletion client/src/app/admin/worshipSchedule/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
Paper,
Chip,
Divider,
FormControl,
InputLabel,
} from "@mui/material"
import { useSetAtom } from "jotai"
import { worshipKr } from "@/util/worship"
Expand All @@ -26,16 +28,30 @@ import AddIcon from "@mui/icons-material/Add"
import EditIcon from "@mui/icons-material/Edit"
import SaveIcon from "@mui/icons-material/Save"
import DeleteIcon from "@mui/icons-material/Delete"
import SearchIcon from "@mui/icons-material/Search"
import { NotificationMessage } from "@/state/notification"
import CalendarMonthIcon from "@mui/icons-material/CalendarMonth"
import { WorshipKind, WorshipSchedule } from "@server/entity/worshipSchedule"
import axios from "@/config/axios"
import dayjs from "dayjs"

export default function WorshipSchedulePage() {
const setNotificationMessage = useSetAtom(NotificationMessage)
const [worshipScheduleList, setWorshipScheduleList] = useState<
WorshipSchedule[]
>([])

// Filter lists
const [filterStartDate, setFilterStartDate] = useState(
dayjs().add(-1, "month").format("YYYY-MM-DD")
)
const [filterEndDate, setFilterEndDate] = useState(
dayjs().format("YYYY-MM-DD")
)
const [filterKind, setFilterKind] = useState<string>("")
const [filterCanEdit, setFilterCanEdit] = useState<string>("")
const [filterIsVisible, setFilterIsVisible] = useState<string>("")

const [selectedWorship, setSelectedWorship] = useState<WorshipSchedule>({
date: "",
kind: WorshipKind.SundayService,
Expand All @@ -55,8 +71,16 @@ export default function WorshipSchedulePage() {
}

async function fetchWorshipSchedules() {
const params: any = {}
if (filterStartDate) params.startDate = filterStartDate
if (filterEndDate) params.endDate = filterEndDate
if (filterKind) params.kind = filterKind
if (filterCanEdit) params.canEdit = filterCanEdit
if (filterIsVisible) params.isVisible = filterIsVisible

const { data: worshipScheduleList } = await axios.get(
"/admin/worship-schedule"
"/admin/worship-schedule",
{ params }
)
setWorshipScheduleList(worshipScheduleList)
}
Expand Down Expand Up @@ -115,6 +139,87 @@ export default function WorshipSchedulePage() {
/>
</Stack>

<Paper
elevation={0}
sx={{ p: 2, mb: 2, bgcolor: "#f8f9fa", borderRadius: 2 }}
>
<Stack
direction="row"
spacing={2}
alignItems="center"
flexWrap="wrap"
useFlexGap
sx={{ "& > *": { mb: { xs: 1, md: 0 } } }}
>
<TextField
label="시작 날짜"
type="date"
size="small"
value={filterStartDate}
onChange={(e) => setFilterStartDate(e.target.value)}
sx={{ width: 150 }}
/>
<TextField
label="종료 날짜"
type="date"
size="small"
value={filterEndDate}
onChange={(e) => setFilterEndDate(e.target.value)}
sx={{ width: 150 }}
/>
<FormControl size="small" sx={{ minWidth: 120 }}>
<InputLabel>예배 종류</InputLabel>
<Select
value={filterKind}
label="예배 종류"
onChange={(e) => setFilterKind(e.target.value)}
>
<MenuItem value="">전체</MenuItem>
<MenuItem value={WorshipKind.SundayService}>
{worshipKr(WorshipKind.SundayService)}
</MenuItem>
<MenuItem value={WorshipKind.FridayService}>
{worshipKr(WorshipKind.FridayService)}
</MenuItem>
<MenuItem value={WorshipKind.Etc}>
{worshipKr(WorshipKind.Etc)}
</MenuItem>
</Select>
</FormControl>
<FormControl size="small" sx={{ minWidth: 120 }}>
<InputLabel>수정 가능</InputLabel>
<Select
value={filterCanEdit}
label="수정 가능"
onChange={(e) => setFilterCanEdit(e.target.value)}
>
<MenuItem value="">전체</MenuItem>
<MenuItem value="true">가능</MenuItem>
<MenuItem value="false">불가능</MenuItem>
</Select>
</FormControl>
<FormControl size="small" sx={{ minWidth: 120 }}>
<InputLabel>조회 여부</InputLabel>
<Select
value={filterIsVisible}
label="조회 여부"
onChange={(e) => setFilterIsVisible(e.target.value)}
>
<MenuItem value="">전체</MenuItem>
<MenuItem value="true">공개</MenuItem>
<MenuItem value="false">비공개</MenuItem>
</Select>
</FormControl>
<Button
variant="contained"
startIcon={<SearchIcon />}
onClick={fetchWorshipSchedules}
>
조회
</Button>
</Stack>
</Paper>

<Paper
elevation={0}
sx={{
Expand Down Expand Up @@ -257,6 +362,9 @@ export default function WorshipSchedulePage() {
<MenuItem value={WorshipKind.FridayService}>
{worshipKr(WorshipKind.FridayService)}
</MenuItem>
<MenuItem value={WorshipKind.Etc}>
{worshipKr(WorshipKind.Etc)}
</MenuItem>
</Select>
</Stack>

Expand Down
17 changes: 11 additions & 6 deletions client/src/app/leader/attendance/AttendRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,23 @@ import { AttendStatus } from "@server/entity/types"
import CheckCircleIcon from "@mui/icons-material/CheckCircle"
import CancelIcon from "@mui/icons-material/Cancel"
import HelpIcon from "@mui/icons-material/Help"
import { AttendData } from "@server/entity/attendData"

export default function AttendRow({ user }: { user: User }) {
const { soonAttendData, setSoonAttendData } = useAttendance()
export default function AttendRow({
user,
soonAttendData,
setSoonAttendData,
}: {
user: User
soonAttendData: Array<AttendData>
setSoonAttendData: React.Dispatch<React.SetStateAction<AttendData[]>>
}) {
const attendData = soonAttendData.find((data) => data.user.id === user.id)
if (!attendData) return null

const isAttend = attendData.isAttend

function handleAttendChange(
event: SelectChangeEvent<string>,
child: React.ReactNode
) {
function handleAttendChange(event: SelectChangeEvent<string>) {
const newAttendStatus = event.target.value as AttendStatus
if (!attendData) return
const newAttendData = { ...attendData, isAttend: newAttendStatus }
Expand Down
12 changes: 9 additions & 3 deletions client/src/app/leader/attendance/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
InputLabel,
Chip,
} from "@mui/material"
import { post } from "@/config/api"
import axios from "@/config/axios"
import { worshipKr } from "@/util/worship"
import useAttendance from "./useAttendance"
import AttendRow from "./AttendRow"
Expand All @@ -32,6 +32,7 @@ export default function SoonAttendance() {
setSelectedScheduleId,
worshipScheduleList,
groupInfo,
setSoonAttendData,
} = useAttendance()
const { isLeaderIfNotExit } = useAuth()

Expand All @@ -40,7 +41,7 @@ export default function SoonAttendance() {
}, [])

async function saveAttendData() {
await post("/soon/attendance", {
await axios.post("/soon/attendance", {
scheduleId: selectedScheduleId,
attendData: soonAttendData,
})
Expand Down Expand Up @@ -138,7 +139,12 @@ export default function SoonAttendance() {
</Typography>
<Stack spacing={2}>
{groupInfo.users.map((user) => (
<AttendRow key={user.id} user={user} />
<AttendRow
key={user.id}
user={user}
soonAttendData={soonAttendData}
setSoonAttendData={setSoonAttendData}
/>
))}
</Stack>
</Stack>
Expand Down
13 changes: 9 additions & 4 deletions client/src/app/leader/attendance/useAttendance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { AttendData } from "@server/entity/attendData"
import { Community } from "@server/entity/community"
import { WorshipSchedule } from "@server/entity/worshipSchedule"
import { get } from "@/config/api"
import axios from "@/config/axios"
import { useEffect } from "react"
import { atom, useAtom } from "jotai"
import { AttendStatus } from "@server/entity/types"
Expand Down Expand Up @@ -34,7 +34,8 @@ export default function useAttendance() {
}, [selectedScheduleId])

async function getAttendData(scheduleId: number) {
const data: Array<AttendData> = await get(
const usersIds = groupInfo?.users.map((user) => user.id) || []
const { data } = await axios.get<AttendData[]>(
`/soon/attendance/?scheduleId=${scheduleId}`
)
groupInfo?.users.forEach((user) => {
Expand All @@ -54,9 +55,13 @@ export default function useAttendance() {
}

async function fetchData() {
const groupInfo = await get("/soon/my-group-info")
const { data: groupInfo } = await axios.get<Community>(
"/soon/my-group-info"
)
setGroupInfo(groupInfo)
const worshipScheduleList = await get("/soon/worship-schedule")
const { data: worshipScheduleList } = await axios.get<WorshipSchedule[]>(
"/soon/worship-schedule"
)
setWorshipScheduleList(worshipScheduleList)
if (worshipScheduleList.length > 0) {
setSelectedScheduleId(worshipScheduleList[0].id as number)
Expand Down
1 change: 1 addition & 0 deletions server/src/entity/worshipSchedule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
export enum WorshipKind {
SundayService = 1,
FridayService = 2,
Etc = 3,
}

@Entity()
Expand Down
31 changes: 31 additions & 0 deletions server/src/routes/admin/worshipSchedule.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,41 @@
import express from "express"
import { worshipScheduleDatabase } from "../../model/dataSource"
import {
Between,
FindOptionsWhere,
LessThanOrEqual,
MoreThanOrEqual,
} from "typeorm"
import { WorshipSchedule } from "../../entity/worshipSchedule"

const router = express.Router()

router.get("/", async (req, res) => {
const { startDate, endDate, kind, canEdit, isVisible } = req.query
const where: FindOptionsWhere<WorshipSchedule> = {}

if (startDate && endDate) {
where.date = Between(String(startDate), String(endDate))
} else if (startDate) {
where.date = MoreThanOrEqual(String(startDate))
} else if (endDate) {
where.date = LessThanOrEqual(String(endDate))
}

if (kind) {
where.kind = Number(kind)
}

if (canEdit !== undefined) {
where.canEdit = canEdit === "true"
}

if (isVisible !== undefined) {
where.isVisible = isVisible === "true"
}

const data = await worshipScheduleDatabase.find({
where,
order: {
date: "DESC",
},
Expand Down
Loading