tsk-4: Fix contacts not being saved #14
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "textsender",
|
"name": "textsender",
|
||||||
"version": "0.0.7",
|
"version": "0.0.8",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "textsender",
|
"name": "textsender",
|
||||||
"version": "0.0.7",
|
"version": "0.0.8",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "^19.2.7",
|
"react": "^19.2.7",
|
||||||
"react-dom": "^19.2.7",
|
"react-dom": "^19.2.7",
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "textsender",
|
"name": "textsender",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.7",
|
"version": "0.0.8",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
import { API_BASE_URL } from '../constants/api';
|
import { API_BASE_URL } from '../constants/api';
|
||||||
|
|
||||||
export class CreateContactRequest {
|
export class CreateContactRequest {
|
||||||
first_name = '';
|
firstname = '';
|
||||||
last_name = '';
|
lastname = '';
|
||||||
|
nickname = '';
|
||||||
phone_number = '';
|
phone_number = '';
|
||||||
user_id = '';
|
user_id = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UpdateContactNamesRequest {
|
export class UpdateContactNamesRequest {
|
||||||
first_name = '';
|
firstname = '';
|
||||||
last_name = '';
|
lastname = '';
|
||||||
nickname = '';
|
nickname = '';
|
||||||
contact_id = '';
|
id = '';
|
||||||
user_id = '';
|
user_id = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ const AddContact = ({ isOpen, onClose, onSuccess }) => {
|
|||||||
phoneNumber: '',
|
phoneNumber: '',
|
||||||
firstName: '',
|
firstName: '',
|
||||||
lastName: '',
|
lastName: '',
|
||||||
|
nickName: '',
|
||||||
});
|
});
|
||||||
const [errors, setErrors] = useState({});
|
const [errors, setErrors] = useState({});
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
@@ -66,8 +67,9 @@ const AddContact = ({ isOpen, onClose, onSuccess }) => {
|
|||||||
const userId = tokenService.getUserId();
|
const userId = tokenService.getUserId();
|
||||||
let contact = new CreateContactRequest();
|
let contact = new CreateContactRequest();
|
||||||
contact.phone_number = formData.phoneNumber;
|
contact.phone_number = formData.phoneNumber;
|
||||||
contact.first_name = formData.firstName;
|
contact.firstname = formData.firstName;
|
||||||
contact.last_name = formData.lastName;
|
contact.lastname = formData.lastName;
|
||||||
|
contact.nickname = formData.nickName;
|
||||||
contact.user_id = userId;
|
contact.user_id = userId;
|
||||||
const result = await contactApi.createContact(
|
const result = await contactApi.createContact(
|
||||||
contact,
|
contact,
|
||||||
@@ -178,6 +180,23 @@ const AddContact = ({ isOpen, onClose, onSuccess }) => {
|
|||||||
<span className="form-hint">Optional field</span>
|
<span className="form-hint">Optional field</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="nickName" className="form-label">
|
||||||
|
Nick Name
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="nickName"
|
||||||
|
name="nickName"
|
||||||
|
type="text"
|
||||||
|
className="form-input"
|
||||||
|
value={formData.nickName}
|
||||||
|
onChange={handleChange}
|
||||||
|
placeholder="Enter nick name (optional)"
|
||||||
|
disabled={isSubmitting}
|
||||||
|
/>
|
||||||
|
<span className="form-hint">Optional field</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="form-actions">
|
<div className="form-actions">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ function ConfirmationStep({ selectedContact, contactDetails, isSubmitting }) {
|
|||||||
<span className={styles.reviewLabel}>First Name</span>
|
<span className={styles.reviewLabel}>First Name</span>
|
||||||
<div className={styles.reviewComparison}>
|
<div className={styles.reviewComparison}>
|
||||||
<span className={styles.oldValue}>
|
<span className={styles.oldValue}>
|
||||||
{selectedContact.first_name || 'Not set'}
|
{selectedContact.firstname || 'Not set'}
|
||||||
</span>
|
</span>
|
||||||
<span className={styles.arrow}>→</span>
|
<span className={styles.arrow}>→</span>
|
||||||
<span className={styles.newValue}>
|
<span className={styles.newValue}>
|
||||||
{contactDetails.first_name || 'Not set'}
|
{contactDetails.firstname || 'Not set'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -46,11 +46,11 @@ function ConfirmationStep({ selectedContact, contactDetails, isSubmitting }) {
|
|||||||
<span className={styles.reviewLabel}>Last Name</span>
|
<span className={styles.reviewLabel}>Last Name</span>
|
||||||
<div className={styles.reviewComparison}>
|
<div className={styles.reviewComparison}>
|
||||||
<span className={styles.oldValue}>
|
<span className={styles.oldValue}>
|
||||||
{selectedContact.last_name || 'Not set'}
|
{selectedContact.lastname || 'Not set'}
|
||||||
</span>
|
</span>
|
||||||
<span className={styles.arrow}>→</span>
|
<span className={styles.arrow}>→</span>
|
||||||
<span className={styles.newValue}>
|
<span className={styles.newValue}>
|
||||||
{contactDetails.last_name || 'Not set'}
|
{contactDetails.lastname || 'Not set'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import styles from './ModifyForm.module.css';
|
|||||||
|
|
||||||
function ModifyForm({ contactDetails, setContactDetails }) {
|
function ModifyForm({ contactDetails, setContactDetails }) {
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
first_name: '',
|
firstname: '',
|
||||||
last_name: '',
|
lastname: '',
|
||||||
nickname: '',
|
nickname: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -12,8 +12,8 @@ function ModifyForm({ contactDetails, setContactDetails }) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (contactDetails) {
|
if (contactDetails) {
|
||||||
setFormData({
|
setFormData({
|
||||||
first_name: contactDetails.first_name || '',
|
firstname: contactDetails.firstname || '',
|
||||||
last_name: contactDetails.last_name || '',
|
lastname: contactDetails.lastname || '',
|
||||||
nickname: contactDetails.nickname || '',
|
nickname: contactDetails.nickname || '',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -37,16 +37,16 @@ function ModifyForm({ contactDetails, setContactDetails }) {
|
|||||||
<h3 className={styles.sectionTitle}>Edit Contact Information</h3>
|
<h3 className={styles.sectionTitle}>Edit Contact Information</h3>
|
||||||
|
|
||||||
<div className={styles.formGroup}>
|
<div className={styles.formGroup}>
|
||||||
<label htmlFor="first_name" className={styles.formLabel}>
|
<label htmlFor="firstname" className={styles.formLabel}>
|
||||||
First Name
|
First Name
|
||||||
<span className={styles.requiredIndicator}>*</span>
|
<span className={styles.requiredIndicator}>*</span>
|
||||||
</label>
|
</label>
|
||||||
<div className={styles.inputContainer}>
|
<div className={styles.inputContainer}>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="first_name"
|
id="firstname"
|
||||||
name="first_name"
|
name="firstname"
|
||||||
value={formData.first_name}
|
value={formData.firstname}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className={styles.formInput}
|
className={styles.formInput}
|
||||||
placeholder="Enter contact's first name"
|
placeholder="Enter contact's first name"
|
||||||
@@ -61,16 +61,16 @@ function ModifyForm({ contactDetails, setContactDetails }) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.formGroup}>
|
<div className={styles.formGroup}>
|
||||||
<label htmlFor="last_name" className={styles.formLabel}>
|
<label htmlFor="lastname" className={styles.formLabel}>
|
||||||
Last Name
|
Last Name
|
||||||
<span className={styles.requiredIndicator}>*</span>
|
<span className={styles.requiredIndicator}>*</span>
|
||||||
</label>
|
</label>
|
||||||
<div className={styles.inputContainer}>
|
<div className={styles.inputContainer}>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="last_name"
|
id="lastname"
|
||||||
name="last_name"
|
name="lastname"
|
||||||
value={formData.last_name}
|
value={formData.lastname}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
className={styles.formInput}
|
className={styles.formInput}
|
||||||
placeholder="Enter contact's last name"
|
placeholder="Enter contact's last name"
|
||||||
|
|||||||
@@ -49,15 +49,15 @@ function ViewContact({ selectedContact, onSelectedContact }) {
|
|||||||
const filteredContacts = contacts.filter(
|
const filteredContacts = contacts.filter(
|
||||||
(contact) =>
|
(contact) =>
|
||||||
contact.phone_number.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
contact.phone_number.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
contact.first_name?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
contact.firstname?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
contact.last_name?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
contact.lastname?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
contact.nickname?.toLowerCase().includes(searchTerm.toLowerCase())
|
contact.nickname?.toLowerCase().includes(searchTerm.toLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
const formatContactDisplay = (contact) => {
|
const formatContactDisplay = (contact) => {
|
||||||
const phone = contact.phone_number || 'No phone';
|
const phone = contact.phone_number || 'No phone';
|
||||||
const name =
|
const name =
|
||||||
[contact.first_name, contact.last_name].filter(Boolean).join(' ') ||
|
[contact.firstname, contact.lastname].filter(Boolean).join(' ') ||
|
||||||
'Unnamed';
|
'Unnamed';
|
||||||
const nickname = contact.nickname ? `"${contact.nickname}"` : '';
|
const nickname = contact.nickname ? `"${contact.nickname}"` : '';
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ function ViewContact({ selectedContact, onSelectedContact }) {
|
|||||||
onClick={() => onSelectedContact(contact)}
|
onClick={() => onSelectedContact(contact)}
|
||||||
>
|
>
|
||||||
<div className={styles.contactAvatar}>
|
<div className={styles.contactAvatar}>
|
||||||
{contact.first_name?.[0]?.toUpperCase() || '?'}
|
{contact.firstname?.[0]?.toUpperCase() || '?'}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.contactInfo}>
|
<div className={styles.contactInfo}>
|
||||||
<div className={styles.contactMainInfo}>
|
<div className={styles.contactMainInfo}>
|
||||||
@@ -131,7 +131,7 @@ function ViewContact({ selectedContact, onSelectedContact }) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.contactName}>
|
<div className={styles.contactName}>
|
||||||
{[contact.first_name, contact.last_name]
|
{[contact.firstname, contact.lastname]
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.join(' ') || 'Unnamed Contact'}
|
.join(' ') || 'Unnamed Contact'}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ const useViewContactWizard = () => {
|
|||||||
case 'modify':
|
case 'modify':
|
||||||
if (!state.contactDetails) return false;
|
if (!state.contactDetails) return false;
|
||||||
if (
|
if (
|
||||||
!state.contactDetails.first_name ||
|
!state.contactDetails.firstname ||
|
||||||
state.contactDetails.first_name.trim() === ''
|
state.contactDetails.firstname.trim() === ''
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
} else if (
|
} else if (
|
||||||
!state.contactDetails.last_name ||
|
!state.contactDetails.lastname ||
|
||||||
state.contactDetails.last_name.trim() === ''
|
state.contactDetails.lastname.trim() === ''
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@@ -61,8 +61,8 @@ const useViewContactWizard = () => {
|
|||||||
? null
|
? null
|
||||||
: {
|
: {
|
||||||
id: contactId,
|
id: contactId,
|
||||||
first_name: contact.first_name,
|
firstname: contact.firstname,
|
||||||
last_name: contact.last_name,
|
lastname: contact.lastname,
|
||||||
phone_number: contact.phone_number,
|
phone_number: contact.phone_number,
|
||||||
user_id: contact.user_id,
|
user_id: contact.user_id,
|
||||||
nickname: contact.nickname || '',
|
nickname: contact.nickname || '',
|
||||||
@@ -90,8 +90,8 @@ const useViewContactWizard = () => {
|
|||||||
step: nextStepValue,
|
step: nextStepValue,
|
||||||
submissionError: null,
|
submissionError: null,
|
||||||
contactDetails: {
|
contactDetails: {
|
||||||
first_name: prev.selectedContact.first_name || '',
|
firstname: prev.selectedContact.firstname || '',
|
||||||
last_name: prev.selectedContact.last_name || '',
|
lastname: prev.selectedContact.lastname || '',
|
||||||
nickname: prev.selectedContact.nickname || '',
|
nickname: prev.selectedContact.nickname || '',
|
||||||
phone_number: prev.selectedContact.phone_number || '',
|
phone_number: prev.selectedContact.phone_number || '',
|
||||||
id: prev.selectedContact.id,
|
id: prev.selectedContact.id,
|
||||||
@@ -139,10 +139,10 @@ const useViewContactWizard = () => {
|
|||||||
console.log('Contact details to update: ', state.contactDetails);
|
console.log('Contact details to update: ', state.contactDetails);
|
||||||
|
|
||||||
let reqBody = new UpdateContactNamesRequest();
|
let reqBody = new UpdateContactNamesRequest();
|
||||||
reqBody.first_name = state.contactDetails.first_name;
|
reqBody.firstname = state.contactDetails.firstname;
|
||||||
reqBody.last_name = state.contactDetails.last_name;
|
reqBody.lastname = state.contactDetails.lastname;
|
||||||
reqBody.nickname = state.contactDetails.nickname || ''; // Send empty string if no nickname
|
reqBody.nickname = state.contactDetails.nickname || ''; // Send empty string if no nickname
|
||||||
reqBody.contact_id = state.selectedContact.id;
|
reqBody.id = state.selectedContact.id;
|
||||||
reqBody.user_id = userId;
|
reqBody.user_id = userId;
|
||||||
|
|
||||||
const response = await contactApi.updateContactNames(
|
const response = await contactApi.updateContactNames(
|
||||||
|
|||||||
Reference in New Issue
Block a user