MIF_E31221222/sigap-website/app/(pages)/(admin)/dashboard/crime-management/crime-overview/action.ts

284 lines
8.5 KiB
TypeScript

'use server';
import { getInjection } from '@/di/container';
import db from '@/prisma/db';
import {
AuthenticationError,
UnauthenticatedError,
} from '@/src/entities/errors/auth';
import { InputParseError } from '@/src/entities/errors/common';
export async function getAvailableYears() {
const instrumentationService = getInjection('IInstrumentationService');
return await instrumentationService.instrumentServerAction(
'Available Years',
{ recordResponse: true },
async () => {
try {
const years = await db.crimes.findMany({
select: {
year: true,
},
distinct: ['year'],
orderBy: {
year: 'asc',
},
});
return years.map((year) => year.year);
} catch (err) {
if (err instanceof InputParseError) {
// return {
// error: err.message,
// };
throw new InputParseError(err.message);
}
if (err instanceof AuthenticationError) {
// return {
// error: 'User not found.',
// };
throw new AuthenticationError(
'There was an error with the credentials. Please try again or contact support.'
);
}
const crashReporterService = getInjection('ICrashReporterService');
crashReporterService.report(err);
// return {
// error:
// 'An error happened. The developers have been notified. Please try again later.',
// };
throw new Error(
'An error happened. The developers have been notified. Please try again later.'
);
}
}
);
}
export async function getCrimes() {
const instrumentationService = getInjection('IInstrumentationService');
return await instrumentationService.instrumentServerAction(
'District Crime Data',
{ recordResponse: true },
async () => {
try {
const crimes = await db.crimes.findMany({
include: {
districts: {
select: {
name: true,
},
},
crime_incidents: {
select: {
timestamp: true,
description: true,
status: true,
crime_categories: {
select: {
name: true,
type: true,
},
},
locations: {
select: {
address: true,
latitude: true,
longitude: true,
},
},
},
},
},
});
return crimes.map((crime) => {
return {
id: crime.id,
district: crime.districts.name,
number_of_crime: crime.number_of_crime,
level: crime.level,
score: crime.score,
month: crime.month,
year: crime.year,
incidents: crime.crime_incidents.map((incident) => {
return {
timestamp: incident.timestamp,
description: incident.description,
status: incident.status,
category: incident.crime_categories.name,
type: incident.crime_categories.type,
address: incident.locations.address,
latitude: incident.locations.latitude,
longitude: incident.locations.longitude,
};
}),
};
});
} catch (err) {
if (err instanceof InputParseError) {
// return {
// error: err.message,
// };
throw new InputParseError(err.message);
}
if (err instanceof AuthenticationError) {
// return {
// error: 'User not found.',
// };
throw new AuthenticationError(
'There was an error with the credentials. Please try again or contact support.'
);
}
const crashReporterService = getInjection('ICrashReporterService');
crashReporterService.report(err);
// return {
// error:
// 'An error happened. The developers have been notified. Please try again later.',
// };
throw new Error(
'An error happened. The developers have been notified. Please try again later.'
);
}
}
);
}
export async function getCrimeByYearAndMonth(
year: number,
month: number | 'all'
) {
const instrumentationService = getInjection('IInstrumentationService');
return await instrumentationService.instrumentServerAction(
'District Crime Data',
{ recordResponse: true },
async () => {
try {
// Build where clause conditionally based on provided parameters
const whereClause: any = {
year: year, // Always filter by year now since "all" is removed
};
// Only add month to filter if it's not "all"
if (month !== 'all') {
whereClause.month = month;
}
const crimes = await db.crimes.findMany({
where: whereClause,
include: {
districts: {
select: {
name: true,
geographics: {
where: { year }, // Match geographics to selected year
select: {
address: true,
land_area: true,
year: true,
},
},
demographics: {
where: { year }, // Match demographics to selected year
select: {
number_of_unemployed: true,
population: true,
population_density: true,
year: true,
},
},
},
},
crime_incidents: {
select: {
id: true,
timestamp: true,
description: true,
status: true,
crime_categories: {
select: {
name: true,
type: true,
},
},
locations: {
select: {
address: true,
latitude: true,
longitude: true,
},
},
},
},
},
});
return crimes.map((crime) => {
return {
id: crime.id,
distrcit_id: crime.district_id,
district_name: crime.districts.name,
number_of_crime: crime.number_of_crime,
level: crime.level,
score: crime.score,
month: crime.month,
year: crime.year,
geographics: crime.districts.geographics.map((geo) => {
return {
address: geo.address,
land_area: geo.land_area,
year: geo.year,
};
}),
demographics: crime.districts.demographics.map((demo) => {
return {
number_of_unemployed: demo.number_of_unemployed,
population: demo.population,
population_density: demo.population_density,
year: demo.year,
};
}),
incidents: crime.crime_incidents.map((incident) => {
return {
id: incident.id,
timestamp: incident.timestamp,
description: incident.description,
status: incident.status,
category: incident.crime_categories.name,
type: incident.crime_categories.type,
address: incident.locations.address,
latitude: incident.locations.latitude,
longitude: incident.locations.longitude,
};
}),
};
});
} catch (err) {
if (err instanceof InputParseError) {
throw new InputParseError(err.message);
}
if (err instanceof AuthenticationError) {
throw new AuthenticationError(
'There was an error with the credentials. Please try again or contact support.'
);
}
const crashReporterService = getInjection('ICrashReporterService');
crashReporterService.report(err);
throw new Error(
'An error happened. The developers have been notified. Please try again later.'
);
}
}
);
}