summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/administration.cpp99
-rw-r--r--src/administration.hpp39
-rw-r--r--src/locales/en.cpp12
-rw-r--r--src/views/contacts.cpp72
-rw-r--r--src/views/dashboard.cpp23
-rw-r--r--src/views/projects.cpp173
-rw-r--r--src/views/views.cpp28
-rw-r--r--src/views/views.hpp13
8 files changed, 384 insertions, 75 deletions
diff --git a/src/administration.cpp b/src/administration.cpp
index 052f007..9362b8d 100644
--- a/src/administration.cpp
+++ b/src/administration.cpp
@@ -1,3 +1,8 @@
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <time.h>
+
#include "administration.hpp"
administration g_administration;
@@ -5,12 +10,14 @@ administration g_administration;
void administration_create()
{
list_init(&g_administration.contacts);
+ list_init(&g_administration.projects);
strncpy(g_administration.path, "[unsaved project]", sizeof(g_administration.path)); // @localize
}
void administration_destroy()
{
list_destroy(&g_administration.contacts);
+ list_destroy(&g_administration.projects);
}
bool administration_create_contact(contact data)
@@ -93,4 +100,96 @@ u32 administration_get_contacts(u32 page_index, u32 page_size, contact* buffer)
char* administration_get_file_path()
{
return g_administration.path;
+}
+
+u32 administration_get_project_count()
+{
+ return list_size(&g_administration.projects);
+}
+
+u32 administration_get_projects(u32 page_index, u32 page_size, project* buffer)
+{
+ assert(buffer);
+
+ u32 write_cursor = 0;
+
+ u32 read_start = page_index * page_size;
+
+ list_iterator_start(&g_administration.projects);
+ while (list_iterator_hasnext(&g_administration.projects)) {
+ project c = *(project *)list_iterator_next(&g_administration.projects);
+
+ if (g_administration.projects.iter_pos <= read_start) continue;
+
+ buffer[write_cursor++] = c;
+ if (write_cursor >= page_size) break;
+ }
+ list_iterator_stop(&g_administration.projects);
+
+ return write_cursor;
+}
+
+void administration_cancel_project(project data)
+{
+ data.end_date = time(NULL);
+ data.state = project_state::CANCELLED;
+ administration_update_project(data);
+}
+
+char* administration_project_get_status_string(project data)
+{
+ switch(data.state)
+ {
+ case project_state::RUNNING: return "project.state.running"; break;
+ case project_state::PAUSED: return "project.state.paused"; break;
+ case project_state::CANCELLED: return "project.state.cancelled"; break;
+ }
+}
+
+bool administration_create_project(project data)
+{
+ data.state = project_state::RUNNING;
+ data.start_date = time(NULL);
+ data.end_date = 0;
+ project* new_project = (project*)malloc(sizeof(project));
+ memcpy((void*)new_project, (void*)&data, sizeof(project));
+ list_append(&g_administration.projects, new_project);
+
+ g_administration.next_id++;
+
+ return true;
+}
+
+bool administration_update_project(project data)
+{
+ list_iterator_start(&g_administration.projects);
+ while (list_iterator_hasnext(&g_administration.projects)) {
+ project* c = (project *)list_iterator_next(&g_administration.projects);
+
+ if (strcmp(c->id, data.id) == 0) {
+ memcpy(c, &data, sizeof(data));
+ list_iterator_stop(&g_administration.projects);
+ return true;
+ }
+ }
+ list_iterator_stop(&g_administration.projects);
+
+ return false;
+}
+
+bool administration_remove_project(project data)
+{
+ list_iterator_start(&g_administration.projects);
+ while (list_iterator_hasnext(&g_administration.projects)) {
+ project* c = (project *)list_iterator_next(&g_administration.projects);
+
+ if (strcmp(c->id, data.id) == 0) {
+ list_iterator_stop(&g_administration.projects);
+ list_delete(&g_administration.projects, c);
+ return true;
+ }
+ }
+ list_iterator_stop(&g_administration.projects);
+
+ return false;
} \ No newline at end of file
diff --git a/src/administration.hpp b/src/administration.hpp
index c20bbfb..9506246 100644
--- a/src/administration.hpp
+++ b/src/administration.hpp
@@ -1,10 +1,5 @@
#pragma once
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-
#include "config.hpp"
#include "simclist.h"
@@ -22,6 +17,22 @@ typedef struct
char bank_account[32];
} contact;
+typedef enum
+{
+ RUNNING,
+ PAUSED,
+ CANCELLED,
+} project_state;
+
+typedef struct
+{
+ char id[16];
+ char description[64];
+ project_state state;
+ time_t start_date;
+ time_t end_date;
+} project;
+
typedef struct
{
contact company_info;
@@ -30,7 +41,7 @@ typedef struct
char program_version[10];
char country_code[2];
list_t contacts;
- // projects
+ list_t projects;
// invoices
char ai_service[16];
char ai_key[32];
@@ -41,11 +52,19 @@ typedef struct
void administration_create();
void administration_destroy();
+char* administration_get_file_path();
+s32 administration_create_id();
+
bool administration_remove_contact(contact data);
bool administration_create_contact(contact data);
bool administration_update_contact(contact data);
-
-char* administration_get_file_path();
-s32 administration_create_id();
u32 administration_get_contact_count();
-u32 administration_get_contacts(u32 page_index, u32 page_size, contact* buffer); // Buffer size atleast be page_size * sizeof contact \ No newline at end of file
+u32 administration_get_contacts(u32 page_index, u32 page_size, contact* buffer);
+
+void administration_cancel_project(project data);
+bool administration_remove_project(project data);
+bool administration_create_project(project data);
+bool administration_update_project(project data);
+char* administration_project_get_status_string(project data);
+u32 administration_get_project_count();
+u32 administration_get_projects(u32 page_index, u32 page_size, project* buffer); \ No newline at end of file
diff --git a/src/locales/en.cpp b/src/locales/en.cpp
index de33655..2b2f2b6 100644
--- a/src/locales/en.cpp
+++ b/src/locales/en.cpp
@@ -10,7 +10,9 @@ locale_entry en_locales[] = {
{"form.change", "Change"},
{"form.view", "View"},
{"form.delete", "Delete"},
+ {"form.cancel", "Cancel"},
{"form.confirmDelete", "Are you sure you want to delete this item?"},
+ {"form.confirmCancelProject", "Are you sure you want to cancel this Project?"},
{"form.required", "required"},
// Countries
@@ -65,6 +67,16 @@ locale_entry en_locales[] = {
{"contact.table.identifier", "Identifier"},
{"contact.table.name", "Name"},
{"contact.table.address", "Address"},
+
+ // Project strings.
+ {"contact.form.identifier", "Identifier"},
+ {"project.form.description", "Description"},
+ {"project.table.identifier", "Identifier"},
+ {"project.table.status", "Status"},
+ {"project.table.description", "Description"},
+ {"project.state.running", "Running"},
+ {"project.state.cancelled", "Cancelled"},
+ {"project.state.paused", "Paused"},
};
const int en_locale_count = sizeof(en_locales) / sizeof(en_locales[0]); \ No newline at end of file
diff --git a/src/views/contacts.cpp b/src/views/contacts.cpp
index 4b352bc..31f95e3 100644
--- a/src/views/contacts.cpp
+++ b/src/views/contacts.cpp
@@ -3,56 +3,26 @@
#include "views.hpp"
#include "imgui.h"
#include "../administration.hpp"
+#include "../locales/locales.hpp"
-typedef enum {
- LIST,
- EDIT,
- CREATE,
- VIEW,
-} contact_view_state;
-
-static contact_view_state view_state = LIST;
+static view_state current_view_state = LIST;
static contact selected_for_removal;
static contact active_contact;
-static void draw_required_tag()
-{
- ImDrawList* draw_list = ImGui::GetWindowDrawList();
-
- const char* text = localize("form.required");
- ImVec2 text_pos = ImGui::GetCursorScreenPos();
- ImVec2 text_size = ImGui::CalcTextSize(text);
- text_pos.y += text_size.y/4.0f;
-
- ImVec4 bg_color = ImVec4(0.9f, 0.235f, 0.235f, 0.4f); // Red background
- ImVec4 text_color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // White text
- float rounding = 2.0f;
- float padding = 2.0f;
-
- // Background rectangle
- ImVec2 bg_min = ImVec2(text_pos.x - padding, text_pos.y - padding);
- ImVec2 bg_max = ImVec2(text_pos.x + text_size.x + padding, text_pos.y + text_size.y + padding);
- draw_list->AddRectFilled(bg_min, bg_max, ImColor(bg_color), rounding);
-
- // Foreground text
- ImGui::PushStyleColor(ImGuiCol_Text, text_color);
- ImGui::TextUnformatted(text);
- ImGui::PopStyleColor();
-}
-
static void draw_contact_form()
{
static const char* selected_country = NULL;
if (ImGui::Button(localize("form.back"))) {
- view_state = contact_view_state::LIST;
+ current_view_state = view_state::LIST;
memset(&active_contact, 0, sizeof(contact));
selected_country = 0;
+ return;
}
ImGui::Spacing();
- bool viewing_only = (view_state == contact_view_state::VIEW);
+ bool viewing_only = (current_view_state == view_state::VIEW);
ImGui::BeginDisabled();
@@ -64,15 +34,15 @@ static void draw_contact_form()
ImGui::SetNextItemWidth(widthAvailable*0.5f);
ImGui::InputTextWithHint(localize("contact.form.fullname"), localize("contact.form.fullname"), active_contact.name, IM_ARRAYSIZE(active_contact.name));
- ImGui::SameLine();draw_required_tag();
+ ImGui::SameLine();view_draw_required_tag();
ImGui::SetNextItemWidth(widthAvailable*0.5f);
ImGui::InputTextWithHint(localize("contact.form.address1"), localize("contact.form.address1"), active_contact.address1, IM_ARRAYSIZE(active_contact.address1));
- ImGui::SameLine();draw_required_tag();
+ ImGui::SameLine();view_draw_required_tag();
ImGui::SetNextItemWidth(widthAvailable*0.5f);
ImGui::InputTextWithHint(localize("contact.form.address2"), localize("contact.form.address2"), active_contact.address2, IM_ARRAYSIZE(active_contact.address2));
- ImGui::SameLine();draw_required_tag();
+ ImGui::SameLine();view_draw_required_tag();
ImGui::SetNextItemWidth(widthAvailable*0.5f);
@@ -102,7 +72,7 @@ static void draw_contact_form()
if (selected_country) {
strncpy(active_contact.country, selected_country, IM_ARRAYSIZE(active_contact.country));
}
- ImGui::SameLine();draw_required_tag();
+ ImGui::SameLine();view_draw_required_tag();
ImGui::SetNextItemWidth(widthAvailable*0.5f);
ImGui::InputTextWithHint(localize("contact.form.taxnumber"), localize("contact.form.taxnumber"), active_contact.taxid, IM_ARRAYSIZE(active_contact.taxid));
@@ -129,14 +99,14 @@ static void draw_contact_form()
// Save button
ImGui::Spacing();
if (ImGui::Button(localize("form.save"))) {
- if (view_state == contact_view_state::CREATE)
+ if (current_view_state == view_state::CREATE)
administration_create_contact(active_contact);
- else if (view_state == contact_view_state::EDIT)
+ else if (current_view_state == view_state::EDIT)
administration_update_contact(active_contact);
memset(&active_contact, 0, sizeof(contact));
- view_state = contact_view_state::LIST;
+ current_view_state = view_state::LIST;
selected_country = 0;
}
if (!can_save) ImGui::EndDisabled();
@@ -148,14 +118,14 @@ static void draw_contact_form()
static void draw_contact_list()
{
- const u32 items_per_page = 5;
+ const u32 items_per_page = 50;
static s32 current_page = 0;
s32 max_page = (administration_get_contact_count() + items_per_page - 1) / items_per_page;
if (max_page == 0) max_page = 1;
if (ImGui::Button(localize("form.create")))
{
- view_state = contact_view_state::CREATE;
+ current_view_state = view_state::CREATE;
memset(&active_contact, 0, sizeof(contact));
snprintf(active_contact.id, IM_ARRAYSIZE(active_contact.id), "C/%d", administration_create_id());
}
@@ -205,7 +175,7 @@ static void draw_contact_list()
sprintf(btn_name, "%s##%d", localize("form.view"), i);
if (ImGui::Button(btn_name)) {
active_contact = c;
- view_state = contact_view_state::VIEW;
+ current_view_state = view_state::VIEW;
}
ImGui::SameLine();
@@ -213,7 +183,7 @@ static void draw_contact_list()
sprintf(btn_name, "%s##%d", localize("form.change"), i);
if (ImGui::Button(btn_name)) {
active_contact = c;
- view_state = contact_view_state::EDIT;
+ current_view_state = view_state::EDIT;
}
ImGui::SameLine();
@@ -247,11 +217,11 @@ static void draw_contact_list()
void views_draw_contacts()
{
- switch(view_state)
+ switch(current_view_state)
{
- case contact_view_state::LIST: draw_contact_list(); break;
- case contact_view_state::CREATE: draw_contact_form(); break;
- case contact_view_state::EDIT: draw_contact_form(); break;
- case contact_view_state::VIEW: draw_contact_form(); break;
+ case view_state::LIST: draw_contact_list(); break;
+ case view_state::CREATE: draw_contact_form(); break;
+ case view_state::EDIT: draw_contact_form(); break;
+ case view_state::VIEW: draw_contact_form(); break;
}
} \ No newline at end of file
diff --git a/src/views/dashboard.cpp b/src/views/dashboard.cpp
index 86dc18f..dcfd002 100644
--- a/src/views/dashboard.cpp
+++ b/src/views/dashboard.cpp
@@ -1,6 +1,7 @@
#include "views.hpp"
#include "imgui.h"
#include "../administration.hpp"
+#include "../locales/locales.hpp"
typedef enum
{
@@ -14,14 +15,14 @@ typedef enum
END
} dashboard_view_state;
-static dashboard_view_state view_state = dashboard_view_state::INVOICES;
+static dashboard_view_state dashboard_state = dashboard_view_state::INVOICES;
void (*drawcalls[dashboard_view_state::END])(void) = {
0,
0,
views_draw_contacts,
0,
0,
- 0,
+ views_draw_projects,
};
void views_draw_dashboard()
@@ -58,21 +59,21 @@ void views_draw_dashboard()
float buttonWidth = sidePanelWidth;
- if (ImGui::Button(localize("nav.invoices"), ImVec2(buttonWidth, 24))) view_state = dashboard_view_state::INVOICES;
- if (ImGui::Button(localize("nav.expenses"), ImVec2(buttonWidth, 24))) view_state = dashboard_view_state::EXPENSES;
- if (ImGui::Button(localize("nav.contacts"), ImVec2(buttonWidth, 24))) view_state = dashboard_view_state::CONTACTS;
+ if (ImGui::Button(localize("nav.invoices"), ImVec2(buttonWidth, 24))) dashboard_state = dashboard_view_state::INVOICES;
+ if (ImGui::Button(localize("nav.expenses"), ImVec2(buttonWidth, 24))) dashboard_state = dashboard_view_state::EXPENSES;
+ if (ImGui::Button(localize("nav.contacts"), ImVec2(buttonWidth, 24))) dashboard_state = dashboard_view_state::CONTACTS;
static bool reports_opened = false;
if (ImGui::Button(localize("nav.reports"), ImVec2(buttonWidth, 24))) reports_opened = !reports_opened;
if (reports_opened)
{
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(20.0f, 0.0f));
- if (ImGui::Button(localize("nav.reports.results"), ImVec2(buttonWidth, 24))) view_state = dashboard_view_state::REPORT_RESULTS;
- if (ImGui::Button(localize("nav.reports.tax"), ImVec2(buttonWidth, 24))) view_state = dashboard_view_state::REPORT_TAX;
+ if (ImGui::Button(localize("nav.reports.results"), ImVec2(buttonWidth, 24))) dashboard_state = dashboard_view_state::REPORT_RESULTS;
+ if (ImGui::Button(localize("nav.reports.tax"), ImVec2(buttonWidth, 24))) dashboard_state = dashboard_view_state::REPORT_TAX;
ImGui::PopStyleVar();
}
- if (ImGui::Button(localize("nav.Projects"), ImVec2(buttonWidth, 24))) view_state = dashboard_view_state::PROJECTS;
+ if (ImGui::Button(localize("nav.Projects"), ImVec2(buttonWidth, 24))) dashboard_state = dashboard_view_state::PROJECTS;
ImGui::PopStyleColor(1);
ImGui::PopStyleVar(3);
@@ -85,7 +86,7 @@ void views_draw_dashboard()
// Main content
ImGui::Begin("AccountingMainWindow", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse);
- if (drawcalls[view_state]) drawcalls[view_state]();
+ if (drawcalls[dashboard_state]) drawcalls[dashboard_state]();
ImGui::End();
// Status bar.
@@ -102,9 +103,7 @@ void views_draw_dashboard()
ImGuiWindowFlags_NoBringToFrontOnFocus |
ImGuiWindowFlags_NoCollapse);
- ImGui::Text("Working on: %s", administration_get_file_path());
- ImGui::SameLine();
- ImGui::Text("Status: []");
+ ImGui::Text("Working on: %s", administration_get_file_path()); // @localize
ImGui::End();
ImGui::PopStyleVar();
diff --git a/src/views/projects.cpp b/src/views/projects.cpp
new file mode 100644
index 0000000..14f99c9
--- /dev/null
+++ b/src/views/projects.cpp
@@ -0,0 +1,173 @@
+#include <stdio.h>
+
+#include "views.hpp"
+#include "imgui.h"
+#include "../administration.hpp"
+#include "../locales/locales.hpp"
+
+static view_state current_view_state = LIST;
+static project selected_for_cancellation;
+
+static project active_project;
+
+static void draw_project_form()
+{
+ static const char* selected_country = NULL;
+
+ if (ImGui::Button(localize("form.back"))) {
+ current_view_state = view_state::LIST;
+ memset(&active_project, 0, sizeof(project));
+ selected_country = 0;
+ return;
+ }
+ ImGui::Spacing();
+
+ bool viewing_only = (current_view_state == view_state::VIEW);
+
+ ImGui::BeginDisabled();
+
+ float widthAvailable = ImGui::GetContentRegionAvail().x;
+
+ ImGui::SetNextItemWidth(widthAvailable*0.2f);
+ ImGui::InputText(localize("contact.form.identifier"), active_project.id, IM_ARRAYSIZE(active_project.id));
+ if (!viewing_only) ImGui::EndDisabled();
+
+ ImGui::SetNextItemWidth(widthAvailable*0.5f);
+ ImGui::InputTextWithHint(localize("project.form.description"), localize("project.form.description"), active_project.description, IM_ARRAYSIZE(active_project.description));
+ ImGui::SameLine();view_draw_required_tag();
+
+ if (viewing_only) ImGui::EndDisabled();
+
+ if (!viewing_only) {
+ bool can_save = strlen(active_project.description) > 0;
+
+ if (!can_save) ImGui::BeginDisabled();
+ // Save button
+ ImGui::Spacing();
+ if (ImGui::Button(localize("form.save"))) {
+ if (current_view_state == view_state::CREATE)
+ administration_create_project(active_project);
+
+ else if (current_view_state == view_state::EDIT)
+ administration_update_project(active_project);
+
+ memset(&active_project, 0, sizeof(project));
+ current_view_state = view_state::LIST;
+ selected_country = 0;
+ }
+ if (!can_save) ImGui::EndDisabled();
+ }
+ else {
+ // TODO list invoices connected to project.
+ }
+}
+
+static void draw_project_list()
+{
+ const u32 items_per_page = 50;
+ static s32 current_page = 0;
+ s32 max_page = (administration_get_project_count() + items_per_page - 1) / items_per_page;
+ if (max_page == 0) max_page = 1;
+
+ if (ImGui::Button(localize("form.create")))
+ {
+ current_view_state = view_state::CREATE;
+ memset(&active_project, 0, sizeof(project));
+ snprintf(active_project.id, IM_ARRAYSIZE(active_project.id), "P/%d", administration_create_id());
+ }
+
+ if (current_page >= max_page-1) current_page = max_page-1;
+ if (current_page < 0) current_page = 0;
+
+ ImGui::SameLine();
+ bool enable_prev = current_page > 0;
+ if (!enable_prev) ImGui::BeginDisabled();
+ if (ImGui::Button("<< Prev") && current_page > 0) current_page--;
+ if (!enable_prev) ImGui::EndDisabled();
+
+ ImGui::SameLine();
+ ImGui::Text("(%d/%d)", current_page+1, max_page);
+
+ ImGui::SameLine();
+ bool enable_next = current_page < max_page-1;
+ if (!enable_next) ImGui::BeginDisabled();
+ if (ImGui::Button("Next >>") && current_page < max_page-1) current_page++;
+ if (!enable_next) ImGui::EndDisabled();
+
+ ImGui::Spacing();
+
+ if (ImGui::BeginTable("TableProjects", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
+
+ ImGui::TableSetupColumn(localize("project.table.identifier"), ImGuiTableColumnFlags_WidthFixed, 80);
+ ImGui::TableSetupColumn(localize("project.table.status"), ImGuiTableColumnFlags_WidthFixed, 140);
+ ImGui::TableSetupColumn(localize("project.table.description"), ImGuiTableColumnFlags_WidthStretch);
+ ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 160);
+ ImGui::TableHeadersRow();
+
+ project project_list[items_per_page];
+ u32 project_count = administration_get_projects(current_page, items_per_page, project_list);
+
+ for (u32 i = 0; i < project_count; i++) {
+ project c = project_list[i];
+
+ ImGui::TableNextRow();
+ ImGui::TableSetColumnIndex(0); ImGui::Text(c.id);
+ ImGui::TableSetColumnIndex(1); ImGui::Text(localize(administration_project_get_status_string(c)));
+ ImGui::TableSetColumnIndex(2); ImGui::Text(c.description);
+
+ ImGui::TableSetColumnIndex(3);
+
+ char btn_name[20];
+ sprintf(btn_name, "%s##%d", localize("form.view"), i);
+ if (ImGui::Button(btn_name)) {
+ active_project = c;
+ current_view_state = view_state::VIEW;
+ }
+
+ if (c.state == project_state::RUNNING)
+ {
+ ImGui::SameLine();
+ sprintf(btn_name, "%s##%d", localize("form.change"), i);
+ if (ImGui::Button(btn_name)) {
+ active_project = c;
+ current_view_state = view_state::EDIT;
+ }
+
+ ImGui::SameLine();
+ sprintf(btn_name, "%s##%d", localize("form.cancel"), i);
+ if (ImGui::Button(btn_name)) {
+ selected_for_cancellation = c;
+ ImGui::OpenPopup("ConfirmCancelProject");
+ }
+ }
+ }
+
+ if (ImGui::BeginPopupModal("ConfirmCancelProject", nullptr, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoTitleBar)) {
+ ImGui::Text(localize("form.confirmCancelProject"));
+ ImGui::Separator();
+
+ if (ImGui::Button(localize("form.yes"), ImVec2(120, 0))) {
+ administration_cancel_project(selected_for_cancellation);
+ ImGui::CloseCurrentPopup();
+ }
+ ImGui::SameLine();
+ if (ImGui::Button(localize("form.no"), ImVec2(120, 0))) {
+ ImGui::CloseCurrentPopup();
+ }
+ ImGui::EndPopup();
+ }
+
+ ImGui::EndTable();
+ }
+}
+
+void views_draw_projects()
+{
+ switch(current_view_state)
+ {
+ case view_state::LIST: draw_project_list(); break;
+ case view_state::CREATE: draw_project_form(); break;
+ case view_state::EDIT: draw_project_form(); break;
+ case view_state::VIEW: draw_project_form(); break;
+ }
+} \ No newline at end of file
diff --git a/src/views/views.cpp b/src/views/views.cpp
new file mode 100644
index 0000000..47eff34
--- /dev/null
+++ b/src/views/views.cpp
@@ -0,0 +1,28 @@
+#include "views.hpp"
+#include "imgui.h"
+#include "../locales/locales.hpp"
+
+void view_draw_required_tag()
+{
+ ImDrawList* draw_list = ImGui::GetWindowDrawList();
+
+ const char* text = localize("form.required");
+ ImVec2 text_pos = ImGui::GetCursorScreenPos();
+ ImVec2 text_size = ImGui::CalcTextSize(text);
+ text_pos.y += text_size.y/4.0f;
+
+ ImVec4 bg_color = ImVec4(0.9f, 0.235f, 0.235f, 0.4f); // Red background
+ ImVec4 text_color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // White text
+ float rounding = 2.0f;
+ float padding = 2.0f;
+
+ // Background rectangle
+ ImVec2 bg_min = ImVec2(text_pos.x - padding, text_pos.y - padding);
+ ImVec2 bg_max = ImVec2(text_pos.x + text_size.x + padding, text_pos.y + text_size.y + padding);
+ draw_list->AddRectFilled(bg_min, bg_max, ImColor(bg_color), rounding);
+
+ // Foreground text
+ ImGui::PushStyleColor(ImGuiCol_Text, text_color);
+ ImGui::TextUnformatted(text);
+ ImGui::PopStyleColor();
+} \ No newline at end of file
diff --git a/src/views/views.hpp b/src/views/views.hpp
index 2ebdedd..f47bf3a 100644
--- a/src/views/views.hpp
+++ b/src/views/views.hpp
@@ -1,6 +1,15 @@
#pragma once
-#include "../locales/locales.hpp"
+typedef enum
+{
+ LIST,
+ EDIT,
+ CREATE,
+ VIEW,
+} view_state;
+
+void view_draw_required_tag();
void views_draw_dashboard();
-void views_draw_contacts(); \ No newline at end of file
+void views_draw_contacts();
+void views_draw_projects(); \ No newline at end of file