Files
sam-manage/resources/views/project-management/projects/index.blade.php
kent 6be0a219c3 refactor(mng): 프로젝트 관리 페이지 이모지를 SVG 아이콘으로 변경
- 대시보드 페이지: 통계 카드, 섹션 제목, JS 동적 렌더링 이모지 → Heroicons SVG
- 프로젝트 목록 페이지: 페이지 제목 이모지 → folder SVG
- mng 시스템 기존 아이콘 스타일과 일관성 유지

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 22:50:26 +09:00

140 lines
5.4 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="text-gray-500 hover:text-gray-700">
대시보드
</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>
<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 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