364 lines
18 KiB
HTML

{% load static %}
<!DOCTYPE html>
<html lang="ko" class="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>프로필 수정 | 신라대학교 AMP 제8기</title>
<script src="https://unpkg.com/htmx.org@1.9.5"></script>
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
darkMode: 'class',
}
</script>
<!-- 다크모드 초기 설정 스크립트 (FOUC 방지) -->
<script>
(function() {
const savedTheme = localStorage.getItem('theme');
if (savedTheme === 'light') {
document.documentElement.classList.remove('dark');
}
})();
</script>
</head>
<body class="bg-gray-200 dark:bg-gray-900 text-gray-900 dark:text-gray-100 min-h-screen transition-colors duration-300">
<style>
/* "Currently:" 텍스트 숨기기 */
.help {
display: none !important;
}
/* 파일 입력 필드 스타일링 */
input[type="file"] {
border: 1px solid #4a5568;
padding: 8px;
border-radius: 4px;
background-color: #2d3748;
color: white;
width: 100%;
}
input[type="file"]::-webkit-file-upload-button {
background-color: #4299e1;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
margin-right: 10px;
}
input[type="file"]::-webkit-file-upload-button:hover {
background-color: #3182ce;
}
</style>
<div class="max-w-5xl mx-auto px-4 py-8">
<!-- 헤더와 다크모드 토글 -->
<div class="flex justify-between items-center mb-6">
<a href="{% url 'main' %}" class="text-3xl font-bold text-gray-900 dark:text-white hover:text-blue-600 dark:hover:text-blue-400 transition-colors duration-200 cursor-pointer">신라대학교 AMP 제8기</a>
<div class="space-x-4 text-sm">
{% if user.is_authenticated %}
<div class="flex flex-col items-end sm:items-center sm:flex-row sm:space-x-4 space-y-1 sm:space-y-0">
<!-- 데스크탑에서만 환영 메시지 표시 -->
<span class="hidden sm:block text-sm text-gray-700 dark:text-gray-200 font-semibold">
{% if user.is_superuser %}
<a href="{% url 'accounts:custom_profile_edit' %}" class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">{{ user.username }} 님</a>, 환영합니다!
{% else %}
<a href="{% url 'accounts:custom_profile_edit' %}" class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">{{ user.person.이름 }} 님</a>, 환영합니다!
{% endif %}
</span>
<!-- 모바일: 햄버거 메뉴, 데스크탑: 버튼 노출 -->
<div class="relative">
<!-- 모바일: 다크모드 토글 버튼과 햄버거 버튼을 가로로 배치 -->
<div class="sm:hidden flex items-center space-x-2">
<!-- 모바일: 다크모드 토글 버튼 (햄버거 버튼 왼쪽) -->
<button id="theme-toggle-mobile" class="p-2 rounded-lg bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors duration-300" aria-label="테마 변경">
<!-- 라이트 모드 아이콘 (다크모드일 때 보임) -->
<svg id="theme-toggle-light-icon-mobile" class="w-5 h-5 text-gray-800 dark:text-gray-200" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" clip-rule="evenodd"></path>
</svg>
<!-- 다크 모드 아이콘 (라이트모드일 때 보임) -->
<svg id="theme-toggle-dark-icon-mobile" class="w-5 h-5 text-gray-800 dark:text-gray-200 hidden" fill="currentColor" viewBox="0 0 20 20">
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"></path>
</svg>
</button>
<!-- 햄버거 버튼 (모바일에서만 보임) -->
<button id="mobile-menu-button" class="flex items-center px-2 py-1 border rounded text-gray-700 dark:text-gray-200 border-gray-400 dark:border-gray-600 focus:outline-none" aria-label="메뉴 열기">
<svg class="w-6 h-6" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16"/>
</svg>
</button>
</div>
<!-- 모바일 드롭다운 메뉴 -->
<div id="mobile-menu-dropdown" class="hidden absolute right-0 mt-2 w-48 bg-white dark:bg-gray-800 rounded-lg shadow-lg z-50 border border-gray-200 dark:border-gray-700">
<!-- 모바일에서 환영 메시지 표시 -->
<div class="px-4 py-2 text-sm text-gray-700 dark:text-gray-200 font-semibold border-b border-gray-200 dark:border-gray-700">
{% if user.is_superuser %}
<a href="{% url 'accounts:custom_profile_edit' %}" class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">{{ user.username }} 님</a>, 환영합니다!
{% else %}
<a href="{% url 'accounts:custom_profile_edit' %}" class="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">{{ user.person.이름 }} 님</a>, 환영합니다!
{% endif %}
</div>
<a href="{% url 'account_logout' %}" class="block px-4 py-2 text-red-500 hover:bg-gray-100 dark:hover:bg-gray-700">로그아웃</a>
</div>
<!-- 데스크탑 버튼 (sm 이상에서만 보임) -->
<div class="hidden sm:flex items-center space-x-3 mt-1 sm:mt-0">
<a href="{% url 'account_logout' %}" class="text-red-400 hover:text-red-500">로그아웃</a>
<!-- 데스크탑: 다크모드 토글 버튼 (로그아웃 오른쪽) -->
<button id="theme-toggle" class="p-2 rounded-lg bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors duration-300" aria-label="테마 변경">
<!-- 라이트 모드 아이콘 (다크모드일 때 보임) -->
<svg id="theme-toggle-light-icon" class="w-5 h-5 text-gray-800 dark:text-gray-200" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" clip-rule="evenodd"></path>
</svg>
<!-- 다크 모드 아이콘 (라이트모드일 때 보임) -->
<svg id="theme-toggle-dark-icon" class="w-5 h-5 text-gray-800 dark:text-gray-200 hidden" fill="currentColor" viewBox="0 0 20 20">
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"></path>
</svg>
</button>
</div>
</div>
</div>
{% elif request.session.authenticated %}
<a href="{% url 'session_logout' %}" class="text-red-400 hover:text-red-500">로그아웃</a>
{% else %}
<a href="{% url 'account_login' %}" class="text-blue-400 hover:text-blue-500">로그인</a>
<a href="{% url 'account_signup' %}" class="text-green-400 hover:text-green-500">회원가입</a>
{% endif %}
</div>
</div>
<!-- 프로필 수정 폼 -->
<div class="flex justify-center">
<div class="bg-white dark:bg-gray-800 bg-opacity-95 dark:bg-opacity-70 backdrop-blur-lg p-8 rounded-2xl shadow-2xl w-full max-w-md border border-gray-200 dark:border-gray-700 transition-colors duration-300">
<div class="text-center mb-6">
<h2 class="text-2xl font-bold tracking-tight text-gray-900 dark:text-white">프로필 수정</h2>
<p class="text-sm text-gray-600 dark:text-gray-400 mt-2">개인 정보를 수정하세요</p>
</div>
{% if messages %}
{% for message in messages %}
<div class="p-4 rounded-lg {% if message.tags == 'success' %}bg-green-600{% else %}bg-red-600{% endif %} text-white mb-4">
{{ message }}
</div>
{% endfor %}
{% endif %}
<form method="POST" enctype="multipart/form-data" class="space-y-4">
{% csrf_token %}
{% if form.errors %}
<div class="text-red-400 text-sm mb-2">
{% for field, errors in form.errors.items %}
{% for error in errors %}
{{ error }}
{% endfor %}
{% endfor %}
</div>
{% endif %}
<!-- 편집 불가능한 필드들 (회색 배경) -->
<div class="mb-6">
<div class="mb-4">
<label class="block mb-1 text-sm text-gray-700 dark:text-gray-300">{{ form.full_name.label }}</label>
{{ form.full_name }}
</div>
<div class="mb-4">
<label class="block mb-1 text-sm text-gray-700 dark:text-gray-300">{{ form.phone_display.label }}</label>
{{ form.phone_display }}
</div>
<div class="mb-4">
<label class="block mb-1 text-sm text-gray-700 dark:text-gray-300">{{ form.birth_date_display.label }}</label>
{{ form.birth_date_display }}
</div>
<div class="mb-4">
<label class="block mb-1 text-sm text-gray-700 dark:text-gray-300">{{ form.amp_title_display.label }}</label>
{{ form.amp_title_display }}
</div>
</div>
<!-- 편집 가능한 필드들 (파란색 테두리) -->
<div class="border-t border-gray-300 dark:border-gray-600 pt-6">
<div class="mb-4">
<label for="{{ form.소속.id_for_label }}" class="block mb-1 text-sm text-gray-700 dark:text-gray-300">{{ form.소속.label }}</label>
{{ form.소속 }}
</div>
<div class="mb-4">
<label for="{{ form.직책.id_for_label }}" class="block mb-1 text-sm text-gray-700 dark:text-gray-300">{{ form.직책.label }}</label>
{{ form.직책 }}
</div>
<div class="mb-4">
<label for="{{ form.주소.id_for_label }}" class="block mb-1 text-sm text-gray-700 dark:text-gray-300">{{ form.주소.label }}</label>
{{ form.주소 }}
</div>
<div class="mb-4">
<label for="{{ form.keyword1.id_for_label }}" class="block mb-1 text-sm text-gray-700 dark:text-gray-300">{{ form.keyword1.label }}</label>
{{ form.keyword1 }}
</div>
<div class="mb-4">
<label for="{{ form.소개글.id_for_label }}" class="block mb-1 text-sm text-gray-700 dark:text-gray-300">{{ form.소개글.label }}</label>
{{ form.소개글 }}
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">최대 200자까지 입력 가능합니다.</p>
</div>
</div>
<button type="submit"
class="w-full py-3 bg-blue-600 hover:bg-blue-700 active:bg-blue-800 rounded-xl text-white font-semibold text-base transition duration-200 shadow-md hover:shadow-lg">
프로필 저장
</button>
</form>
<!-- 비밀번호 변경 섹션 -->
<div class="mt-6 pt-6 border-t border-gray-300 dark:border-gray-600">
<div class="text-center">
<div class="space-y-3">
<a href="{% url 'accounts:password_change_logged_in' %}"
class="block w-full px-6 py-2 bg-orange-600 hover:bg-orange-700 rounded-lg text-white font-medium text-sm transition duration-200 shadow-md hover:shadow-lg">
비밀번호 변경
</a>
</div>
</div>
</div>
<!-- 회원탈퇴 섹션 -->
<div class="mt-8 pt-6 border-t border-gray-300 dark:border-gray-600">
<div class="bg-red-50 dark:bg-red-900 bg-opacity-50 dark:bg-opacity-20 border border-red-300 dark:border-red-600 p-4 rounded-xl">
<h3 class="text-sm font-medium text-red-700 dark:text-red-300 mb-2">회원탈퇴</h3>
<p class="text-xs text-red-600 dark:text-red-200 mb-4">
탈퇴 시 계정이 삭제되고 개인정보가 원본 데이터로 복원됩니다.
관리자 승인 후 처리되며, 탈퇴 후 재가입 시 기존 정보가 초기화됩니다.
</p>
<a href="{% url 'accounts:withdrawal_request' %}"
class="inline-block px-4 py-2 bg-red-600 hover:bg-red-700 text-white text-sm rounded-lg transition duration-200"
onclick="return confirm('정말로 회원탈퇴를 요청하시겠습니까?')">
회원탈퇴 요청
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// 사진 업로드 시 미리보기 (필드가 없으면 안전하게 건너뜀)
(function() {
const fileInput = document.querySelector('input[type=file][name$=사진]');
if (fileInput) {
fileInput.addEventListener('change', function(e) {
const file = e.target.files && e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(ev) {
const preview = document.getElementById('profile-preview');
if (preview) {
preview.src = ev.target.result;
}
};
reader.readAsDataURL(file);
}
});
}
})();
// 통합된 스크립트 - DOMContentLoaded 이벤트 한 번만 사용
document.addEventListener('DOMContentLoaded', function() {
// ===== 햄버거 메뉴 토글 스크립트 =====
const mobileMenuBtn = document.getElementById('mobile-menu-button');
const mobileMenuDropdown = document.getElementById('mobile-menu-dropdown');
if (mobileMenuBtn && mobileMenuDropdown) {
mobileMenuBtn.addEventListener('click', function(e) {
e.stopPropagation();
mobileMenuDropdown.classList.toggle('hidden');
});
// 메뉴 외부 클릭 시 닫기
document.addEventListener('click', function(e) {
if (!mobileMenuDropdown.classList.contains('hidden')) {
mobileMenuDropdown.classList.add('hidden');
}
});
// 메뉴 클릭 시 닫히지 않도록
mobileMenuDropdown.addEventListener('click', function(e) {
e.stopPropagation();
});
}
// ===== 다크모드 토글 스크립트 (메인 페이지와 동일한 로직) =====
const themeToggle = document.getElementById('theme-toggle');
const themeToggleMobile = document.getElementById('theme-toggle-mobile');
const lightIcon = document.getElementById('theme-toggle-light-icon');
const darkIcon = document.getElementById('theme-toggle-dark-icon');
const lightIconMobile = document.getElementById('theme-toggle-light-icon-mobile');
const darkIconMobile = document.getElementById('theme-toggle-dark-icon-mobile');
// 저장된 테마 확인 (메인 페이지와 동일)
const savedTheme = localStorage.getItem('theme');
// 아이콘 초기 설정 함수 (메인 페이지와 동일)
function updateIcons() {
const isDark = document.documentElement.classList.contains('dark');
if (isDark) {
// 다크모드일 때 - 태양 아이콘 표시
if (lightIcon) lightIcon.classList.remove('hidden');
if (darkIcon) darkIcon.classList.add('hidden');
if (lightIconMobile) lightIconMobile.classList.remove('hidden');
if (darkIconMobile) darkIconMobile.classList.add('hidden');
} else {
// 라이트모드일 때 - 달 아이콘 표시
if (lightIcon) lightIcon.classList.add('hidden');
if (darkIcon) darkIcon.classList.remove('hidden');
if (lightIconMobile) lightIconMobile.classList.add('hidden');
if (darkIconMobile) darkIconMobile.classList.remove('hidden');
}
}
// 초기 아이콘 설정
updateIcons();
// 테마 토글 함수 (메인 페이지와 동일)
function toggleTheme() {
const isDark = document.documentElement.classList.contains('dark');
if (isDark) {
// 라이트 모드로 전환
document.documentElement.classList.remove('dark');
localStorage.setItem('theme', 'light');
} else {
// 다크 모드로 전환
document.documentElement.classList.add('dark');
localStorage.setItem('theme', 'dark');
}
updateIcons();
}
// 데스크탑 토글 버튼 클릭 이벤트 (메인 페이지와 동일)
if (themeToggle) {
themeToggle.addEventListener('click', toggleTheme);
}
// 모바일 토글 버튼 클릭 이벤트 (메인 페이지와 동일)
if (themeToggleMobile) {
themeToggleMobile.addEventListener('click', toggleTheme);
}
});
</script>
</body>
</html>