Skip to content

Commit

Permalink
Fixed multiple bugs (#128)
Browse files Browse the repository at this point in the history
1. Fixed location update bug. Updated location will be validated.

Valid Update:

![Screenshot 2023-12-10
165235](https://github.com/gcivil-nyu-org/INET-Monday-Fall2023-Team-1/assets/71821708/b567ed6b-b309-4314-bf73-4bf949e72dcf)

2. Default location is auto-selected when the user starts to create a
new job (Add Job tab).

For example, if Bobst Library is the default location:

![Screenshot 2023-12-10
170116](https://github.com/gcivil-nyu-org/INET-Monday-Fall2023-Team-1/assets/71821708/e69b3c1d-110b-4edd-9a81-acc513a2062d)

When adding a new job, the location will be auto-selected as Bobst
Library.

![Screenshot 2023-12-10
170159](https://github.com/gcivil-nyu-org/INET-Monday-Fall2023-Team-1/assets/71821708/3d554c67-bf10-44df-b583-7d7a3c930e87)

3. A location currently set as default can be unset as default.
4. Updated UI of the location cards.
  • Loading branch information
rajghodasara1 authored Dec 11, 2023
1 parent 9c4bae4 commit 47b868b
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 57 deletions.
9 changes: 6 additions & 3 deletions frontend/src/Jobs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ interface Location {
city: string;
country: string;
zipcode: string;
default_location: boolean;
}

interface Pet {
Expand Down Expand Up @@ -310,9 +311,11 @@ const JobPage: React.FC<JobPageProps> = () => {
return axios
.get(API_ROUTES.USER.LOCATION)
.then((response) => {
//console.log(response, response.data);
setLocations(response?.data ?? []);
// return response;
const default_location = response.data.filter((location: Location) => location.default_location);
if (default_location.length > 0) {
setJobFormData({ ...jobFormData, location: default_location[0].id });
}
})
.catch((err) => {
console.error("failed to fetch locations", err);
Expand All @@ -333,7 +336,7 @@ const JobPage: React.FC<JobPageProps> = () => {
.post(API_ROUTES.JOBS, jobFormData)
.then((response) => {
if (response.status === 201) {
toast.success("Job Addedd Successfully");
toast.success("Job Added Successfully");
setJobFormData({
pet: "",
location: "",
Expand Down
54 changes: 36 additions & 18 deletions frontend/src/Locations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const Locations = () => {
const [locations, setLocations] = useState<FurbabyLocation[]>([]);
const [address, setAddress] = useState("");
const [city, setCity] = useState("New York City");
const [country, setCountry] = useState("usa");
const [country, setCountry] = useState("USA");
const [zipcode, setZipcode] = useState("");

const onClickConfirm = () => {
Expand Down Expand Up @@ -47,9 +47,11 @@ const Locations = () => {
};

const onCloseModal = () => {
setEditLocationId("");
setAddress("");
setCity("");
setCountry("");
setCity("New York City");
setCountry("USA");
setZipcode("");
setOpen(false);
};

Expand All @@ -71,9 +73,9 @@ const Locations = () => {
getLocations(); //.then((response) => {
}, []);

const setAsDefault = (location: FurbabyLocation) => {
const updateDefault = (location: FurbabyLocation, newDefault: boolean) => {
axios
.put(API_ROUTES.USER.LOCATION, JSON.stringify({ ...location, default_location: true }))
.put(API_ROUTES.USER.LOCATION, { ...location, default_location: newDefault })
.then((resp) => {
console.log(resp);
})
Expand All @@ -99,19 +101,32 @@ const Locations = () => {
<div className="grid gap-x-8 gap-y-4 grid-cols-1 sm:grid-cols-2 md:grid-cols-3">
{locations.map((loc, index) => (
<div className="card w-96 bg-base-100 shadow-md" key={loc.id}>
{loc.default_location && (
<div className="absolute top-7 right-7">
<div className="badge badge-outline">
Default
</div>
</div>
)}
<div className="card-body">
<h2 className="card-title">Location {index + 1}</h2>
<p className="prose">{loc.address}</p>
<p className="prose">
{loc.city}, {loc.country} - {loc.zipcode}
</p>
<div className="card-actions justify-between items-center">
{loc.default_location && <div className="badge badge-outline">Default</div>}
<button className="btn btn-secondary" onClick={() => onClickEdit(loc)}>
<div className="card-actions justify-between items-center mt-4">
<button className="px-3 py-2 text-sm font-medium text-center text-white bg-blue-400 rounded-lg hover:bg-blue-600 focus:outline-none transition ease-in-out duration-150"
onClick={() => onClickEdit(loc)}>
Edit
</button>
{!loc.default_location && (
<button className="btn btn-primary" onClick={() => setAsDefault(loc)}>
{loc.default_location ? (
<button className="px-3 py-2 text-sm font-medium text-center text-white bg-red-300 rounded-lg hover:bg-red-400 focus:outline-none transition ease-in-out duration-150"
onClick={() => updateDefault(loc, false)}>
Remove Default
</button>
) : (
<button className="px-3 py-2 text-sm font-medium text-center text-white bg-green-400 rounded-lg hover:bg-green-600 focus:outline-none transition ease-in-out duration-150"
onClick={() => updateDefault(loc, true)}>
Set as default
</button>
)}
Expand All @@ -132,24 +147,28 @@ const Locations = () => {
}, [locations]);

const onClickEditConfirm = () => {
console.log(editLocationId);
axios
.put(
API_ROUTES.USER.LOCATION,
JSON.stringify({
{
id: editLocationId,
address,
city,
zipcode,
country,
})
zipcode,
}
)
.then(() => {
toast.success("your changes have been saved");
.then((response) => {
// TODO: handle response
//console.log(response);
if (response.status === 200) {
onCloseModal();
toast.success("Location updated successfully.");
}
})
.catch((err) => {
// TODO: handle error
toast.error("Failed to update location.");
console.error(err);
});
};
Expand Down Expand Up @@ -186,10 +205,9 @@ const Locations = () => {
autoComplete="country-name"
value={country}
onChange={(e) => setCountry(e.target.value)}
defaultValue="usa"
className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:max-w-xs sm:text-sm sm:leading-6"
>
<option value="usa">United States</option>
<option value="USA">USA</option>
</select>
</div>
</div>
Expand Down
16 changes: 13 additions & 3 deletions furbaby/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,24 @@ def validate(self, data):
raise ValidationError("Users must be located in New York City/NYC")
if country not in countries_allowed_list:
raise ValidationError("Users must be located in the United States of America/USA")
if data.get("default_location", True):
# If the user is setting a default location, set all other locations to false
Locations.objects.filter(user_id=data.get("user").id).update(default_location=False)
return data

def create(self, validated_data):
return Locations.objects.create(**validated_data)

def update(self, instance, validated_data):
instance.address = validated_data.get("address", instance.address)
instance.city = validated_data.get("city", instance.city)
instance.country = validated_data.get("country", instance.country)
instance.zipcode = validated_data.get("zipcode", instance.zipcode)
if validated_data.get("default_location"):
Locations.objects.filter(user=instance.user).update(default_location=False)
instance.default_location = True
if not validated_data.get("default_location"):
instance.default_location = False
instance.save()
return instance


class PetSerializer(serializers.ModelSerializer):
owner = serializers.HiddenField(default=serializers.CurrentUserDefault())
Expand Down
5 changes: 1 addition & 4 deletions furbaby/api/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,6 @@ def test_location_update_missing_location_id(self):
"city": "New York City",
"country": "USA",
"zipcode": "12345",
"default_location": True,
}
response = client.put(url, data, format="json")
data = json.loads(response.content)
Expand All @@ -912,7 +911,6 @@ def test_location_update_location_does_not_exist(self):
"city": "New York City",
"country": "USA",
"zipcode": "12345",
"default_location": True,
}
response = client.put(url, data, format="json")
data = json.loads(response.content)
Expand All @@ -937,9 +935,8 @@ def test_location_update_successful(self):
"id": location.id,
"address": "456 Main St",
"city": "NYC",
"country": "US",
"country": "USA",
"zipcode": "45678",
"default_location": True,
}
response = client.put(url, data, format="json")
data = json.loads(response.content)
Expand Down
69 changes: 40 additions & 29 deletions furbaby/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ def get_user_location_by_id(self, request):

# takes as input a user_id and returns a JSON of all the locations for that user
def get_user_locations(self, request):
locations = Locations.objects.filter(user_id=request.user.id)
locations = Locations.objects.filter(user_id=request.user.id).order_by("created_at")
location_list = [
{
"id": location.id,
Expand All @@ -464,36 +464,52 @@ def update_location_record(self, request):
)

try:
updated_fields = []
location = Locations.objects.get(id=location_id)
if "address" in request.data:
location.address = request.data["address"]
updated_fields.append("address")
if "city" in request.data:
location.city = request.data["city"]
updated_fields.append("city")
if "country" in request.data:
location.country = request.data["country"]
updated_fields.append("country")
if "zipcode" in request.data:
location.zipcode = request.data["zipcode"]
updated_fields.append("zipcode")
if "default_location" in request.data:
if request.data["default_location"] == True:
# unset all other locations as default
Locations.objects.filter(user_id=request.user.id).update(default_location=False)
location.default_location = request.data["default_location"]
updated_fields.append("default_location")

# location.save()
location.save(update_fields=updated_fields)
if "default_location" not in request.data:
request.data["default_location"] = location.default_location
serializer = self.serializer_class(
location, data=request.data, partial=True, context={"request": request}
)
if not serializer.is_valid():
return json_response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)

serializer.save()
return json_response(
self.get_location_record(location),
location.id,
status.HTTP_200_OK,
safe=False,
include_data=False,
)

# updated_fields = []
# if "address" in request.data:
# location.address = request.data["address"]
# updated_fields.append("address")
# if "city" in request.data:
# location.city = request.data["city"]
# updated_fields.append("city")
# if "country" in request.data:
# location.country = request.data["country"]
# updated_fields.append("country")
# if "zipcode" in request.data:
# location.zipcode = request.data["zipcode"]
# updated_fields.append("zipcode")
# if "default_location" in request.data:
# if request.data["default_location"] == True:
# # unset all other locations as default
# Locations.objects.filter(user_id=request.user.id).update(default_location=False)
# location.default_location = request.data["default_location"]
# updated_fields.append("default_location")
#
# # location.save()
# location.save(update_fields=updated_fields)
#
# return json_response(
# self.get_location_record(location),
# status.HTTP_200_OK,
# safe=False,
# include_data=False,
# )
except Locations.DoesNotExist:
return json_response(
data={
Expand Down Expand Up @@ -816,7 +832,6 @@ def get(self, request, *args, **kwargs):
return JsonResponse(response_data, safe=False)

elif "sitter" in request.user.user_type:
# print("here")
queryset_sitter = self.get_all()
serializer_sitter = JobSerializer(queryset_sitter, many=True)
response_data = {
Expand All @@ -829,7 +844,6 @@ def put(self, request, *args, **kwargs):
job_id = self.request.data.get("id") # type: ignore
try:
job = Jobs.objects.get(id=job_id)
# print(job.status)
if job.status == "open":
job.status = "acceptance_complete"
job.save()
Expand Down Expand Up @@ -889,7 +903,6 @@ def get(self, request, *args, **kwargs):
def put(self, request, *args, **kwargs):
# Retrieve the application ID from the URL or request data
application_id = request.data.get("id")
# print(application_id)
try:
application = Applications.objects.get(id=application_id)
except Applications.DoesNotExist:
Expand All @@ -898,7 +911,6 @@ def put(self, request, *args, **kwargs):

# Check if the user making the request is the owner of the application
if request.user == job_instance.user:
# print(request.user)
# Check if the job status is "open"
if job_instance.status == "open":
# Update the application status based on your requirements
Expand Down Expand Up @@ -932,7 +944,6 @@ def put(self, request, *args, **kwargs):

def post(self, request, *args, **kwargs):
job_id = self.request.data.get("id") # type: ignore
# print(request.data)
# print(job_id)
try:
job = Jobs.objects.get(id=job_id)
Expand Down

0 comments on commit 47b868b

Please sign in to comment.