Files
sam-manage/app/Http/Controllers/DashboardCalendarController.php
김보곤 0281e4a8aa feat:대시보드 일정관리 달력 추가
- Schedule 모델 생성 (schedules 테이블, type별 색상 상수)
- DashboardCalendarController 생성 (CRUD + 달력 partial)
- 대시보드 뷰에 월간 달력 섹션 추가 (HTMX + Vanilla JS)
- 일정 생성/수정/삭제 모달 구현
- 공휴일 빨간색 표시, 일정 유형별 색상 뱃지

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 20:11:36 +09:00

172 lines
5.3 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\System\Holiday;
use App\Models\System\Schedule;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Contracts\View\View;
class DashboardCalendarController extends Controller
{
/**
* 달력 partial 반환 (HTMX용)
*/
public function calendar(Request $request): View
{
$year = (int) $request->input('year', now()->year);
$month = (int) $request->input('month', now()->month);
$tenantId = session('selected_tenant_id', 1);
$firstDay = Carbon::create($year, $month, 1);
$lastDay = $firstDay->copy()->endOfMonth();
$startOfWeek = $firstDay->copy()->startOfWeek(Carbon::SUNDAY);
$endOfWeek = $lastDay->copy()->endOfWeek(Carbon::SATURDAY);
$calendarData = Schedule::forTenant($tenantId)
->active()
->betweenDates($startOfWeek->toDateString(), $endOfWeek->toDateString())
->orderBy('start_date')
->orderBy('start_time')
->get()
->groupBy(fn ($s) => $s->start_date->format('Y-m-d'));
$holidayMap = $this->getHolidayMap($tenantId, $year, $month);
return view('dashboard.partials.calendar', compact(
'year', 'month', 'calendarData', 'holidayMap'
));
}
/**
* 일정 등록
*/
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string|max:1000',
'start_date' => 'required|date',
'end_date' => 'nullable|date|after_or_equal:start_date',
'start_time' => 'nullable|date_format:H:i',
'end_time' => 'nullable|date_format:H:i',
'is_all_day' => 'boolean',
'type' => 'required|in:event,meeting,notice,other',
'color' => 'nullable|string|max:20',
]);
$tenantId = session('selected_tenant_id', 1);
$validated['tenant_id'] = $tenantId;
$validated['created_by'] = auth()->id();
$validated['is_all_day'] = $validated['is_all_day'] ?? true;
if (empty($validated['end_date'])) {
$validated['end_date'] = $validated['start_date'];
}
$schedule = Schedule::create($validated);
return response()->json([
'success' => true,
'message' => '일정이 등록되었습니다.',
'data' => $schedule,
]);
}
/**
* 일정 상세 (JSON)
*/
public function show(int $id): JsonResponse
{
$tenantId = session('selected_tenant_id', 1);
$schedule = Schedule::forTenant($tenantId)->findOrFail($id);
return response()->json([
'success' => true,
'data' => $schedule,
]);
}
/**
* 일정 수정
*/
public function update(Request $request, int $id): JsonResponse
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string|max:1000',
'start_date' => 'required|date',
'end_date' => 'nullable|date|after_or_equal:start_date',
'start_time' => 'nullable|date_format:H:i',
'end_time' => 'nullable|date_format:H:i',
'is_all_day' => 'boolean',
'type' => 'required|in:event,meeting,notice,other',
'color' => 'nullable|string|max:20',
]);
$tenantId = session('selected_tenant_id', 1);
$schedule = Schedule::forTenant($tenantId)->findOrFail($id);
$validated['updated_by'] = auth()->id();
$validated['is_all_day'] = $validated['is_all_day'] ?? true;
if (empty($validated['end_date'])) {
$validated['end_date'] = $validated['start_date'];
}
$schedule->update($validated);
return response()->json([
'success' => true,
'message' => '일정이 수정되었습니다.',
'data' => $schedule->fresh(),
]);
}
/**
* 일정 삭제
*/
public function destroy(int $id): JsonResponse
{
$tenantId = session('selected_tenant_id', 1);
$schedule = Schedule::forTenant($tenantId)->findOrFail($id);
$schedule->update(['deleted_by' => auth()->id()]);
$schedule->delete();
return response()->json([
'success' => true,
'message' => '일정이 삭제되었습니다.',
]);
}
/**
* 해당 월의 휴일 맵 생성 (날짜 => 휴일명)
*/
private function getHolidayMap(int $tenantId, int $year, int $month): array
{
$startOfMonth = Carbon::create($year, $month, 1)->startOfWeek(Carbon::SUNDAY);
$endOfMonth = Carbon::create($year, $month, 1)->endOfMonth()->endOfWeek(Carbon::SATURDAY);
$holidays = Holiday::forTenant($tenantId)
->where('start_date', '<=', $endOfMonth->toDateString())
->where('end_date', '>=', $startOfMonth->toDateString())
->get();
$map = [];
foreach ($holidays as $holiday) {
$start = $holiday->start_date->copy();
$end = $holiday->end_date->copy();
for ($d = $start; $d->lte($end); $d->addDay()) {
$map[$d->format('Y-m-d')] = $holiday->name;
}
}
return $map;
}
}