add option to delete location in all subsequent months

- Added toggle in LocationDeleteForm for deleting locations from future months (disabled by default)
- Modified deleteLocationById action to support batch deletion across subsequent months
- When enabled, deletes all locations with same name in current and future months/years
- Only deletes user's own locations with proper data isolation
- Added translations for toggle text in Croatian and English
- Removed unused imports and variables to fix TypeScript warnings
- Uses efficient MongoDB deleteMany operation for bulk deletions

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-08-11 11:01:16 +02:00
parent 2cf338c50a
commit 1eac116a55
4 changed files with 45 additions and 15 deletions

View File

@@ -302,7 +302,7 @@ export const fetchLocationById = async (locationID:string) => {
return(billLocation);
};
export const deleteLocationById = withUser(async (user:AuthenticatedUser, locationID:string, yearMonth:YearMonth) => {
export const deleteLocationById = withUser(async (user:AuthenticatedUser, locationID:string, yearMonth:YearMonth, _prevState:any, formData: FormData) => {
noStore();
@@ -310,8 +310,35 @@ export const deleteLocationById = withUser(async (user:AuthenticatedUser, locati
const { id: userId } = user;
// find a location with the given locationID
await dbClient.collection<BillingLocation>("lokacije").deleteOne({ _id: locationID, userId });
const deleteInSubsequentMonths = formData.get('deleteInSubsequentMonths') === 'on';
if (deleteInSubsequentMonths) {
// Get the location name first to find all locations with the same name
const location = await dbClient.collection<BillingLocation>("lokacije")
.findOne({ _id: locationID, userId });
if (location) {
// Delete all locations with the same name in current and subsequent months
await dbClient.collection<BillingLocation>("lokacije").deleteMany({
userId,
name: location.name,
$or: [
{ "yearMonth.year": { $gt: yearMonth.year } },
{
"yearMonth.year": yearMonth.year,
"yearMonth.month": { $gte: yearMonth.month }
}
]
});
}
} else {
// Delete only the specific location (current behavior)
await dbClient.collection<BillingLocation>("lokacije").deleteOne({ _id: locationID, userId });
}
await gotoHome(yearMonth)
await gotoHome(yearMonth);
return {
message: null
};
})

View File

@@ -4,7 +4,6 @@ import { FC, ReactNode } from "react";
import { BillingLocation } from "../lib/db-types";
import { deleteLocationById } from "../lib/actions/locationActions";
import { useFormState } from "react-dom";
import { gotoUrl } from "../lib/actions/navigationActions";
import Link from "next/link";
import { useTranslations } from "next-intl";
@@ -16,14 +15,9 @@ export interface LocationDeleteFormProps {
export const LocationDeleteForm:FC<LocationDeleteFormProps> = ({ location }) =>
{
const handleAction = deleteLocationById.bind(null, location._id, location.yearMonth);
const [ state, dispatch ] = useFormState(handleAction, null);
const [ , dispatch ] = useFormState(handleAction, null);
const t = useTranslations("location-delete-form");
const handleCancel = () => {
gotoUrl(`/location/${location._id}/edit/`);
};
return(
<div className="card card-compact card-bordered min-w-[20em] max-w-[90em] bg-base-100 shadow-s my-1">
<div className="card-body">
@@ -36,6 +30,13 @@ export const LocationDeleteForm:FC<LocationDeleteFormProps> = ({ location }) =>
})
}
</p>
<div className="form-control">
<label className="label cursor-pointer">
<span className="label-text">{t("delete-in-subsequent-months")}</span>
<input type="checkbox" name="deleteInSubsequentMonths" className="toggle toggle-error" />
</label>
</div>
<div className="pt-4 text-center">
<button className="btn btn-primary w-[5.5em]">{t("confirm-button")}</button>
<Link className="btn btn-neutral w-[5.5em] ml-3" href={`/location/${location._id}/edit/`}>{t("cancel-button")}</Link>