Skip to content

Commit

Permalink
Added logic so that operating initials can be assigned from the matrix.
Browse files Browse the repository at this point in the history
  • Loading branch information
beabravedude committed Jan 27, 2025
1 parent 4611ceb commit f5b71a7
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 17 deletions.
29 changes: 29 additions & 0 deletions actions/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,35 @@ import {z} from "zod";
import {writeDossier} from "@/actions/dossier";
import {log} from "@/actions/log";
import {getController} from "@/actions/vatusa/controller";
import { after } from "next/server";

export const updateOperatingInitials = async (user: User, initials: string,) => {

const existing = await prisma.user.findFirst({
where: {
operatingInitials: initials,
},
});

if (existing) {
return "These operating initials are already in use.";
}

await prisma.user.update({
data: {
operatingInitials: initials,
},
where: {
id: user.id,
}
});

after(async () => {
await log("UPDATE", "USER_SETTINGS", `User operating initials updated to ${initials} for ${user.firstName} ${user.lastName} (${user.cid})`,);
});

revalidatePath('/admin/oi-matrix');
}

export const updateSettings = async (formData: FormData) => {

Expand Down
25 changes: 9 additions & 16 deletions app/admin/oi-matrix/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,31 @@ import React from 'react';
import prisma from "@/lib/db";
import {Box, Card, CardContent, Grid2, Stack, Tooltip, Typography} from "@mui/material";
import Link from "next/link";
import OperatingInitialAssignmentItem from '@/components/OperatingInitials/OperatingInitialAssignmentItem';
import { User } from 'next-auth';

export default async function Page() {

const inUseOperatingInitials = await prisma.user.findMany({
const allControllers = await prisma.user.findMany({
where: {
operatingInitials: {
not: null,
},
controllerStatus: {
not: 'NONE',
},
},
select: {
operatingInitials: true,
id: true,
cid: true,
firstName: true,
lastName: true,
controllerStatus: true,
rating: true,
},
});

const inUseOperatingInitials = allControllers
.filter((c) => c.operatingInitials);

const allPossibleOperatingInitials = Array.from({length: 26 * 26}, (_, i) => {
const first = String.fromCharCode(65 + Math.floor(i / 26));
const second = String.fromCharCode(65 + i % 26);
Expand Down Expand Up @@ -75,18 +79,7 @@ export default async function Page() {
</Tooltip>
</Grid2>
) : (
<Grid2
key={initials}
size={{
xs: 4,
sm: 3,
md: 2,
xl: 1
}}>
<Box sx={{border: 2, borderRadius: 2,}}>
<Typography textAlign="center" variant="body2">{initials}</Typography>
</Box>
</Grid2>
<OperatingInitialAssignmentItem allControllers={allControllers as User[]} initials={initials} key={initials} />
);
})}
</Grid2>
Expand Down
2 changes: 1 addition & 1 deletion components/EventPosition/EventPositionRequestForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default function EventPositionRequestForm({ admin, currentUser, event, ev
onChange={(event, newValue) => {
setUser(newValue ? newValue.id : '');
}}
renderInput={(params) => <TextField {...params} label="Student"/>}
renderInput={(params) => <TextField {...params} label="Controller"/>}
/>
</Grid2> }
<Grid2 size={{ xs: 6, md: 2, }}>
Expand Down
68 changes: 68 additions & 0 deletions components/OperatingInitials/OperatingInitialAssignmentItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
'use client';
import { updateOperatingInitials } from "@/actions/user";
import { getRating } from "@/lib/vatsim";
import { Autocomplete, Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, TextField, Typography } from "@mui/material";

import { Grid2 } from "@mui/material";
import { User } from "next-auth";
import { useState } from "react";
import { toast } from "react-toastify";

export default function OperatingInitialAssignmentItem({ initials, allControllers, }: { initials: string, allControllers: User[], }) {

const [open, setOpen] = useState(false);
const [user, setUser] = useState<string>('');

const handleSubmit = async () => {

const u = allControllers.find((u) => u.id === user);

if (!u) return;

const error = await updateOperatingInitials(u, initials);

if (error) {
toast.error(error);
return;
}

toast.success(`Successfully assigned ${initials} to ${u.firstName} ${u.lastName}`);
setOpen(false);
}

return (
<>
<Grid2
key={initials}
size={{
xs: 4,
sm: 3,
md: 2,
xl: 1
}}>
<Box sx={{border: 2, borderRadius: 2, cursor: 'pointer', }}>
<div onClick={() => setOpen(true)}>
<Typography textAlign="center" variant="body2">{initials}</Typography>
</div>
</Box>
</Grid2>
<Dialog open={open} onClose={() => setOpen(false)}>
<DialogTitle>Assign Operating Initials - {initials}</DialogTitle>
<DialogContent>
<Autocomplete
options={allControllers}
getOptionLabel={(option) => `${option.firstName} ${option.lastName} - ${getRating(option.rating)} (${option.cid})`}
value={allControllers.find((u) => u.id === user) || null}
onChange={(event, newValue) => {
setUser(newValue ? newValue.id : '');
}}
renderInput={(params) => <TextField {...params} label="Controller"/>} />
</DialogContent>
<DialogActions>
<Button onClick={() => setOpen(false)}>Cancel</Button>
<Button onClick={handleSubmit} variant="contained">Assign</Button>
</DialogActions>
</Dialog>
</>
);
}

0 comments on commit f5b71a7

Please sign in to comment.