최초 커밋

This commit is contained in:
root
2026-07-23 16:15:57 +09:00
commit c8f5efb6b7
14652 changed files with 4812531 additions and 0 deletions
+545
View File
@@ -0,0 +1,545 @@
<?php
$pdo = new PDO("mysql:host=localhost;dbname=egbim;charset=utf8mb4","egbim","baron3840!!");
$rows = $pdo->query("
SELECT
s.schedule_date,
s.time_period,
s.content,
s.emp_no,
m.emp_name,
c.client_name
FROM sales_schedules s
LEFT JOIN sales_members m ON s.emp_no = m.emp_no
LEFT JOIN sales_clients c ON s.client_code = c.client_code
")->fetchAll(PDO::FETCH_ASSOC);
// 모든 emp_no는 소문자로 통일!
$tagMap = [
"j01201" => "",
"223070" => "",
"m21430" => "",
"b21367" => ""
];
$eventsData = [];
foreach ($rows as $r) {
$date = $r["schedule_date"];
$empNo = strtolower($r["emp_no"]); // ★ emp_no를 소문자로 통일
// 날짜 키가 없으면 배열 초기화
if (!isset($eventsData[$date])) {
$eventsData[$date] = [];
}
// 여러 개가 정상적으로 PUSH됨
$eventsData[$date][] = [
"time" => $r["time_period"],
"title" => $r["content"],
"tags" => [ $tagMap[$empNo] ?? "" ]
];
}
echo "<script>var eventsData = " . json_encode($eventsData, JSON_UNESCAPED_UNICODE) . ";</script>";
?>
<div id="scheduleModal" class="modal calendar">
<div class="modal-content">
<div class="modal-header">
<div class="filter-options">
<div class="checkbox-group green">
<input type="checkbox" id="check1" value="green" checked />
<label for="check1">권혁진 수석</label>
</div>
<div class="checkbox-group purple">
<input type="checkbox" id="check2" value="purple" checked />
<label for="check2">염승호 수석</label>
</div>
<div class="checkbox-group teal">
<input type="checkbox" id="check3" value="teal" checked />
<label for="check3">김지영 선임</label>
</div>
<div class="checkbox-group black">
<input type="checkbox" id="check4" value="black" checked />
<label for="check4">윤준수 선임</label>
</div>
</div>
<div class="date-navigation">
<button class="prev-btn" id="prevMonth"></button>
<div class="current-date" id="currentDate">2025.11</div>
<button class="next-btn" id="nextMonth"></button>
</div>
<div class="flex">
<div class="toggle-area">
<input type="radio" id="option1" name="toggle" value="접기" checked />
<label for="option1">접기</label>
<input type="radio" id="option2" name="toggle" value="펼치기" />
<label for="option2">펼치기</label>
<div class="toggle-slider"></div>
</div>
<button class="modal-close" onclick="closeModal()">&times;</button>
</div>
</div>
<div class="modal-body" id="modalBody">
<div class="weekdays">
<div class="weekday">일</div>
<div class="weekday">월</div>
<div class="weekday">화</div>
<div class="weekday">수</div>
<div class="weekday">목</div>
<div class="weekday">금</div>
<div class="weekday">토</div>
</div>
<div class="calendar-days">
<div class="days collapsed" id="calendarDays"></div>
</div>
</div>
</div>
<script>
// 모달 배경 클릭시 닫기
const modal = document.getElementById("scheduleModal");
modal.addEventListener("click", function (e) {
if (e.target === modal) {
closeModal();
}
});
</script>
<script>
function initializeCalendar() {
const tagMapping = {
"권": "green",
"염": "purple",
"김": "teal",
"윤": "black"
};
// 사람 고정 순서 (우선순위 낮을수록 뒤로)
const PERSON_ORDER = {
"권": 1, // 권혁진
"염": 2, // 염승호
"김": 3, // 김지영
"윤": 4 // 윤준수
};
function sortEventsByPerson(events) {
return events.slice().sort((a, b) => {
const aTag = a.tags[0] || "";
const bTag = b.tags[0] || "";
return (PERSON_ORDER[aTag] || 99) - (PERSON_ORDER[bTag] || 99);
});
}
/* ===============================
오전 / 오후 판별 (핵심)
→ title 문자열 기준
=============================== */
function isMorning(event) {
return event.time === "오전";
}
function isAfternoon(event) {
return event.time === "오후";
}
const today = new Date();
let currentYear = today.getFullYear(); // 2025 대신
let currentMonth = today.getMonth(); // 11 대신
let selectedFilters = ["green", "purple", "teal", "black"];
function renderCalendar() {
const calendarDays = document.getElementById("calendarDays");
const currentDate = document.getElementById("currentDate");
currentDate.textContent = `${currentYear}.${String(currentMonth + 1).padStart(2, "0")}`;
const firstDay = new Date(currentYear, currentMonth, 1);
const lastDay = new Date(currentYear, currentMonth + 1, 0);
const prevLastDay = new Date(currentYear, currentMonth, 0);
const firstDayOfWeek = firstDay.getDay();
const lastDate = lastDay.getDate();
const prevLastDate = prevLastDay.getDate();
// 오늘 날짜의 주차 계산
const today = new Date();
let todayWeekStart = -1;
let todayWeekEnd = -1;
// 현재 달력에 오늘이 포함되어 있는지 확인
if (
currentMonth === today.getMonth() &&
currentYear === today.getFullYear()
) {
const todayDate = today.getDate();
const currentDate = new Date(currentYear, currentMonth, todayDate);
const dayOfWeek = currentDate.getDay();
// 이번 주의 시작(일요일)과 끝(토요일) 날짜 계산
todayWeekStart = todayDate - dayOfWeek;
todayWeekEnd = todayDate + (6 - dayOfWeek);
}
let weeks = "";
let currentWeekDays = "";
let dayCount = 0;
let weekNumber = 0;
// Previous month days
const prevMonth = currentMonth === 0 ? 11 : currentMonth - 1;
const prevYear = currentMonth === 0 ? currentYear - 1 : currentYear;
for (let i = firstDayOfWeek - 1; i >= 0; i--) {
const dayNum = prevLastDate - i;
const dateKey = `${prevYear}-${String(prevMonth + 1).padStart(2, "0")}-${String(dayNum).padStart(2, "0")}`;
const dayEvents = eventsData[dateKey] || [];
const filteredEvents = sortEventsByPerson(
dayEvents.filter((event) =>
event.tags.some((tag) => selectedFilters.includes(tagMapping[tag]))
)
);
let morningHtml = "";
let afternoonHtml = "";
filteredEvents.forEach((event) => {
const tagsHtml = event.tags
.filter((tag) => selectedFilters.includes(tagMapping[tag]))
.map(
(tag) =>
`<span class="event-tag badge-${tagMapping[tag]}">${tag}</span>`
)
.join("");
const html = `
<div class="event-item">
<span class="event-title">${tagsHtml}${event.title}</span>
</div>
`;
if (isMorning(event)) {
morningHtml += html;
}
if (isAfternoon(event)) {
afternoonHtml += html;
}
});
currentWeekDays += `<div class="day other-month">
<div class="day-number">${dayNum}</div>
<dl>
<dt>오전</dt>
<dd class="day-content">${morningHtml}</dd>
</dl>
<dl>
<dt>오후</dt>
<dd class="day-content">${afternoonHtml}</dd>
</dl>
</div>`;
dayCount++;
}
// Current month days
for (let i = 1; i <= lastDate; i++) {
const isToday =
i === today.getDate() &&
currentMonth === today.getMonth() &&
currentYear === today.getFullYear();
const isCurrentWeek =
todayWeekStart >= 0 && i >= todayWeekStart && i <= todayWeekEnd;
const dateKey = `${currentYear}-${String(currentMonth + 1).padStart(2, "0")}-${String(i).padStart(2, "0")}`;
const dayEvents = eventsData[dateKey] || [];
const filteredEvents = sortEventsByPerson(
dayEvents.filter((event) =>
event.tags.some((tag) => selectedFilters.includes(tagMapping[tag]))
)
);
filteredEvents.forEach((event) => {
console.log(event.title);
});
let morningHtml = "";
let afternoonHtml = "";
filteredEvents.forEach((event) => {
const tagsHtml = event.tags
.filter((tag) => selectedFilters.includes(tagMapping[tag]))
.map(
(tag) =>
`<span class="event-tag badge-${tagMapping[tag]}">${tag}</span>`
)
.join("");
const html = `
<div class="event-item">
<span class="event-title">${tagsHtml}${event.title}</span>
</div>
`;
if (isMorning(event)) {
morningHtml += html;
}
if (isAfternoon(event)) {
afternoonHtml += html;
}
});
currentWeekDays += `<div class="day ${isToday ? "today" : ""} ${isCurrentWeek ? "current-week" : ""}">
<div class="day-number">${i}</div>
<dl>
<dt>오전</dt>
<dd class="day-content">${morningHtml}</dd>
</dl>
<dl>
<dt>오후</dt>
<dd class="day-content">${afternoonHtml}</dd>
</dl>
</div>`;
dayCount++;
// 7일마다 한 주 완성
if (dayCount === 7) {
const hasCurrentWeek =
currentWeekDays.includes('class="day today"') ||
currentWeekDays.includes("current-week");
weeks += `<div class="week ${hasCurrentWeek ? "current-week-row" : ""}">${currentWeekDays}</div>`;
currentWeekDays = "";
dayCount = 0;
weekNumber++;
}
}
// Next month days
const nextMonth = currentMonth === 11 ? 0 : currentMonth + 1;
const nextYear = currentMonth === 11 ? currentYear + 1 : currentYear;
const remainingDays = 42 - (firstDayOfWeek + lastDate);
for (let i = 1; i <= remainingDays; i++) {
const dateKey = `${nextYear}-${String(nextMonth + 1).padStart(2, "0")}-${String(i).padStart(2, "0")}`;
const dayEvents = eventsData[dateKey] || [];
const filteredEvents = sortEventsByPerson(
dayEvents.filter((event) =>
event.tags.some((tag) => selectedFilters.includes(tagMapping[tag]))
)
);
let morningHtml = "";
let afternoonHtml = "";
filteredEvents.forEach((event) => {
const tagsHtml = event.tags
.filter((tag) => selectedFilters.includes(tagMapping[tag]))
.map(
(tag) =>
`<span class="event-tag badge-${tagMapping[tag]}">${tag}</span>`
)
.join("");
const html = `
<div class="event-item">
<span class="event-title">${tagsHtml}${event.title}</span>
</div>
`;
if (isMorning(event)) morningHtml += html;
if (isAfternoon(event)) afternoonHtml += html;
});
currentWeekDays += `<div class="day other-month">
<div class="day-number">${i}</div>
<dl>
<dt>오전</dt>
<dd class="day-content">${morningHtml}</dd>
</dl>
<dl>
<dt>오후</dt>
<dd class="day-content">${afternoonHtml}</dd>
</dl>
</div>`;
dayCount++;
// 7일마다 한 주 완성
if (dayCount === 7) {
weeks += `<div class="week">${currentWeekDays}</div>`;
currentWeekDays = "";
dayCount = 0;
}
}
calendarDays.innerHTML = weeks;
document.querySelectorAll(".day:not(.other-month)").forEach((day) => {
day.addEventListener("click", function () {
document
.querySelectorAll(".day")
.forEach((d) => d.classList.remove("selected"));
this.classList.add("selected");
});
});
}
function checkOverflow() {
const calendarDaysEl = document.getElementById("calendarDays");
if (!calendarDaysEl.classList.contains("collapsed")) return;
document.querySelectorAll(".day-content").forEach((content) => {
// 스크롤 높이가 실제 높이보다 크면 overflow 발생
if (content.scrollHeight > content.clientHeight) {
content.classList.add("has-overflow");
} else {
content.classList.remove("has-overflow");
}
});
}
// document.getElementById("prevMonth").addEventListener("click", () => {
// currentMonth--;
// if (currentMonth < 0) {
// currentMonth = 11;
// currentYear--;
// }
// renderCalendar();
// checkOverflow();
// });
// document.getElementById("nextMonth").addEventListener("click", () => {
// currentMonth++;
// if (currentMonth > 11) {
// currentMonth = 0;
// currentYear++;
// }
// renderCalendar();
// checkOverflow();
// });
// 필터 체크박스
const filterCheckboxes = document.querySelectorAll(
'.filter-options input[type="checkbox"]',
);
filterCheckboxes.forEach((checkbox) => {
checkbox.addEventListener("change", () => {
selectedFilters = Array.from(filterCheckboxes)
.filter((cb) => cb.checked)
.map((cb) => cb.value);
renderCalendar();
checkOverflow();
});
});
// 접기/펼치기 토글
const calendarDaysEl = document.getElementById("calendarDays");
const toggleRadios = document.querySelectorAll('input[name="toggle"]');
toggleRadios.forEach((radio) => {
radio.addEventListener("change", (e) => {
if (e.target.value === "접기") {
calendarDaysEl.classList.add("collapsed");
} else {
calendarDaysEl.classList.remove("collapsed");
}
});
});
calendarDaysEl.classList.add("collapsed");
renderCalendar();
checkOverflow();
bindCalendarEvents();
//바인드 함수 컨트롤
function bindCalendarEvents() {
// 이전 월
const prevBtn = document.getElementById("prevMonth");
if (prevBtn) {
prevBtn.onclick = () => {
currentMonth--;
if (currentMonth < 0) {
currentMonth = 11;
currentYear--;
}
renderCalendar();
checkOverflow();
};
}
// 다음 월
const nextBtn = document.getElementById("nextMonth");
if (nextBtn) {
nextBtn.onclick = () => {
currentMonth++;
if (currentMonth > 11) {
currentMonth = 0;
currentYear++;
}
renderCalendar();
checkOverflow();
};
}
// 필터 체크박스
const filterCheckboxes = document.querySelectorAll('.filter-options input[type="checkbox"]');
filterCheckboxes.forEach((checkbox) => {
checkbox.onclick = () => {
selectedFilters = Array.from(filterCheckboxes)
.filter((cb) => cb.checked)
.map((cb) => cb.value);
renderCalendar();
checkOverflow();
};
});
// 접기&펼치기 토글
const radios = document.querySelectorAll('input[name="toggle"]');
radios.forEach((radio) => {
radio.addEventListener("change", (e) => {
const calendarDaysEl = document.getElementById("calendarDays");
if (e.target.value === "접기") {
calendarDaysEl.classList.add("collapsed");
} else {
calendarDaysEl.classList.remove("collapsed");
// 스크롤을 맨 아래로 이동
setTimeout(() => {
const scheduleList = document.querySelector(".calendar-days");
const scheduleItem = document.querySelector(".current-week-row");
if (scheduleList && scheduleItem) {
// 현재 주가 보이도록 + 살짝 아래로 여유 있게
scheduleList.scrollTo({
top:
scheduleItem.offsetTop -
scheduleList.offsetHeight / 2 +
scheduleItem.offsetHeight / 2,
// 또는 그냥 맨 아래로 내리고 싶으면:
// top: scheduleList.scrollHeight,
behavior: "smooth",
});
}
}, 100);
}
});
});
}
}
// 모달이 로드되면 자동 실행
initializeCalendar();
</script>
</div>