Skip to content

Commit

Permalink
Implementing Dynamic Plot Selection (#152)
Browse files Browse the repository at this point in the history
Plot display and selection system needs to be dynamic based on database being logged into:

ChangeLog:

* Shifting hub layout SQL data collection system to EntryModal component and adding this to Login component --> EntryModal will now run AFTER logging in and BEFORE access to the rest of the application
* Implementing remaining SQL API routes for fixed data/properties pages
* Splitting contexts out into separate components --> BECAUSE list of plots will change depending on which database is being used, plot, quadrat, and census selection depends on updating plot list in order to select from the right dataset. By splitting plot list, quadrat list, and census list contexts into a separate parent context component and plot/quadrat/census selection contexts into a child context component, they can actually access the respective list contexts.
* Removing quadrat and census selection options from sidebar breadcrumbs menu --> the sidebar selection menu identifies selections that are core to all pages, and not all pages require quadrat or census selection.
  • Loading branch information
siddheshraze committed Jan 5, 2024
1 parent 88d6da8 commit e58dc32
Show file tree
Hide file tree
Showing 13 changed files with 443 additions and 308 deletions.
37 changes: 35 additions & 2 deletions frontend/app/(login)/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@ import {animated, useTransition} from "@react-spring/web";
import styles from "@/styles/styles.module.css";
import Sidebar from "@/components/sidebar";
import Box from "@mui/joy/Box";
import {
useAttributeLoadDispatch,
useCensusLoadDispatch,
usePersonnelLoadDispatch,
usePlotsLoadDispatch,
useQuadratsLoadDispatch,
useSpeciesLoadDispatch,
useSubSpeciesLoadDispatch
} from "@/app/contexts/fixeddatacontext";
import {
Button,
DialogActions,
DialogContent,
DialogTitle,
LinearProgress,
Modal,
ModalDialog,
Stack,
Typography
} from "@mui/joy";
import WarningRoundedIcon from "@mui/icons-material/WarningRounded";
import Divider from "@mui/joy/Divider";
import {useFirstLoadContext, useFirstLoadDispatch} from "@/app/contexts/generalcontext";
import EntryModal from "@/components/client/entrymodal";

const slides = [
'background-1.jpg',
Expand All @@ -29,9 +53,18 @@ export default function Page() {
},
exitBeforeEnter: true,
})
useEffect(() => void setInterval(() => setIndex(state => (state + 1) % slides.length), 5000), [])
useEffect(
() => {
void setInterval(() => setIndex(state => (state + 1) % slides.length), 5000)
}, []);
const {status} = useSession();
if (status == "authenticated") redirect('/dashboard');
if (status == "authenticated") {
return (
<>
<EntryModal />
</>
);
}
else
return (
<>
Expand Down
33 changes: 33 additions & 0 deletions frontend/app/api/quadratsperplot/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {NextRequest, NextResponse} from "next/server";
import sql from "mssql";
import {sqlConfig} from "@/config/macros";
import {AttributeRDS} from "@/config/sqlmacros";

async function getSqlConnection(tries: number) {
return await sql.connect(sqlConfig).catch((err) => {
console.error(err);
if (tries == 5) {
throw new Error("Connection failure");
}
console.log("conn failed --> trying again!");
getSqlConnection(tries + 1);
});
}

async function runQuery(conn: sql.ConnectionPool, query: string) {
if (!conn) {
throw new Error("invalid ConnectionPool object. check connection string settings.")
}
return await conn.request().query(query);
}
export async function GET(request: NextRequest) {
let i = 0;
let conn = await getSqlConnection(i);
if (!conn) throw new Error('sql connection failed');

let plotID = request.nextUrl.searchParams.get('plotID')!;
let results = await runQuery(conn, `SELECT COUNT(*) FROM forestgeo.Quadrats WHERE PlotID = ${plotID}`);
if (!results) throw new Error("call failed");
await conn.close();
return new NextResponse(JSON.stringify(Object.values(results.recordset[0])));
}
98 changes: 98 additions & 0 deletions frontend/app/contexts/generalcontext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"use client";
import React, {createContext, Dispatch, useContext, useReducer} from 'react';
import {allCensus, allQuadrats, Plot, plots} from "@/config/macros";
import PlotProvider, {PlotsContext} from "@/app/contexts/userselectioncontext";

export const PlotListContext = createContext<Plot[] | null>(null);
export const QuadratListContext = createContext<number[] | null>(null);
export const CensusListContext = createContext<number[] | null>(null);
export const FirstLoadContext = createContext<boolean | null>(null);
export const PlotListDispatchContext = createContext<Dispatch<{ plotList: Plot[] | null }> | null>(null);
export const QuadratListDispatchContext = createContext<Dispatch<{ quadratList: number[] | null }> | null>(null);
export const CensusListDispatchContext = createContext<Dispatch<{ censusList: number[] | null }> | null>(null);
export const FirstLoadDispatchContext = createContext<Dispatch<{ firstLoad: boolean }> | null>(null);

export function ContextsProvider({children}: { children: React.ReactNode }) {
const [plotList, plotListDispatch] = useReducer(
plotListReducer,
plots
)

const [quadratList, quadratListDispatch] = useReducer(
quadratListReducer,
[]
)

const [censusList, censusListDispatch] = useReducer(
censusListReducer,
[]
)

const [firstLoad, firstLoadDispatch] = useReducer(
firstLoadReducer,
true
)


return (
<>
<PlotListContext.Provider value={plotList}>
<PlotListDispatchContext.Provider value={plotListDispatch}>
<QuadratListContext.Provider value={quadratList}>
<QuadratListDispatchContext.Provider value={quadratListDispatch}>
<CensusListContext.Provider value={censusList}>
<CensusListDispatchContext.Provider value={censusListDispatch}>
<FirstLoadContext.Provider value={firstLoad}>
<FirstLoadDispatchContext.Provider value={firstLoadDispatch}>
<PlotProvider>
{children}
</PlotProvider>
</FirstLoadDispatchContext.Provider>
</FirstLoadContext.Provider>
</CensusListDispatchContext.Provider>
</CensusListContext.Provider>
</QuadratListDispatchContext.Provider>
</QuadratListContext.Provider>
</PlotListDispatchContext.Provider>
</PlotListContext.Provider>
</>
);
}

function firstLoadReducer(currentState: any, action: { firstLoad: boolean | null }) {
if (action.firstLoad == false && currentState) return action.firstLoad;
else return currentState;
}
function plotListReducer(_currentPlotList: any, action: {plotList: Plot[] | null}) {
return action.plotList;
}
function quadratListReducer(_currentQuadratList: any, action: { quadratList: number[] | null}) {
return action.quadratList;
}
function censusListReducer(_currentCensusList: any, action: { censusList: number[] | null}) {
return action.censusList;
}
export function useFirstLoadContext() {
return useContext(FirstLoadContext);
}
export function useFirstLoadDispatch() {
return useContext(FirstLoadDispatchContext);
}
export function usePlotListContext() {
return useContext(PlotListContext);
}
export function usePlotListDispatch() {
return useContext(PlotListDispatchContext);
}
export function useQuadratListContext() {
return useContext(QuadratListContext);
}
export function useQuadratListDispatch() {
return useContext(QuadratListDispatchContext);
}
export function useCensusListContext() {
return useContext(CensusListContext);
}
export function useCensusListDispatch() {
return useContext(CensusListDispatchContext);
}
106 changes: 0 additions & 106 deletions frontend/app/contexts/plotcontext.tsx

This file was deleted.

Loading

0 comments on commit e58dc32

Please sign in to comment.