diff --git a/app/lib/actions/locationActions.ts b/app/lib/actions/locationActions.ts index d1ef4c4..d1b29ed 100644 --- a/app/lib/actions/locationActions.ts +++ b/app/lib/actions/locationActions.ts @@ -27,6 +27,7 @@ const FormSchema = (t:IntlTemplateFn) => z.object({ _id: z.string(), locationName: z.coerce.string().min(1, t("location-name-required")), locationNotes: z.string(), + addToSubsequentMonths: z.boolean().optional(), }) // dont include the _id field in the response .omit({ _id: true }); @@ -47,6 +48,7 @@ export const updateOrAddLocation = withUser(async (user:AuthenticatedUser, locat const validatedFields = FormSchema(t).safeParse({ locationName: formData.get('locationName'), locationNotes: formData.get('locationNotes'), + addToSubsequentMonths: formData.get('addToSubsequentMonths') === 'on', }); // If form validation fails, return errors early. Otherwise, continue... @@ -60,6 +62,7 @@ export const updateOrAddLocation = withUser(async (user:AuthenticatedUser, locat const { locationName, locationNotes, + addToSubsequentMonths, } = validatedFields.data; // update the bill in the mongodb @@ -80,6 +83,7 @@ export const updateOrAddLocation = withUser(async (user:AuthenticatedUser, locat } }); } else if(yearMonth) { + // Always add location to the specified month await dbClient.collection("lokacije").insertOne({ _id: (new ObjectId()).toHexString(), userId, @@ -89,6 +93,78 @@ export const updateOrAddLocation = withUser(async (user:AuthenticatedUser, locat yearMonth: yearMonth, bills: [], }); + + // If addToSubsequentMonths is enabled, add to all subsequent months + if (addToSubsequentMonths) { + // Find all subsequent months that exist in the database + const subsequentMonths = await dbClient.collection("lokacije") + .aggregate([ + { + $match: { + userId, + $or: [ + { "yearMonth.year": { $gt: yearMonth.year } }, + { + "yearMonth.year": yearMonth.year, + "yearMonth.month": { $gt: yearMonth.month } + } + ] + } + }, + { + $group: { + _id: { + year: "$yearMonth.year", + month: "$yearMonth.month" + } + } + }, + { + $project: { + _id: 0, + year: "$_id.year", + month: "$_id.month" + } + }, + { + $sort: { + year: 1, + month: 1 + } + } + ]) + .toArray(); + + // For each subsequent month, check if location with same name already exists + const locationsToInsert = []; + for (const monthData of subsequentMonths) { + const existingLocation = await dbClient.collection("lokacije") + .findOne({ + userId, + name: locationName, + "yearMonth.year": monthData.year, + "yearMonth.month": monthData.month + }); + + // Only add if location with same name doesn't already exist in that month + if (!existingLocation) { + locationsToInsert.push({ + _id: (new ObjectId()).toHexString(), + userId, + userEmail, + name: locationName, + notes: locationNotes, + yearMonth: { year: monthData.year, month: monthData.month }, + bills: [], + }); + } + } + + // Insert all new locations at once if any + if (locationsToInsert.length > 0) { + await dbClient.collection("lokacije").insertMany(locationsToInsert); + } + } } if(yearMonth) await gotoHome(yearMonth); @@ -235,7 +311,7 @@ export const deleteLocationById = withUser(async (user:AuthenticatedUser, locati const { id: userId } = user; // find a location with the given locationID - const post = await dbClient.collection("lokacije").deleteOne({ _id: locationID, userId }); + await dbClient.collection("lokacije").deleteOne({ _id: locationID, userId }); await gotoHome(yearMonth) }) \ No newline at end of file diff --git a/app/lib/auth.ts b/app/lib/auth.ts index 501c647..b63a207 100644 --- a/app/lib/auth.ts +++ b/app/lib/auth.ts @@ -7,17 +7,31 @@ import { defaultLocale } from '../i18n'; export const myAuth = () => { - // Ovo koristim u developmentu + /** - // const session:Session = { - // user: { - // id: "109754742613069927799", - // name: "Nikola Derežić", - // }, - // expires: "123", - // }; + Google auth does not work in development environment + - this is a hack to make it work in development environment + - it returns a fake session object which is used by the Next-Auth middleware + + Instructions: when in dev environment, uncomment the following code snippet + - this will return a fake session object which is used by the Next-Auth middleware + - when in production environment, comment the code snippet back + + Note: this is not a secure way to handle authentication, it is only for development purposes + - in production environment, the auth should be handled by the Next-Auth middleware + + Code snippet: - // return(Promise.resolve(session)); + const session:Session = { + user: { + id: "109754742613069927799", + name: "Nikola Derežić", + }, + expires: "123", + }; + + return(Promise.resolve(session)); + */ return(auth()); } diff --git a/app/ui/LocationEditForm.tsx b/app/ui/LocationEditForm.tsx index a64ea24..b3020f9 100644 --- a/app/ui/LocationEditForm.tsx +++ b/app/ui/LocationEditForm.tsx @@ -60,6 +60,16 @@ export const LocationEditForm:FC = ({ location, yearMonth ))} + {/* Show toggle only when adding a new location (not editing) */} + {!location && ( +
+ +
+ )} +
{ state.message && diff --git a/messages/en.json b/messages/en.json index 98edd7c..caa76ac 100644 --- a/messages/en.json +++ b/messages/en.json @@ -98,6 +98,7 @@ "save-button": "Save", "cancel-button": "Cancel", "delete-tooltip": "Delete realestate", + "add-to-subsequent-months": "Add to all subsequent months", "validation": { "location-name-required": "Relaestate name is required" } diff --git a/messages/hr.json b/messages/hr.json index cdc916b..41c8fb4 100644 --- a/messages/hr.json +++ b/messages/hr.json @@ -97,6 +97,7 @@ "save-button": "Spremi", "cancel-button": "Odbaci", "delete-tooltip": "Brisanje nekretnine", + "add-to-subsequent-months": "Dodaj u sve mjesece koji slijede", "validation": { "location-name-required": "Ime nekretnine je obavezno" }