Age input when editing/adding pet profile
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
package com.petshop.backend.dto.pet;
|
package com.petshop.backend.dto.pet;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Max;
|
||||||
|
import jakarta.validation.constraints.Min;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
@@ -16,6 +18,10 @@ public class MyPetRequest {
|
|||||||
@Size(max = 50, message = "Breed must not exceed 50 characters")
|
@Size(max = 50, message = "Breed must not exceed 50 characters")
|
||||||
private String breed;
|
private String breed;
|
||||||
|
|
||||||
|
@Min(value = 0, message = "Age must be 0 or greater")
|
||||||
|
@Max(value = 100, message = "Age must not exceed 100")
|
||||||
|
private Integer petAge;
|
||||||
|
|
||||||
public String getPetName() {
|
public String getPetName() {
|
||||||
return petName;
|
return petName;
|
||||||
}
|
}
|
||||||
@@ -39,4 +45,12 @@ public class MyPetRequest {
|
|||||||
public void setBreed(String breed) {
|
public void setBreed(String breed) {
|
||||||
this.breed = breed;
|
this.breed = breed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getPetAge() {
|
||||||
|
return petAge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPetAge(Integer petAge) {
|
||||||
|
this.petAge = petAge;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,17 +6,19 @@ public class MyPetResponse {
|
|||||||
private String petName;
|
private String petName;
|
||||||
private String species;
|
private String species;
|
||||||
private String breed;
|
private String breed;
|
||||||
|
private Integer petAge;
|
||||||
private String imageUrl;
|
private String imageUrl;
|
||||||
private String petStatus;
|
private String petStatus;
|
||||||
|
|
||||||
public MyPetResponse() {
|
public MyPetResponse() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MyPetResponse(Long customerPetId, String petName, String species, String breed, String imageUrl, String petStatus) {
|
public MyPetResponse(Long customerPetId, String petName, String species, String breed, Integer petAge, String imageUrl, String petStatus) {
|
||||||
this.customerPetId = customerPetId;
|
this.customerPetId = customerPetId;
|
||||||
this.petName = petName;
|
this.petName = petName;
|
||||||
this.species = species;
|
this.species = species;
|
||||||
this.breed = breed;
|
this.breed = breed;
|
||||||
|
this.petAge = petAge;
|
||||||
this.imageUrl = imageUrl;
|
this.imageUrl = imageUrl;
|
||||||
this.petStatus = petStatus;
|
this.petStatus = petStatus;
|
||||||
}
|
}
|
||||||
@@ -53,6 +55,14 @@ public class MyPetResponse {
|
|||||||
this.breed = breed;
|
this.breed = breed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getPetAge() {
|
||||||
|
return petAge;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPetAge(Integer petAge) {
|
||||||
|
this.petAge = petAge;
|
||||||
|
}
|
||||||
|
|
||||||
public String getImageUrl() {
|
public String getImageUrl() {
|
||||||
return imageUrl;
|
return imageUrl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -357,6 +357,7 @@ public class PetService {
|
|||||||
pet.getPetName(),
|
pet.getPetName(),
|
||||||
pet.getPetSpecies(),
|
pet.getPetSpecies(),
|
||||||
pet.getPetBreed(),
|
pet.getPetBreed(),
|
||||||
|
pet.getPetAge(),
|
||||||
pet.getImageUrl() != null && !pet.getImageUrl().isBlank() ? "/api/v1/pets/" + pet.getPetId() + "/image" : null,
|
pet.getImageUrl() != null && !pet.getImageUrl().isBlank() ? "/api/v1/pets/" + pet.getPetId() + "/image" : null,
|
||||||
pet.getPetStatus()
|
pet.getPetStatus()
|
||||||
);
|
);
|
||||||
@@ -366,7 +367,7 @@ public class PetService {
|
|||||||
pet.setPetName(request.getPetName().trim());
|
pet.setPetName(request.getPetName().trim());
|
||||||
pet.setPetSpecies(request.getSpecies().trim());
|
pet.setPetSpecies(request.getSpecies().trim());
|
||||||
pet.setPetBreed(normalizeOptional(request.getBreed()));
|
pet.setPetBreed(normalizeOptional(request.getBreed()));
|
||||||
pet.setPetAge(null);
|
pet.setPetAge(request.getPetAge());
|
||||||
pet.setPetPrice(null);
|
pet.setPetPrice(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ export default function ProfilePage() {
|
|||||||
const [petName, setPetName] = useState("");
|
const [petName, setPetName] = useState("");
|
||||||
const [species, setSpecies] = useState("");
|
const [species, setSpecies] = useState("");
|
||||||
const [breed, setBreed] = useState("");
|
const [breed, setBreed] = useState("");
|
||||||
|
const [petAge, setPetAge] = useState("1");
|
||||||
const [submitting, setSubmitting] = useState(false);
|
const [submitting, setSubmitting] = useState(false);
|
||||||
const [petError, setPetError] = useState(null);
|
const [petError, setPetError] = useState(null);
|
||||||
const [profileForm, setProfileForm] = useState({ fullName: "", email: "", phone: "" });
|
const [profileForm, setProfileForm] = useState({ fullName: "", email: "", phone: "" });
|
||||||
@@ -230,6 +231,7 @@ if (user?.role === "CUSTOMER" || user?.role === "ADMIN") {
|
|||||||
setPetName("");
|
setPetName("");
|
||||||
setSpecies("");
|
setSpecies("");
|
||||||
setBreed("");
|
setBreed("");
|
||||||
|
setPetAge("1");
|
||||||
setPetError(null);
|
setPetError(null);
|
||||||
setShowForm(true);
|
setShowForm(true);
|
||||||
}
|
}
|
||||||
@@ -239,6 +241,7 @@ if (user?.role === "CUSTOMER" || user?.role === "ADMIN") {
|
|||||||
setPetName(pet.petName);
|
setPetName(pet.petName);
|
||||||
setSpecies(pet.species);
|
setSpecies(pet.species);
|
||||||
setBreed(pet.breed || "");
|
setBreed(pet.breed || "");
|
||||||
|
setPetAge(pet.petAge != null ? String(pet.petAge) : "1");
|
||||||
setPetError(null);
|
setPetError(null);
|
||||||
setShowForm(true);
|
setShowForm(true);
|
||||||
}
|
}
|
||||||
@@ -265,7 +268,7 @@ if (user?.role === "CUSTOMER" || user?.role === "ADMIN") {
|
|||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
body: JSON.stringify({ petName, species, breed: breed || null }),
|
body: JSON.stringify({ petName, species, breed: breed || null, petAge: Number(petAge) }),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
@@ -485,6 +488,19 @@ if (user?.role === "CUSTOMER" || user?.role === "ADMIN") {
|
|||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
|
<label className="appt-label">
|
||||||
|
Age (years)
|
||||||
|
<select
|
||||||
|
className="appt-select"
|
||||||
|
value={petAge}
|
||||||
|
onChange={(e) => setPetAge(e.target.value)}
|
||||||
|
required
|
||||||
|
>
|
||||||
|
{Array.from({ length: 20 }, (_, i) => i + 1).map((n) => (
|
||||||
|
<option key={n} value={n}>{n}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
<div className="profile-pet-form-actions">
|
<div className="profile-pet-form-actions">
|
||||||
<button type="submit" className="appt-submit-btn" disabled={submitting}>
|
<button type="submit" className="appt-submit-btn" disabled={submitting}>
|
||||||
{submitting ? "Saving..." : editingPet ? "Save Changes" : "Add Pet"}
|
{submitting ? "Saving..." : editingPet ? "Save Changes" : "Add Pet"}
|
||||||
@@ -531,6 +547,7 @@ if (user?.role === "CUSTOMER" || user?.role === "ADMIN") {
|
|||||||
<span className="profile-pet-card-name">{pet.petName}</span>
|
<span className="profile-pet-card-name">{pet.petName}</span>
|
||||||
<span className="profile-pet-card-detail">{pet.species}</span>
|
<span className="profile-pet-card-detail">{pet.species}</span>
|
||||||
{pet.breed && <span className="profile-pet-card-detail">{pet.breed}</span>}
|
{pet.breed && <span className="profile-pet-card-detail">{pet.breed}</span>}
|
||||||
|
{pet.petAge != null && <span className="profile-pet-card-detail">Age: {pet.petAge === 0 ? "< 1 yr" : `${pet.petAge} yr${pet.petAge !== 1 ? "s" : ""}`}</span>}
|
||||||
</div>
|
</div>
|
||||||
<div className="profile-pet-card-actions">
|
<div className="profile-pet-card-actions">
|
||||||
<button type="button" className="profile-pet-edit-btn" onClick={() => openEditForm(pet)}>Edit</button>
|
<button type="button" className="profile-pet-edit-btn" onClick={() => openEditForm(pet)}>Edit</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user