Files
sam-manage/resources/views/project-management/projects/index.blade.php
hskwon 2846d6c034 style: 관리자 패널 UI 개선 및 스크럼 모달 통합
- 테이블 헤더 스타일 통일 (menus, roles, permissions, boards 등)
- 권한 매트릭스 체크박스/버튼 크기 20x20으로 표준화
- 스크럼 항목 추가/수정 모달 통합 (코드 중복 제거)
- daily-logs API URL 경로 수정 (/pm/ 제거)
- 타임존 Asia/Seoul로 변경
- flow-tester 액션 아이콘 크기 조정
2025-12-03 16:47:57 +09:00

151 lines
6.2 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@extends('layouts.app')
@section('title', '프로젝트 목록')
@section('content')
<!-- 페이지 헤더 -->
<div class="flex justify-between items-center mb-6">
<div class="flex items-center gap-4">
<a href="{{ route('pm.index') }}" class="inline-flex items-center gap-1 px-3 py-1.5 text-sm text-gray-600 bg-gray-100 hover:bg-gray-200 rounded-lg transition">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/>
</svg>
대시보드
</a>
<h1 class="text-2xl font-bold text-gray-800 flex items-center gap-2">
<svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z" />
</svg>
프로젝트 목록
</h1>
</div>
<div class="flex gap-2">
<a href="{{ route('pm.import') }}" class="bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg transition flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
</svg>
JSON Import
</a>
<a href="{{ route('pm.projects.create') }}" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition">
+ 프로젝트
</a>
</div>
</div>
<!-- 필터 영역 -->
<div class="bg-white rounded-lg shadow-sm p-4 mb-6">
<form id="filterForm" class="flex gap-4 flex-wrap">
<!-- 검색 -->
<div class="flex-1 min-w-64">
<input type="text"
name="search"
placeholder="프로젝트명, 설명으로 검색..."
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<!-- 상태 필터 -->
<div class="w-40">
<select name="status" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="">전체 상태</option>
@foreach($statuses as $value => $label)
<option value="{{ $value }}">{{ $label }}</option>
@endforeach
</select>
</div>
<!-- 삭제된 항목 포함 -->
<div class="w-40">
<select name="trashed" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="">활성만</option>
<option value="with">삭제 포함</option>
<option value="only">삭제만</option>
</select>
</div>
<!-- 검색 버튼 -->
<button type="submit" class="bg-gray-600 hover:bg-gray-700 text-white px-6 py-2 rounded-lg transition">
검색
</button>
</form>
</div>
<!-- 테이블 영역 (HTMX로 로드) -->
<div id="project-table"
hx-get="/api/admin/pm/projects"
hx-trigger="load, filterSubmit from:body"
hx-include="#filterForm"
hx-headers='{"X-CSRF-TOKEN": "{{ csrf_token() }}"}'
class="bg-white rounded-lg shadow-sm overflow-hidden">
<!-- 로딩 스피너 -->
<div class="flex justify-center items-center p-12">
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
</div>
</div>
@endsection
@push('scripts')
<script>
// 폼 제출 시 HTMX 이벤트 트리거
document.getElementById('filterForm').addEventListener('submit', function(e) {
e.preventDefault();
htmx.trigger('#project-table', 'filterSubmit');
});
// 삭제 확인
window.confirmDelete = function(id, name) {
if (confirm(`"${name}" 프로젝트를 삭제하시겠습니까?`)) {
htmx.ajax('DELETE', `/api/admin/pm/projects/${id}`, {
target: '#project-table',
swap: 'none',
headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}' }
}).then(() => {
htmx.trigger('#project-table', 'filterSubmit');
});
}
};
// 복원 확인
window.confirmRestore = function(id, name) {
if (confirm(`"${name}" 프로젝트를 복원하시겠습니까?`)) {
htmx.ajax('POST', `/api/admin/pm/projects/${id}/restore`, {
target: '#project-table',
swap: 'none',
headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}' }
}).then(() => {
htmx.trigger('#project-table', 'filterSubmit');
});
}
};
// 영구삭제 확인
window.confirmForceDelete = function(id, name) {
if (confirm(`"${name}" 프로젝트를 영구 삭제하시겠습니까?\n\n⚠ 이 작업은 되돌릴 수 없으며, 관련된 모든 작업과 이슈도 삭제됩니다!`)) {
htmx.ajax('DELETE', `/api/admin/pm/projects/${id}/force`, {
target: '#project-table',
swap: 'none',
headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}' }
}).then(() => {
htmx.trigger('#project-table', 'filterSubmit');
});
}
};
// 복제 확인
window.confirmDuplicate = function(id, name) {
const newName = prompt(`"${name}" 프로젝트를 복제합니다.\n새 프로젝트 이름을 입력하세요:`, name + ' (복사본)');
if (newName) {
htmx.ajax('POST', `/api/admin/pm/projects/${id}/duplicate`, {
target: '#project-table',
swap: 'none',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}',
'Content-Type': 'application/json'
},
values: { name: newName }
}).then(() => {
htmx.trigger('#project-table', 'filterSubmit');
});
}
};
</script>
@endpush