// panel_calendar.cpp — MVP monthly calendar view. // // Renders a simple 7-column grid for the current month with cards bucketed // by `due_date`. No navigation, no editing — that's tracked as TODO in // app.md ## Gotchas. #include "panels.h" #include "core/icons_tabler.h" #include #include #include namespace kanban_cpp { void draw_calendar(AppState& s, bool* p_open) { if (!ImGui::Begin(TI_CALENDAR " Calendar", p_open)) { ImGui::End(); return; } std::time_t now = std::time(nullptr); std::tm tm_now; #ifdef _WIN32 localtime_s(&tm_now, &now); #else localtime_r(&now, &tm_now); #endif // Heading static const char* months[] = {"Enero","Febrero","Marzo","Abril","Mayo","Junio", "Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"}; ImGui::Text("%s %d", months[tm_now.tm_mon], tm_now.tm_year + 1900); ImGui::TextDisabled("(MVP estatico — TODO: navegacion + filtros)"); ImGui::Separator(); std::vector cards_snap; { std::lock_guard lock(s.mu); cards_snap = s.cards; } // First day of current month + days in month std::tm tm_first = tm_now; tm_first.tm_mday = 1; std::mktime(&tm_first); int first_wday = tm_first.tm_wday; // 0 = Sunday int first_wday_mon = (first_wday + 6) % 7; // 0 = Monday (ES convention) int days_in_month = 31; { std::tm tm_test = tm_now; tm_test.tm_mday = 32; std::mktime(&tm_test); days_in_month = 32 - tm_test.tm_mday; } // Grid 7 cols if (ImGui::BeginTable("##cal", 7, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingStretchSame)) { const char* wdays[] = {"L","M","X","J","V","S","D"}; for (int i = 0; i < 7; ++i) ImGui::TableSetupColumn(wdays[i]); ImGui::TableHeadersRow(); int day = 1; int total_cells = first_wday_mon + days_in_month; int rows = (total_cells + 6) / 7; int cell_index = 0; for (int r = 0; r < rows; ++r) { ImGui::TableNextRow(); for (int c = 0; c < 7; ++c) { ImGui::TableSetColumnIndex(c); if (cell_index < first_wday_mon || day > days_in_month) { ImGui::TextDisabled(" "); } else { ImGui::Text("%d", day); // Count cards whose due_date falls in this day. int hits = 0; for (const auto& card : cards_snap) { if (card.due_date == 0) continue; std::time_t cd = (std::time_t)card.due_date; std::tm tmc; #ifdef _WIN32 localtime_s(&tmc, &cd); #else localtime_r(&cd, &tmc); #endif if (tmc.tm_year == tm_now.tm_year && tmc.tm_mon == tm_now.tm_mon && tmc.tm_mday == day) ++hits; } if (hits > 0) ImGui::TextColored(ImVec4(0.6f, 0.55f, 0.95f, 1.0f), TI_FLAG " %d", hits); ++day; } ++cell_index; } } ImGui::EndTable(); } ImGui::End(); } } // namespace kanban_cpp