-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
server action for race results associated with location in use
- Loading branch information
1 parent
36c1573
commit 253e6dc
Showing
8 changed files
with
275 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
"use server"; | ||
import { db } from "@/lib/db"; | ||
import { getSessionUser } from "@/utils/getSessionUser"; | ||
import { Routes } from "@/utils/router/Routes.constants"; | ||
import { revalidatePath } from "next/cache"; | ||
|
||
async function editRaceLocation( | ||
city: string, | ||
state: string, | ||
locationId: string | ||
): Promise<void> { | ||
const sessionUser = await getSessionUser(); | ||
|
||
if (!sessionUser || !sessionUser.userId) { | ||
throw new Error("User ID is required"); | ||
} | ||
|
||
const { userId } = sessionUser; | ||
|
||
const existingRaceLocation = await db.raceLocation.findFirst({ | ||
where: { id: locationId }, | ||
}); | ||
|
||
if (existingRaceLocation?.userId.toString() !== userId) { | ||
throw new Error("Current user does not own this race location"); | ||
} | ||
|
||
await db.raceLocation.update({ | ||
where: { id: locationId }, | ||
data: { | ||
city, | ||
state, | ||
}, | ||
}); | ||
await db.raceResult.updateMany({ | ||
where: { raceLocationId: locationId, userId }, | ||
data: { | ||
city, | ||
state, | ||
}, | ||
}); | ||
|
||
revalidatePath(Routes.ManageRaceLocations, "layout"); | ||
} | ||
|
||
export default editRaceLocation; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
"use server"; | ||
import { IPersonalResult } from "@/components/personal-results/PersonalResults.types"; | ||
import { db } from "@/lib/db"; | ||
import { getSessionUser } from "@/utils/getSessionUser"; | ||
import { Routes } from "@/utils/router/Routes.constants"; | ||
import { revalidatePath } from "next/cache"; | ||
|
||
async function getRaceResultsAssociatedWithLocation( | ||
locationId: string | ||
): Promise<{ | ||
resultsAssociatedWithLocation: IPersonalResult[]; | ||
}> { | ||
const sessionUser = await getSessionUser(); | ||
|
||
if (!sessionUser || !sessionUser.userId) { | ||
throw new Error("User ID is required"); | ||
} | ||
|
||
const { userId } = sessionUser; | ||
|
||
const resultsAssociatedWithLocation: IPersonalResult[] = | ||
await db.raceResult.findMany({ | ||
where: { raceLocationId: locationId, userId }, | ||
}); | ||
|
||
revalidatePath(Routes.ManageRaceLocations, "layout"); | ||
|
||
return { | ||
resultsAssociatedWithLocation, | ||
}; | ||
} | ||
|
||
export default getRaceResultsAssociatedWithLocation; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
components/locations-list/edit-race-location-dialog/EditRaceLocationDialog.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
"use client"; | ||
|
||
import { Button } from "@/components/ui/button"; | ||
import { Input } from "@/components/ui/input"; | ||
import { Dialog } from "@/components/dialog/Dialog"; | ||
import { useState } from "react"; | ||
import { Pencil } from "lucide-react"; | ||
import { SubmitButton } from "@/components/buttons/submit-button/SubmitButton"; | ||
import { Tab } from "@/components/tabs/Tabs.constants"; | ||
import { useToast } from "@/hooks/use-toast"; | ||
import editRaceLocation from "@/app/actions/editRaceLocation"; | ||
import { | ||
Select, | ||
SelectContent, | ||
SelectItem, | ||
SelectTrigger, | ||
SelectValue, | ||
} from "@/components/ui/select"; | ||
import { states } from "@/components/personal-results/PersonalResults.constants"; | ||
|
||
interface IProps { | ||
city: string; | ||
state: string; | ||
locationId: string; | ||
} | ||
|
||
export const EditRaceLocationDialog = (props: IProps) => { | ||
const [open, setOpen] = useState<boolean>(false); | ||
const { toast } = useToast(); | ||
|
||
const onSubmit = async (formData: FormData) => { | ||
const city = formData.get("city") as string; | ||
const state = formData.get("state") as string; | ||
|
||
await editRaceLocation(city, state, props.locationId); | ||
toast({ | ||
title: "Successfully updated race location", | ||
}); | ||
setOpen(false); | ||
}; | ||
|
||
return ( | ||
<Dialog | ||
open={open} | ||
onOpenChange={setOpen} | ||
title={"Edit Race Location"} | ||
titleColor={"orange"} | ||
trigger={ | ||
<Button size="sm"> | ||
<Pencil className="h-4 w-4" /> | ||
</Button> | ||
} | ||
> | ||
<form action={onSubmit} className="space-y-4"> | ||
<Input | ||
className="border-blue-300 focus:border-blue-500" | ||
defaultValue={props.city} | ||
name="city" | ||
placeholder="City" | ||
required={true} | ||
/> | ||
<Select name="state" required={true} defaultValue={props.state}> | ||
<SelectTrigger className="border-blue-300 focus:border-blue-500"> | ||
<SelectValue | ||
placeholder="Select State" | ||
defaultValue={props.state} | ||
/> | ||
</SelectTrigger> | ||
<SelectContent className="bg-white"> | ||
{states.map((state) => ( | ||
<SelectItem key={state.value} value={state.value}> | ||
{state.label} | ||
</SelectItem> | ||
))} | ||
</SelectContent> | ||
</Select> | ||
<SubmitButton tab={Tab.ManageLocations} /> | ||
</form> | ||
</Dialog> | ||
); | ||
}; |
48 changes: 48 additions & 0 deletions
48
components/locations-list/location-in-use-dialog/LocationInUseDialog.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
"use client"; | ||
|
||
import { Button } from "@/components/ui/button"; | ||
import { | ||
Dialog, | ||
DialogContent, | ||
DialogDescription, | ||
DialogFooter, | ||
DialogHeader, | ||
DialogTitle, | ||
} from "@/components/ui/dialog"; | ||
import { AlertCircle } from "lucide-react"; | ||
|
||
interface IProps { | ||
isOpen: boolean; | ||
onClose: () => void; | ||
} | ||
|
||
export const LocationInUseDialog = ({ isOpen, onClose }: IProps) => { | ||
return ( | ||
<Dialog open={isOpen} onOpenChange={onClose}> | ||
<DialogContent className="sm:max-w-[425px] bg-white"> | ||
<DialogHeader> | ||
<DialogTitle className="flex items-center gap-2 text-amber-600"> | ||
<AlertCircle className="h-5 w-5" /> | ||
Location In Use | ||
</DialogTitle> | ||
<DialogDescription> | ||
The location cannot be deleted because it is associated with | ||
existing race results. | ||
</DialogDescription> | ||
</DialogHeader> | ||
<div className="py-4"> | ||
<p className="text-sm text-gray-500"> | ||
This location is currently used in at least one race result. To | ||
delete this location, you must first remove or update all associated | ||
race results. | ||
</p> | ||
</div> | ||
<DialogFooter className="sm:justify-start"> | ||
<Button type="button" onClick={onClose} variant="outline"> | ||
Understood | ||
</Button> | ||
</DialogFooter> | ||
</DialogContent> | ||
</Dialog> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters