fully featured address book is complete

This commit is contained in:
Greg Gauthier 2025-05-10 13:27:13 +01:00
parent ab9b3c208a
commit e10a6aeb5a
3 changed files with 276 additions and 56 deletions

View File

@ -88,7 +88,7 @@
self~addPhoneNumber(contactId, contactDict["PHONE_TYPE"], contactDict["PHONE_NUMBER"])
self~addEmailAddress(contactId, contactDict["EMAIL_TYPE"], contactDict["EMAIL_ADDRESS"])
/* contactId, addressType, street, city, state, postalCode, country */
self~addRealAddress(contactId, "NA", contactDict~street, contactDict~city, contactDict~state, contactDict~postCode, "NA")
self~addRealAddress(contactId, "NA", contactDict~street, contactDict~city, contactDict~state, contactDict~postCode, contactDict~country)
return contactId
::METHOD getContact
@ -213,13 +213,16 @@
***********************/
::METHOD updateContact
expose db
use arg contactId, firstName, lastName
sql = "UPDATE contacts SET first_name = '"firstName"', last_name = '"lastName"' WHERE id = "contactId
rc = db~exec(sql)
if rc \= 0 then do
say "Error updating contact:" db~errMsg()
return -1
end
use arg contactId, contactDict
rc = 0
sql1 = "UPDATE contacts SET first_name = '"contactDict~first_Name"', last_name = '"contactDict~last_Name"' WHERE id = "contactId
rc = db~exec(sql1)
sql2 = "UPDATE phone_numbers SET number = '"contactDict~phone_number"', type = '"contactDict~phone_type"' WHERE contact_id = "contactId
rc = db~exec(sql2)
sql3 = "UPDATE email_addresses SET email = '"contactDict~email_address"', type = '"contactDict~email_type"' WHERE contact_id = "contactId
rc = db~exec(sql3)
sql4 = "UPDATE addresses SET street = '"contactDict~street"', city = '"contactDict~city"', state = '"contactDict~state"', postal_code = '"contactDict~postcode"', country = '"contactDict~country"' WHERE contact_id = "contactId
rc = db~exec(sql4)
return rc
/**************************

View File

@ -13,7 +13,7 @@
::method initialize
expose win mainMenu db
win = self~DrawMainPanel(0, .true) /* default colour, draw border box */
win = self~DrawMainPanel(0, .false) /* default colour, no main border */
self~setupMainMenu(win)
return
@ -79,6 +79,10 @@
when clrset = 9 then panel~init_pair(10, panel~COLOR_BLACK, panel~COLOR_BLACK)
/* red on black */
when clrset = 10 then panel~init_pair(11, panel~COLOR_RED, panel~COLOR_BLACK)
/* yellow on black */
when clrset = 11 then panel~init_pair(12, panel~COLOR_YELLOW, panel~COLOR_BLACK)
/* green on black */
when clrset = 12 then panel~init_pair(13, panel~COLOR_GREEN, panel~COLOR_BLACK)
/* Default to white text on black background */
OTHERWISE DO
clrset=0
@ -152,8 +156,9 @@
menuwin~refresh()
RETURN
/**********************
* Add new contact *
/************************************* ADD CONTACT **************************************/
/**********************
* Add new contact *
**********************/
::method addContactPanel
expose win db menuwin formwin
@ -165,7 +170,7 @@
form_width = 60
start_y = (max_y - form_height) % 2
start_x = (max_x - form_width) % 2
formwin = self~DrawSubPanel(form_height, form_width, start_y, start_x, 0, "Add New Contact", .true)
formwin = self~DrawSubPanel(form_height, form_width, start_y, start_x, 12, "Add New Contact", .true)
/* Create form fields */
formwin~mvaddstr(3, 2, "First Name: ")
@ -174,61 +179,67 @@
formwin~mvaddstr(6, 2, "Email: "); formwin~mvaddstr(6, 42, "Type: ");
formwin~mvaddstr(7, 2, "Street: ")
formwin~mvaddstr(8, 2, "City: "); formwin~mvaddstr(8, 28, "State: "); formwin~mvaddstr(8, 40, "PostCode: ")
formwin~mvaddstr(9, 2, "Country: ")
formwin~mvaddstr(form_height-2, 2, "[Enter] to save, [Esc] to cancel")
formwin~refresh()
/* Input fields */
firstName = self~getInputField(formwin, 3, 14, 30)
firstName = self~getInputField(formwin, 3, 14, 30, '')
if firstName = .nil then do
self~dropWindow(formwin)
RETURN
END
lastName = self~getInputField(formwin, 4, 14, 30)
lastName = self~getInputField(formwin, 4, 14, 30, '')
if lastName = .nil then do
self~dropWindow(formwin)
RETURN
END
phone = self~getInputField(formwin, 5, 10, 15)
phone = self~getInputField(formwin, 5, 10, 15, '')
if phone = .nil then do
self~dropWindow(formwin)
RETURN
END
phone_type = self~getInputField(formwin, 5, 48, 15)
phone_type = self~getInputField(formwin, 5, 48, 15, '')
if phone_type = .nil then do
self~dropWindow(formwin)
RETURN
END
email = self~getInputField(formwin, 6, 10, 30)
email = self~getInputField(formwin, 6, 10, 30, '')
if email = .nil then do
self~dropWindow(formwin)
RETURN
END
email_type = self~getInputField(formwin, 6, 48, 15)
email_type = self~getInputField(formwin, 6, 48, 15, '')
if email_type = .nil then do
self~dropWindow(formwin)
RETURN
END
street = self~getInputField(formwin, 7, 10, 25)
street = self~getInputField(formwin, 7, 10, 25, '')
if street = .nil then do
self~dropWindow(formwin)
RETURN
END
city = self~getInputField(formwin, 8, 10, 15)
city = self~getInputField(formwin, 8, 10, 15, '')
if city = .nil then do
self~dropWindow(formwin)
RETURN
END
state = self~getInputField(formwin, 8, 35, 2)
state = self~getInputField(formwin, 8, 35, 2, '')
if state = .nil then do
self~dropWindow(formwin)
RETURN
END
postCode = self~getInputField(formwin, 8, 50, 10)
postCode = self~getInputField(formwin, 8, 50, 10, '')
if postCode = .nil then do
self~dropWindow(formwin)
RETURN
END
country = self~getInputField(formwin, 9, 10, 15, '')
if country = .nil then do
self~dropWindow(formwin)
RETURN
END
if firstname = "" | lastname = "" then do
formwin~mvaddstr(8, 2, "First and Last names are required.")
@ -248,6 +259,7 @@
contactDict["CITY"] = city
contactDict["STATE"] = state
contactDict["POSTCODE"] = postCode
contactDict["COUNTRY"] = country
result = db~addContact(contactDict)
/* Display result message */
@ -265,6 +277,202 @@
self~dropWindow(formwin)
RETURN
/************************************* EDIT CONTACT **************************************/
/*****************************
* Edit Contact Select Panel *
*****************************/
::METHOD editContactSelectPanel
expose win db menuwin ewin
/* Create a form panel */
max_y = win~lines
max_x = win~cols
form_height = 12
form_width = 35
start_y = (max_y - form_height) % 2
start_x = (max_x - form_width) % 2
ewin = self~DrawSubPanel(form_height, form_width, start_y, start_x, 11, "Select A Contact To Edit", .true)
ewin~mvaddstr(4, 2, "Contact ID: ")
ewin~mvaddstr(form_height-1, 2, "[Enter] to edit, [Esc] to cancel")
ewin~refresh()
contactId = self~getInputField(ewin, 4, 14, 10, '')
if contactId = .nil then do
self~dropWindow(ewin)
RETURN
END
result = db~getContact(contactId)
if result = .nil then do /* should be a result id number */
ewin~mvaddstr(8, 2, "Contact not found.")
ewin~refresh()
call SysWait 0.5
self~dropWindow(ewin)
RETURN
end
/* launch a view panel with full contact details */
self~dropWindow(ewin)
self~editContactDetailsPanel(contactId)
RETURN
/*************************
* Edit Existing Contact *
*************************/
::METHOD editContactDetailsPanel
expose win db menuwin editwin
use arg contactId
/* Create a form panel */
max_y = win~lines
max_x = win~cols
form_height = 15
form_width = 60
start_y = (max_y - form_height) % 2
start_x = (max_x - form_width) % 2
editwin = self~DrawSubPanel(form_height, form_width, start_y, start_x, 11, "Edit Contact Details", .true)
/* Create form fields */
editwin~mvaddstr(3, 2, "First Name: ")
editwin~mvaddstr(4, 2, "Last Name: ")
editwin~mvaddstr(5, 2, "Phone: "); editwin~mvaddstr(5, 42, "Type: ");
editwin~mvaddstr(6, 2, "Email: "); editwin~mvaddstr(6, 42, "Type: ");
editwin~mvaddstr(7, 2, "Street: ")
editwin~mvaddstr(8, 2, "City: "); editwin~mvaddstr(8, 28, "State: "); editwin~mvaddstr(8, 40, "PostCode: ")
editwin~mvaddstr(9, 2, "Country: ")
editwin~mvaddstr(form_height-1, 2, "[Enter] to save, [Esc] to cancel")
editwin~refresh()
/* Get existing details */
contactDetails = db~getContactDetails(contactId)
editwin~mvaddstr(3, 14, contactDetails~first_name);
editwin~mvaddstr(4, 14, contactDetails~last_name);
editwin~mvaddstr(5, 10, contactDetails~phone_number);
editwin~mvaddstr(5, 48, contactDetails~phone_type);
editwin~mvaddstr(6, 10, contactDetails~email_address);
editwin~mvaddstr(6, 48, contactDetails~email_type);
editwin~mvaddstr(7, 10, contactDetails~street);
editwin~mvaddstr(8, 10, contactDetails~city);
editwin~mvaddstr(8, 35, contactDetails~state);
editwin~mvaddstr(8, 50, contactDetails~postal_code);
editwin~mvaddstr(9, 10, contactDetails~country);
/* Prepopulate the input fields */
firstNameInit = contactDetails~first_name
lastNameInit = contactDetails~last_name
phoneInit = contactDetails~phone_number
phone_typeInit = contactDetails~phone_type
emailInit = contactDetails~email_address
email_typeInit = contactDetails~email_type
streetInit = contactDetails~street
cityInit = contactDetails~city
stateInit = contactDetails~state
postCodeInit = contactDetails~postal_code
countryInit = contactDetails~country
/* Input fields */
firstName = self~getInputField(editwin, 3, 14, 30, firstNameInit)
if firstName = .nil then do
self~dropWindow(editwin)
RETURN
END
lastName = self~getInputField(editwin, 4, 14, 30, lastNameInit)
if lastName = .nil then do
self~dropWindow(editwin)
RETURN
END
phone = self~getInputField(editwin, 5, 10, 15, phoneInit)
if phone = .nil then do
self~dropWindow(editwin)
RETURN
END
phone_type = self~getInputField(editwin, 5, 48, 15, phone_typeInit)
if phone_type = .nil then do
self~dropWindow(editwin)
RETURN
END
email = self~getInputField(editwin, 6, 10, 30, emailInit)
if email = .nil then do
self~dropWindow(editwin)
RETURN
END
email_type = self~getInputField(editwin, 6, 48, 15, email_typeInit)
if email_type = .nil then do
self~dropWindow(editwin)
RETURN
END
street = self~getInputField(editwin, 7, 10, 30, streetInit)
if street = .nil then do
self~dropWindow(editwin)
RETURN
END
city = self~getInputField(editwin, 8, 10, 15, cityInit)
if city = .nil then do
self~dropWindow(editwin)
RETURN
END
state = self~getInputField(editwin, 8, 35, 2, stateInit)
if state = .nil then do
self~dropWindow(editwin)
RETURN
END
postCode = self~getInputField(editwin, 8, 50, 10, postCodeInit)
if postCode = .nil then do
self~dropWindow(editwin)
RETURN
END
country = self~getInputField(editwin, 9, 10, 15, countryInit)
if country = .nil then do
self~dropWindow(editwin)
RETURN
END
/* Add to database */
contactDict = .Directory~new()
contactDict["FIRST_NAME"] = firstName
contactDict["LAST_NAME"] = lastName
contactDict["PHONE_NUMBER"] = phone
contactDict["PHONE_TYPE"] = phone_type
contactDict["EMAIL_ADDRESS"] = email
contactDict["EMAIL_TYPE"] = email_type
contactDict["STREET"] = street
contactDict["CITY"] = city
contactDict["STATE"] = state
contactDict["POSTCODE"] = postCode
contactDict["COUNTRY"] = country
result = db~updateContact(contactId, contactDict)
/* Display result message */
if result = 0 then do /* should be a result id number */
editwin~mvaddstr(11, 2, "Contact ID ["result"] edited successfully!")
editwin~refresh()
call SysWait 1.5
end
else do
editwin~mvaddstr(11, 2, "Failed to edit contact.")
editwin~refresh()
call SysWait 1.5
end
self~dropWindow(editwin)
RETURN
/************************************* DELETE CONTACT **************************************/
/****************************
* Delete Contact Panel *
****************************/
@ -284,7 +492,7 @@
delwin~mvaddstr(form_height-1, 2, "[Enter] to del, [Esc] to cancel")
delwin~refresh()
contactId = self~getInputField(delwin, 4, 14, 10)
contactId = self~getInputField(delwin, 4, 14, 10, '')
if contactId = .nil then do
self~dropWindow(delwin)
RETURN
@ -305,6 +513,8 @@
self~dropWindow(delwin)
RETURN
/************************************* VIEW CONTACT **************************************/
/********************************
* View Contact Selection Panel *
********************************/
@ -324,7 +534,7 @@
viewselectwin~mvaddstr(form_height-1, 2, "[Enter] to sel., [Esc] to cancel")
viewselectwin~refresh()
contactId = self~getInputField(viewselectwin, 4, 14, 10)
contactId = self~getInputField(viewselectwin, 4, 14, 10, '')
if contactId = .nil then do
self~dropWindow(viewselectwin)
RETURN
@ -383,6 +593,8 @@
RETURN
/************************************* VIEW ALL CONTACTS **********************************/
/****************************
* List all contacts *
****************************/
@ -393,7 +605,7 @@
max_y = win~lines
max_x = win~cols
list_height = max_y - 10
list_width = max_x - 30
list_width = max_x - 18
start_y = (max_y - list_height) % 2
start_x = (max_x - list_width) % 2
@ -404,11 +616,11 @@
/* Display column headers */
listwin~attron(listwin~A_BOLD)
listwin~mvaddstr(4, 2, "ID")
listwin~mvaddstr(4, 5, "First Name")
listwin~mvaddstr(4, 17, "Last Name")
listwin~mvaddstr(4, 29, "Phone")
listwin~mvaddstr(4, 45, "Email")
listwin~mvaddstr(5, 2, "-- ---------- --------- --------------- -------------------------")
listwin~mvaddstr(4, 7, "First Name")
listwin~mvaddstr(4, 21, "Last Name")
listwin~mvaddstr(4, 36, "Phone")
listwin~mvaddstr(4, 52, "Email")
listwin~mvaddstr(5, 2, "---- ---------- ------------ --------------- -------------------------")
listwin~attroff(listwin~A_BOLD)
contacts = db~getAllContacts()
@ -418,10 +630,10 @@
do i = 1 to contacts~items
contact = contacts[i]
listwin~mvaddstr(i+5, 2, contact['ID'])
listwin~mvaddstr(i+5, 5, contact['FIRST_NAME'])
listwin~mvaddstr(i+5, 17, contact['LAST_NAME'])
listwin~mvaddstr(i+5, 29, contact['PHONE_NUMBER'])
listwin~mvaddstr(i+5, 45, contact['EMAIL_ADDRESS'])
listwin~mvaddstr(i+5, 7, contact['FIRST_NAME'])
listwin~mvaddstr(i+5, 21, contact['LAST_NAME'])
listwin~mvaddstr(i+5, 36, contact['PHONE_NUMBER'])
listwin~mvaddstr(i+5, 52, contact['EMAIL_ADDRESS'])
/* Break if we run out of screen space */
if i > list_height-7 then LEAVE
end
@ -435,6 +647,8 @@
RETURN
Return
/************************************* SEARCH ALL CONTACTS ***********************************/
/****************************
* Search for contact *
****************************/
@ -454,7 +668,7 @@
searchwin~refresh()
/* Get search term */
term = self~getInputField(searchwin, 3, 15, 30)
term = self~getInputField(searchwin, 3, 15, 30, '')
/* If canceled, return to main menu */
if term = .nil then do
@ -482,7 +696,7 @@
max_y = win~lines
max_x = win~cols
list_height = max_y - 15
list_width = max_x - 30
list_width = max_x - 18
start_y = (max_y - list_height) % 2
start_x = (max_x - list_width) % 2
@ -493,11 +707,11 @@
/* Display column headers */
searchoutwin~attron(searchoutwin~A_BOLD)
searchoutwin~mvaddstr(4, 2, "ID")
searchoutwin~mvaddstr(4, 5, "First Name")
searchoutwin~mvaddstr(4, 17, "Last Name")
searchoutwin~mvaddstr(4, 29, "Phone")
searchoutwin~mvaddstr(4, 45, "Email")
searchoutwin~mvaddstr(5, 2, "-- ---------- --------- --------------- -------------------------")
searchoutwin~mvaddstr(4, 7, "First Name")
searchoutwin~mvaddstr(4, 21, "Last Name")
searchoutwin~mvaddstr(4, 36, "Phone")
searchoutwin~mvaddstr(4, 52, "Email")
searchoutwin~mvaddstr(5, 2, "---- ---------- ------------ --------------- -------------------------")
searchoutwin~attroff(searchoutwin~A_BOLD)
contacts = db~searchContacts(term)
@ -507,10 +721,10 @@
do i = 1 to contacts~items
contact = contacts[i]
searchoutwin~mvaddstr(i+5, 2, contact['ID'])
searchoutwin~mvaddstr(i+5, 5, contact['FIRST_NAME'])
searchoutwin~mvaddstr(i+5, 17, contact['LAST_NAME'])
searchoutwin~mvaddstr(i+5, 29, contact['PHONE_NUMBER'])
searchoutwin~mvaddstr(i+5, 45, contact['EMAIL_ADDRESS'])
searchoutwin~mvaddstr(i+5, 7, contact['FIRST_NAME'])
searchoutwin~mvaddstr(i+5, 21, contact['LAST_NAME'])
searchoutwin~mvaddstr(i+5, 36, contact['PHONE_NUMBER'])
searchoutwin~mvaddstr(i+5, 52, contact['EMAIL_ADDRESS'])
/* Break if we run out of screen space */
if i > list_height-7 then LEAVE
end
@ -524,29 +738,33 @@
RETURN
/************************************* UTILITIY METHODS **************************************/
/************************
* Get Input From Field *
************************/
::method getInputField
use arg win, y, x, maxlen
use arg win, y, x, maxlen, bufferContent
win~move(y, x)
win~curs_set(1) /* Show cursor */
win~keypad(1) /* Enable function keys and arrow keys */
win~echo() /* Show typed characters */
win~raw
buffer = ""
if LENGTH(bufferContent) > 0 then DO
buffer = bufferContent
win~move(y, x + buffer~length)
END
Else DO
buffer = ""
win~move(y, x)
END
blank_line = copies(" ", maxlen) /* String of spaces for clearing the line */
do forever
key = win~getch()
decimalKey = C2D(key)
/* Debug: Display key decimal value */
/* win~mvaddstr(12, 2, "Key pressed (decimal): " || decimalKey || " ") */
decimalKey = C2D(key)
select
when key = D2C(27) then do /* ESC key */
win~curs_set(0) /* Hide cursor */
@ -646,8 +864,7 @@
self~deleteContactPanel()
END
when key_char = 'e' then do
menuwin~mvaddstr(menuwin~lines-15, 3, "TODO: Create Edit Panel");
menuwin~refresh
self~editContactSelectPanel()
END
when key_char = 's' then do
self~searchContactPanel()

Binary file not shown.