diff --git a/src/App.svelte b/src/App.svelte index e88cfdea..aef1c587 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -53,6 +53,8 @@ import Imprint from "./components/Imprint.svelte"; import Privacy from "./components/Privacy.svelte"; import ResetPassword from "./components/ResetPassword.svelte"; +import Contacts from "./components/Contacts.svelte"; +import ContactDetail from "./components/ContactDetail.svelte"; store.init(); registerSW(); @@ -119,6 +121,14 @@ import ResetPassword from "./components/ResetPassword.svelte"; + + + + + + + + diff --git a/src/components/AddContactModal.svelte b/src/components/AddContactModal.svelte new file mode 100644 index 00000000..2ea11bce --- /dev/null +++ b/src/components/AddContactModal.svelte @@ -0,0 +1,439 @@ + + +{#if modal_open} +
{ + modal_open = false; + }}> +
+ +
+{/if} diff --git a/src/components/AddRunnerModal.svelte b/src/components/AddRunnerModal.svelte index 32c0da99..fe4cc642 100644 --- a/src/components/AddRunnerModal.svelte +++ b/src/components/AddRunnerModal.svelte @@ -36,7 +36,7 @@ $: firstname_input_value = ""; $: processed_last_submit = true; $: isPhoneValidOrEmpty = - isMobilePhone( + phone_input_value.includes("+")&&isMobilePhone( phone_input_value .replaceAll("(", "") .replaceAll(")", "") @@ -258,7 +258,7 @@ {#if !isPhoneValidOrEmpty} - {$_('the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number')} + {@html $_('the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number')} {/if}
diff --git a/src/components/ContactDetail.svelte b/src/components/ContactDetail.svelte new file mode 100644 index 00000000..6e8888d9 --- /dev/null +++ b/src/components/ContactDetail.svelte @@ -0,0 +1,385 @@ + + +{#await promise} + {$_('loading-contact-details')} +{:then} +
+
+
+ +
+
+
+ {original_data.firstname} + {original_data.middlename || ''} + {original_data.lastname} + + {#if store.state.jwtinfo.userdetails.permissions.includes('CONTACT:DELETE')} + {#if delete_triggered} + + + {/if} + {#if !delete_triggered} + + {/if} + {/if} + {#if !delete_triggered} + + {/if} + +
+ +
+ + + {#if !isFirstnameValid} + + {$_('first-name-is-required')} + + {/if} +
+
+ + +
+
+ + + {#if !isLastnameValid} + + {$_('last-name-is-required')} + + {/if} +
+
+ + + {#if !isEmailValid} + + {$_('valid-email-is-required')} + + {/if} +
+
+ + + {#if !isPhoneValidOrEmpty} + + {$_('valid-international-phone-number-is-required')} + + {/if} +
+
+ {$_('groups')} + +
+ +
+
+ +
+
+ +
+
+ {#if editable.address_checked === true} +
+ + + {#if !isAddress1Valid} + + {$_('address-is-required')} + + {/if} +
+
+ + +
+
+ + + {#if !iszipcodevalid} + + {$_('valid-zipcode-postal-code-is-required')} + + {/if} +
+
+ + + {#if !iscityvalid} + + {$_('valid-city-is-required')} + + {/if} +
+ {/if} +
+{:catch error} + +{/await} diff --git a/src/components/Contacts.svelte b/src/components/Contacts.svelte new file mode 100644 index 00000000..cfd8fa73 --- /dev/null +++ b/src/components/Contacts.svelte @@ -0,0 +1,29 @@ + + +
+ + {$_('contacts')} + {#if store.state.jwtinfo.userdetails.permissions.includes('CONTACT:CREATE')} + + {/if} + + +
+ +{#if store.state.jwtinfo.userdetails.permissions.includes('CONTACT:CREATE')} + +{/if} diff --git a/src/components/ContactsEmptyState.svelte b/src/components/ContactsEmptyState.svelte new file mode 100644 index 00000000..7188c76f --- /dev/null +++ b/src/components/ContactsEmptyState.svelte @@ -0,0 +1,17 @@ + + +
+

+ + {$_('there-are-no-contacts-added-yet')}
+ {$_('add-your-first-contact')} +

+
+ + diff --git a/src/components/ContactsOverview.svelte b/src/components/ContactsOverview.svelte new file mode 100644 index 00000000..6ebeca5f --- /dev/null +++ b/src/components/ContactsOverview.svelte @@ -0,0 +1,177 @@ + + +{#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:GET')} + {#await promise} + + {:then} + {#if current_contacts.length === 0} + + {:else} + +
+ + + + + + + + + + + {#each current_contacts as t} + {#if Object.values(t) + .toString() + .toLowerCase() + .includes(searchvalue)} + + + + + {#if active_deletes[t.id] === true} + + {:else} + + {/if} + + {/if} + {/each} + +
+ Name + + Groups + + Address + + Action +
+
+
+
+ {t.firstname} + {t.middlename || ''} + {t.lastname} +
+
+
+
+
+
+
+ {#if t.groups.length > 0} + {#each t.groups as g} + {#if g.responseType === 'RUNNERORGANIZATION'} + {g.name} + {:else} + {g.parentGroup.name} + > + {g.name} + {/if} + {/each} + {:else} + {$_('contact-is-not-a-member-in-any-group')} + {/if} +
+
+
+
+
+
+
+ {#if t.address.address1 !== null} + {t.address.address1}
+ {t.address.address2 || ''}
+ {t.address.postalcode} + {t.address.city} + {t.address.country} + {/if} +
+
+
+
+ + + + {$_('edit')} + {#if store.state.jwtinfo.userdetails.permissions.includes('TEAM:DELETE')} + + {/if} +
+
+ {/if} + {:catch error} +
+ + {$_('general_promise_error')} + {error} + +
+ {/await} +{/if} diff --git a/src/components/Dashboard.svelte b/src/components/Dashboard.svelte index 23de2d92..72ffc38d 100644 --- a/src/components/Dashboard.svelte +++ b/src/components/Dashboard.svelte @@ -122,6 +122,13 @@ {$_('tracks')} {/if} + + + {$_('contacts')} + - import { RunnerOrganizationService } from "@odit/lfk-client-js"; + import { + GroupContactService, + RunnerOrganizationService, + } from "@odit/lfk-client-js"; import { _ } from "svelte-i18n"; import Toastify from "toastify-js"; import store from "../store"; @@ -11,15 +14,24 @@ export let params; let orgdata = {}; let original = {}; + let contacts = []; $: data_loaded = false; $: data_changed = JSON.stringify(orgdata) === JSON.stringify(original); const promise = RunnerOrganizationService.runnerOrganizationControllerGetOne( params.orgid ).then((value) => { data_loaded = true; + if (value.contact) { + if (value.contact !== "null") { + value.contact = value.contact.id; + } + } orgdata = Object.assign(orgdata, value); original = Object.assign(original, value); }); + GroupContactService.groupContactControllerGetAll().then((val) => { + contacts = val; + }); let modal_open = false; let delete_org = {}; function deleteOrganization() { @@ -46,9 +58,11 @@ text: "updating organization", duration: 2500, }).showToast(); + let postdata = orgdata; + postdata.contact = postdata.contact === "null" ? null : postdata.contact; RunnerOrganizationService.runnerOrganizationControllerPut( original.id, - orgdata + postdata ) .then((resp) => { Object.assign(original, orgdata); @@ -209,13 +223,19 @@ - + bind:value={orgdata.contact} + class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"> + + {#each contacts as c} + + {/each} +
-
+
{o.name}
@@ -88,8 +87,7 @@
-
+
{#if o.address} {JSON.stringify(o.address)} {:else}no address specified{/if} @@ -100,10 +98,13 @@
-
+
{#if o.contact} - {JSON.stringify(o.contact)} + {o.contact.firstname} + {o.contact.middlename || ''} + {o.contact.lastname} {:else}no contact specified{/if}
diff --git a/src/components/TeamDetail.svelte b/src/components/TeamDetail.svelte index fec053dd..4248fc69 100644 --- a/src/components/TeamDetail.svelte +++ b/src/components/TeamDetail.svelte @@ -1,5 +1,6 @@ @@ -216,13 +227,19 @@ - + bind:value={teamdata.contact} + class="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-gray-500 rounded-md p-2"> + + {#each contacts as c} + + {/each} +
diff --git a/src/components/TeamsOverview.svelte b/src/components/TeamsOverview.svelte index b76db2da..204d3ddc 100644 --- a/src/components/TeamsOverview.svelte +++ b/src/components/TeamsOverview.svelte @@ -104,7 +104,11 @@ diff --git a/src/locales/en.json b/src/locales/en.json index 85a3a196..3eee95c6 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -3,24 +3,36 @@ "404title": "Error 404", "about": "About", "action": "Action", + "add-your-first-contact": "Add your first contact", "add-your-first-track": "Add your first track.", "address": "Address", + "address-is-required": "Address is required", + "apartment-suite-etc": "Apartment, suite, etc.", "application_name": "Lauf für Kaya! - Admin", + "attention": "Attention!", "author": "Author", "bitte-bestaetige-diese-laeufer-fuer-den-import": "Please confirm these runners for import.", "browse": "Browse", "by": "by", "cancel": "Cancel", + "cancel-delete": "Cancel Delete", + "cancel-keep-team": "Cancel, keep team", "cannot-reset-your-password-directly": "Bummer. We unfortunately cannot reset your password directly. Please send us a mail and confirm your identity", "changelog": "Changelog", + "city": "City", "close": "Close", "confirm-delete": "Confirm Delete", + "confirm-delete-team-and-associated-runners": "Confirm, delete team and associated runners.", "confirm-deletion": "Confirm Deletion", "contact": "Contact", "contact-information": "Contact Information", + "contact-is-being-updated": "Contact is being updated...", + "contact-is-not-a-member-in-any-group": "Contact is not a member in any group", + "contacts": "Contacts", "count_organizations": "# Organizations", "count_teams": "# Teams", "create": "Create", + "create-a-new-contact": "Create a new contact", "create-a-new-runner": "Create a new Runner", "create-a-new-track": "Create a new Track", "create-organization": "Create Organization", @@ -49,6 +61,7 @@ "an_error_happened_while_fetching_the_data": "An error happened while fetching the data" }, "delete": "Delete", + "delete-contact": "Delete Contact", "delete-organization": "Delete Organization", "delete-runner": "Delete Runner", "delete-team": "Delete Team", @@ -60,6 +73,7 @@ "dont-panic-were-resetting-it": "Don't panic, we're resetting it ✌", "drag-and-drop-your-files-or__legacy": "Drag & Drop your files or", "e-mail-adress": "E-Mail Adress", + "edit": "Edit", "edit-permissions": "edit permissions", "email_address_or_username": "Email / username", "error_on_login": "Error on login", @@ -106,6 +120,7 @@ "lfk-is-os": "The \"Lauf für Kaya!\" Frontend is (like all other projects for the \"LfK!\" Also) an open source project.", "license": "License", "licenses-are-being-loaded": "Licenses are being loaded...", + "loading-contact-details": "Loading contact details...", "loading-runners": "loading runners...", "log_in": "Log in", "log_in_to_your_account": "Log in to your account", @@ -157,7 +172,9 @@ "team": "Team", "team-name": "Team name", "teams": "Teams", + "teams-are-being-loaded": "Teams are being loaded...", "the-provided-phone-number-is-invalid-less-than-br-greater-than-please-enter-a-valid-international-number": "the provided phone number is invalid.
please enter a valid international number...", + "there-are-no-contacts-added-yet": "There are no contacts added yet.", "this-might-take-a-moment": "This might take a moment 👀", "total-distance": "total distance", "total-donations": "total donations", @@ -168,13 +185,18 @@ "track-length-in-m": "Track Length in m", "track-name": "Track name", "tracks": "Tracks", + "updated-contact": "Updated contact!", "updating-runner": "Updating runner...", "updating-user": "updating user...", "user-updated": "User updated", "username": "Username", "users": "Users", + "valid-city-is-required": "Valid city is required", "valid-email-is-required": "valid email is required", + "valid-international-phone-number-is-required": "valid international phone number is required...", + "valid-zipcode-postal-code-is-required": "Valid zipcode/ postal code is required", "welcome_wavinghand": "Welcome 👋", "you-can-now-use-your-new-password-to-log-in-to-your-account": "You can now use your new password to log in to your account! 🎉", - "your_profile": "Your Profile" + "your_profile": "Your Profile", + "zip-postal-code": "ZIP/ postal code" } \ No newline at end of file