diff --git a/ui/next.config.js b/ui/next.config.js index 7767ea3..82ee722 100644 --- a/ui/next.config.js +++ b/ui/next.config.js @@ -4,8 +4,8 @@ const nextConfig = { // reactStrictMode: true, env: { // // apiUrl: "http://localhost:8080/api", - // apiUrl: "https://mypetjournal-lqkz3.ondigitalocean.app/api", - apiUrl: "/api", + apiUrl: "https://mypetjournal-lqkz3.ondigitalocean.app/api", + // apiUrl: "/api", }, images: { unoptimized: true diff --git a/ui/src/components/LineRecordDialog.tsx b/ui/src/components/LineRecordDialog.tsx index 0d944ba..8d0b877 100644 --- a/ui/src/components/LineRecordDialog.tsx +++ b/ui/src/components/LineRecordDialog.tsx @@ -188,7 +188,7 @@ export default class LineRecordDialog extends Component
{/*Modal content*/} -
+
{/*Modal header*/}

diff --git a/ui/src/components/NavBar.tsx b/ui/src/components/NavBar.tsx index 6f4e9da..05cc66d 100644 --- a/ui/src/components/NavBar.tsx +++ b/ui/src/components/NavBar.tsx @@ -70,7 +70,9 @@ class NavBar extends BaseComponent { /> this.logout(() => this.props.router.replace("/auth/login"))} />

diff --git a/ui/src/components/PhoneInput.tsx b/ui/src/components/PhoneInput.tsx index f32537e..72a8b5d 100644 --- a/ui/src/components/PhoneInput.tsx +++ b/ui/src/components/PhoneInput.tsx @@ -29,6 +29,7 @@ export default function PhoneInput(props: PhoneInputProps) { +
{!this.props.hideNav && } {this.props.children}
diff --git a/ui/src/components/RecordDialog.tsx b/ui/src/components/RecordDialog.tsx index b691be3..19c36fd 100644 --- a/ui/src/components/RecordDialog.tsx +++ b/ui/src/components/RecordDialog.tsx @@ -469,7 +469,7 @@ export default class RecordDialog extends Component
{/*Modal content*/} -
+
{/*Modal header*/}
{this.state.pet && ( diff --git a/ui/src/components/TextInput.tsx b/ui/src/components/TextInput.tsx index 4e4eaac..a5a89c5 100644 --- a/ui/src/components/TextInput.tsx +++ b/ui/src/components/TextInput.tsx @@ -4,6 +4,7 @@ import styles from "./textInput.module.css" interface ButtonProps { id: string name: string + icon?: React.ReactElement type?: HTMLInputTypeAttribute required?: boolean autoComplete: string @@ -35,6 +36,9 @@ export default function TextInput(props: ButtonProps) { + {props.icon !== undefined &&
+ {props.icon} +
} void } -interface VetDialogState { +interface UserDialogState { title: string info: User show: boolean } -export default class VetDialog extends Component { - constructor(props: VetDialogProps) { +export default class UserDialog extends Component { + constructor(props: UserDialogProps) { super(props) this.state = { title: "Vet Information", @@ -45,12 +45,12 @@ export default class VetDialog extends Component } render() { - const vet = this.state.info + const user = this.state.info return (
{/*Modal content*/} -
+
{/*Modal header*/}

{this.state.title}

@@ -67,31 +67,34 @@ export default class VetDialog extends Component {this.state.info !== undefined && (
- } /> +

- {vet.surname} {vet.name} + {user.surname} {user.name}

- {vet.email && ( + {user.email && ( - {vet.email} + {user.email} )} - {vet.phone && ( + {user.phone && user.phone.length > 3 && ( - {vet.phone} + {user.phone} )}
diff --git a/ui/src/components/button.module.css b/ui/src/components/button.module.css index ec945dd..04909bc 100644 --- a/ui/src/components/button.module.css +++ b/ui/src/components/button.module.css @@ -16,7 +16,7 @@ } .btnSecondary:hover { - @apply ring-2 ring-indigo-700 text-white; + @apply ring-1 ring-indigo-700 shadow-lg text-indigo-500 dark:text-white; } .btnSecondary:focus-visible { @@ -24,7 +24,7 @@ } .btnGroup { - @apply m-0 rounded-none first:rounded-l-lg first:ml-0 last:rounded-r-lg border focus:z-10; + @apply m-0 rounded-none first:rounded-l-lg first:ml-0 last:rounded-r-lg border-0 focus:z-10 shadow-sm; } .btnPrimaryDisabled { diff --git a/ui/src/components/deleteModal.module.css b/ui/src/components/deleteModal.module.css index 1740470..c05397e 100644 --- a/ui/src/components/deleteModal.module.css +++ b/ui/src/components/deleteModal.module.css @@ -7,7 +7,7 @@ } .content { - @apply relative rounded-lg shadow bg-gray-700 + @apply relative rounded-lg shadow bg-gray-700/60 backdrop-blur-lg } .btnDelete { diff --git a/ui/src/components/navbar.module.css b/ui/src/components/navbar.module.css index c6931e2..7a7ee2c 100644 --- a/ui/src/components/navbar.module.css +++ b/ui/src/components/navbar.module.css @@ -1,5 +1,5 @@ .navbar { - @apply sticky border-gray-200 bg-slate-800; + @apply sticky border-gray-200 bg-slate-900; } .rightSideContainer { diff --git a/ui/src/components/textInput.module.css b/ui/src/components/textInput.module.css index 3049447..c4b239f 100644 --- a/ui/src/components/textInput.module.css +++ b/ui/src/components/textInput.module.css @@ -1,5 +1,5 @@ .textInput { - @apply relative flex border-0 py-1.5 text-gray-900 dark:text-slate-300 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6 + @apply flex border-0 py-1.5 text-gray-900 dark:text-slate-300 ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:z-10 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6 dark:bg-slate-700 dark:ring-slate-600; } @@ -8,7 +8,7 @@ } .label { - @apply text-gray-900 dark:text-slate-300 text-sm mb-2; + @apply text-indigo-900 dark:text-slate-300 text-sm mb-2; } .textInputFull { @@ -24,7 +24,7 @@ } .textInputContainer { - @apply w-full flex flex-col; + @apply w-full flex flex-col relative; } .phoneInput { diff --git a/ui/src/pages/account.tsx b/ui/src/pages/account.tsx index 1d72f7f..e74bdb8 100644 --- a/ui/src/pages/account.tsx +++ b/ui/src/pages/account.tsx @@ -207,15 +207,16 @@ class Account extends BaseComponent { } return ( - -
+ +
-
-

-
-

+

{this.state.viewOnly ? "Account Information" : "Update Account Information"}

diff --git a/ui/src/pages/auth/login.tsx b/ui/src/pages/auth/login.tsx index eaad91b..8faaea4 100644 --- a/ui/src/pages/auth/login.tsx +++ b/ui/src/pages/auth/login.tsx @@ -74,9 +74,19 @@ class Login extends BaseComponent { render() { return (
- } /> + + } + />
-
+

@@ -122,7 +132,14 @@ class Login extends BaseComponent { />

-
diff --git a/ui/src/pages/auth/signup.tsx b/ui/src/pages/auth/signup.tsx index 575b453..d18a701 100644 --- a/ui/src/pages/auth/signup.tsx +++ b/ui/src/pages/auth/signup.tsx @@ -2,12 +2,8 @@ import Button from "@/components/Button" import React from "react" import {UserType, UserTypeUtils} from "@/enums/UserType" import countries from "i18n-iso-countries" -import PhoneInput from "@/components/PhoneInput" import "react-phone-input-2/lib/material.css" -import TextUtils from "@/Utils/TextUtils" import TextInput from "@/components/TextInput" -import textInputStyle from "@/components/textInput.module.css" -import styles from "@/components/textInput.module.css" import {withRouter} from "next/router" import NavBar from "@/components/NavBar" import {Auth} from "@/models/user/User" @@ -72,42 +68,6 @@ class Signup extends BaseComponent { this.setState({vm}) } - private onCountryChange = (event: any) => { - const vm = this.state.vm - vm.country = event.currentTarget.value - this.setState({vm}) - } - - private onCityChange = (value: string) => { - const vm = this.state.vm - vm.city = value - this.setState({vm}) - } - - private onStateChange = (value: string) => { - const vm = this.state.vm - vm.state = value - this.setState({vm}) - } - - private onZipChange = (value: string) => { - const vm = this.state.vm - vm.zip = value - this.setState({vm}) - } - - private onAddressChange = (value: string) => { - const vm = this.state.vm - vm.address = value - this.setState({vm}) - } - - private onPhoneChanged = (phone: string) => { - const vm = this.state.vm - vm.phone = phone - this.setState({vm}) - } - private checkName = () => { this.state.vm.checkName() this.forceUpdate() @@ -164,11 +124,21 @@ class Signup extends BaseComponent { const vm = this.state.vm return (
- } /> + + } + />
-
+
-

+

Create your account

@@ -197,7 +167,7 @@ class Signup extends BaseComponent { required width={"full"} classNames="rounded-s-md" - placeholder="Name" + placeholder="Name*" value={vm.name} onInput={this.onNameChange} onBlur={this.checkName} @@ -213,7 +183,7 @@ class Signup extends BaseComponent { required width={"full"} classNames="rounded-e-md" - placeholder="Surname" + placeholder="Surname*" value={vm.surname} onInput={this.onSurnameChange} onBlur={this.checkSurname} @@ -223,39 +193,39 @@ class Signup extends BaseComponent { />
-
- + - -
+ + ) + } + render() { - const sortedPets = this.state.pets.sort((a, b) => new Date(a.createdAt!).getTime() - new Date(b.createdAt!).getTime()) + const sortedPets = this.filteredPets.sort((a, b) => new Date(a.createdAt!).getTime() - new Date(b.createdAt!).getTime()) return ( -
-

Pets

+
+

Pets

+ + } + type={"search"} + id={"pet-filter"} + name={"filter"} + autoComplete={"off"} + placeholder={"Search pet name or owner name or email..."} + onInput={this.onFilterInputChange} + classNames="p-4 ps-10 rounded-md shadow hover:shadow-lg" + /> + + {this.state.loading ? (
{
{sortedPets.map((pet) => { return ( - -
+ +
-
{pet.name}
-
-
- Breed: {TextUtils.valueOrEmpty(pet.breedName, "-")} +
+ {pet.name} +
+
+ {TextUtils.valueOrEmpty(pet.breedName, "-")} +
+
+
+ +
+
Pet Owner Info
+
+ {pet.owner?.surname} {pet.owner?.name}
-
- Gender: {TextUtils.valueOrEmpty(PetGenderUtils.getTitle(pet.gender!), "-")} +
+ {TextUtils.valueOrEmpty(pet.owner?.email!, "-")}
) })} - + {this.petCreateButton}
) : ( - //
- // - //

Create your first pet

- //
- + {this.petCreateButton}
)} diff --git a/ui/src/pages/pet/[id]/edit.tsx b/ui/src/pages/pet/[id]/edit.tsx index aad6bc1..48d73a0 100644 --- a/ui/src/pages/pet/[id]/edit.tsx +++ b/ui/src/pages/pet/[id]/edit.tsx @@ -303,9 +303,7 @@ class Edit extends BaseComponent { init={this.initPage} className={"bg-[url('/register-bg-dark.jpg')] bg-contain bg-center overflow-y-auto"} > - {/*
*/} - -
+
@@ -315,7 +313,6 @@ class Edit extends BaseComponent {
this.deleteDialogRef?.show()} />
-
@@ -329,7 +326,6 @@ class Edit extends BaseComponent { className={"h-[90px] w-[90px]"} />
- (this.imageInputRef = ref)} className={`sr-only`} @@ -341,7 +337,6 @@ class Edit extends BaseComponent { onChange={this.onImageChange} />
- { errorMessage={vm.nameError} showLabel={true} /> - import("@/components/ProtectedPage"), { class PetPage extends BaseComponent { private weightEntriesDialogRef: LineRecordDialog | null = null - private vetDialogRef: VetDialog | null = null + private userDialogRef: UserDialog | null = null private recordDialogRef: RecordDialog | null = null private deleteDialogRef: DeleteModal | null = null @@ -296,42 +292,55 @@ class PetPage extends BaseComponent { private get petCard() { const pet = this.state.pet! return ( -
-
+
+
-

{pet.name}

-
+
-
-
-

breed :

-

{pet.breedName}

-
-
-

Age :

-

{this.getAge(pet)}

-
-
-

gender :

-

{PetGenderUtils.getTitle(pet.gender)}

+
+

+ {pet.name} +

+
+
+

+ breed : +

+

{pet.breedName}

+
+
+

+ Age : +

+

{this.getAge(pet)}

+
+
+

+ gender : +

+

+ {PetGenderUtils.getTitle(pet.gender)} +

+
{pet.colors && pet.colors.length > 0 && (
-

colors:

+

+ Colors : +

{pet.colors.map((color, index) => (
))}
@@ -339,22 +348,29 @@ w-[15px] lg:h-[20px] lg:w-[20px] text-center text-xl font-bold ring-1 ring-slate )} {pet.pedigree && (
-

pedigree :

-

{pet.pedigree}

+

+ pedigree : +

+

{pet.pedigree}

)} {pet.microchip && (
-

microchip :

-

{pet.microchip}

+

+ microchip : +

+

+ {pet.microchip} +

)}
- {/*

{pet.name}

*/} {pet.description && ( -

{pet.description}

+

+ {pet.description} +

)}
@@ -362,30 +378,30 @@ w-[15px] lg:h-[20px] lg:w-[20px] text-center text-xl font-bold ring-1 ring-slate {pet.vet !== undefined && TextUtils.isNotEmpty(pet.vet?.id) && (
{ - this.vetDialogRef?.setData(this.state.pet!.vet!) - this.vetDialogRef?.setTitle("Vet Information") - this.vetDialogRef?.show() + this.userDialogRef?.setData(this.state.pet!.vet!) + this.userDialogRef?.setTitle("Vet Information") + this.userDialogRef?.show() }} > - Show Vet Info + Vet Info
)} {pet.owner !== undefined && TextUtils.isNotEmpty(pet.owner?.name) && (
{ - this.vetDialogRef?.setData(this.state.pet!.owner!) - this.vetDialogRef?.setTitle("Owner Information") - this.vetDialogRef?.show() + this.userDialogRef?.setData(this.state.pet!.owner!) + this.userDialogRef?.setTitle("Owner Information") + this.userDialogRef?.show() }} > - Show Owner Info + Owner Info
)} @@ -417,9 +433,9 @@ w-[15px] lg:h-[20px] lg:w-[20px] text-center text-xl font-bold ring-1 ring-slate private getColors(type: RecordType): RecordColor { switch (type) { case RecordType.TEMPERATURE: - return {main: "#22d3ee", tooltip: "#0891b2", dot: "#06b6d4",backgroundColor: "#1E293B"} + return {main: "#22d3ee", tooltip: "#0891b2", dot: "#06b6d4", backgroundColor: "#1E293B"} default: - return {main: "#818CF8", tooltip: "#4F46E5", dot: "#6366F1",backgroundColor: "#1E293B"} + return {main: "#818CF8", tooltip: "#4F46E5", dot: "#6366F1", backgroundColor: "#1E293B"} } } @@ -431,7 +447,7 @@ w-[15px] lg:h-[20px] lg:w-[20px] text-center text-xl font-bold ring-1 ring-slate
@@ -450,8 +466,10 @@ w-[15px] lg:h-[20px] lg:w-[20px] text-center text-xl font-bold ring-1 ring-slate }} >

{RecordTypeUtils.getTitle(it)} @@ -461,12 +479,14 @@ w-[15px] lg:h-[20px] lg:w-[20px] text-center text-xl font-bold ring-1 ring-slate

@@ -480,7 +500,13 @@ w-[15px] lg:h-[20px] lg:w-[20px] text-center text-xl font-bold ring-1 ring-slate - + @@ -521,9 +547,9 @@ w-[15px] lg:h-[20px] lg:w-[20px] text-center text-xl font-bold ring-1 ring-slate { - this.vetDialogRef?.setData(r.verifiedBy!) - this.vetDialogRef?.setTitle("Vet Information") - this.vetDialogRef?.show() + this.userDialogRef?.setData(r.verifiedBy!) + this.userDialogRef?.setTitle("Vet Information") + this.userDialogRef?.show() }} /> ) : ( @@ -581,14 +607,44 @@ w-[15px] lg:h-[20px] lg:w-[20px] text-center text-xl font-bold ring-1 ring-slate return <> } const records = this.state.records.sort((a, b) => a.date! - b.date!).filter((it) => it.administeredBy !== undefined) + const expired = this.state.records + .sort((a, b) => a.date! - b.date!) + .filter((it) => it.administeredBy === undefined && isBefore(new Date(it.date!), new Date())) const upcoming = this.state.records.sort((a, b) => a.date! - b.date!).filter((it) => it.administeredBy === undefined) const expandedUpcoming = this.state.expandedTypes.get(this.REMINDER) return records.length > 0 ? (
+ {expired.length > 0 && ( +
+
+
this.updateExpanded(this.REMINDER, !expandedUpcoming)} + > + Upcoming + {expandedUpcoming ? ( + + ) : ( + + )} +
+
+
+
+
Name
+
Date
+
+ {upcoming.map((record) => this.recordEntry(record, true))} +
+
+ )} {upcoming.length > 0 && (
Name
Date
- {upcoming.map((record)=>this.recordEntry(record, true))} + {upcoming.map((record) => this.recordEntry(record, true))}
)} @@ -696,7 +752,7 @@ w-[15px] lg:h-[20px] lg:w-[20px] text-center text-xl font-bold ring-1 ring-slate
@@ -714,8 +770,10 @@ w-[15px] lg:h-[20px] lg:w-[20px] text-center text-xl font-bold ring-1 ring-slate }} >

{RecordViewTypeUtils.getTitle(it)} @@ -723,7 +781,10 @@ w-[15px] lg:h-[20px] lg:w-[20px] text-center text-xl font-bold ring-1 ring-slate ))}

- +
{this.state.recordViewType === RecordViewType.RECORDS && this.recordsListView} {this.state.recordViewType === RecordViewType.AGENDA && this.calendarListView} @@ -793,7 +854,7 @@ w-[15px] lg:h-[20px] lg:w-[20px] text-center text-xl font-bold ring-1 ring-slate onUpdate={this.onUpdateLineRecord} onDelete={this.onDeleteLineRecord} /> - (this.vetDialogRef = ref)} onDismiss={() => this.vetDialogRef?.hide()} /> + (this.userDialogRef = ref)} onDismiss={() => this.userDialogRef?.hide()} /> (this.recordDialogRef = ref)} onDismiss={() => this.recordDialogRef?.hide()} diff --git a/ui/src/pages/pet/create.tsx b/ui/src/pages/pet/create.tsx index 4ecd3ed..c806743 100644 --- a/ui/src/pages/pet/create.tsx +++ b/ui/src/pages/pet/create.tsx @@ -245,8 +245,8 @@ class Create extends BaseComponent { render() { const vm = this.state.vm return ( - -
+ +

Create a Pet profile @@ -254,14 +254,14 @@ class Create extends BaseComponent {
{this.state.vm.avatar && } -
+
{ this.imageInputRef?.click() }} - textStyle={"text-lg h-[90px] w-[90px]"} + textStyle={"text-lg h-[90px] w-[90px] hover:shadow-xl"} />
@@ -326,6 +326,7 @@ class Create extends BaseComponent { className={`${styles.textInput} ${styles.textInputFull} ${ vm.hasGenderError && styles.errorHighlight } rounded-md`} + required > {PetGenderUtils.getAll().map((g) => {