-
+
+
+
{props.subtitle}
+
+ Unit Strength: {uniqueNamesSet.size}
+
+
+
);
}
diff --git a/client/app/adr/page.css b/client/app/adr/page.css
index 1ae39a9..73d1241 100644
--- a/client/app/adr/page.css
+++ b/client/app/adr/page.css
@@ -239,3 +239,11 @@
/* No idea why i have to do this stupidity. For some reason if I dont do this, this shit becomes off centered */
transform-origin: 67% 67%;
}
+
+.CounterSubtitle {
+ display: flex;
+}
+
+.Counter {
+ font-weight: bold;
+}
diff --git a/client/app/adr/page.jsx b/client/app/adr/page.jsx
index b830c9f..3903b7e 100644
--- a/client/app/adr/page.jsx
+++ b/client/app/adr/page.jsx
@@ -2,6 +2,7 @@ import Link from "next/link";
import GetCombatRoster from "../reusableModules/getCombatRoster";
import GetReserveRoster from "../reusableModules/getReserveRoster";
import GetApiTimestamp from "../reusableModules/getApiTimestamp";
+import GetRosterGroups from "../reusableModules/getGroups";
import AdrListEntry from "./modules/AdrListEntry";
import Logo from "../theme/adrLogo";
import "./page.css";
@@ -12,14 +13,30 @@ export const metadata = {
};
export default async function ActiveDutyRoster() {
- const [combat, reserve, timestamp] = await Promise.all([
+ const [combat, reserve, timestamp, groups] = await Promise.all([
GetCombatRoster(),
GetReserveRoster(),
GetApiTimestamp(),
+ GetRosterGroups(),
]);
const milpacArray = [{ combat, reserve }];
+ const rosterGroups = groups;
+ const units = [
+ { title: "Regimental Command", selectors: [0] },
+ { title: "First Battalion", selectors: [2, 3, 4, 5, 6] },
+ { title: "Second Battalion", selectors: [7, 8, 9, 10, 11] },
+ { title: "Third Battalion", selectors: [12, 15, 13 /*, 14*/] },
+ {
+ title: "Auxiallary Combat Division",
+ selectors: [16, 17, 18 /*, 19*/, 20],
+ },
+ {
+ title: "Support Departments",
+ selectors: [1],
+ },
+ ];
return (
@@ -50,15 +67,25 @@ export default async function ActiveDutyRoster() {
- {/* note: bBGroup = Billet Bank Group */}
-
-
-
+ {units.map((unit) => (
+
+
{unit.title}
+ {unit.selectors.map((selector) => (
+
+ ))}
+
+ ))}
+ {/*
-
+
*/}
);
diff --git a/client/app/reusableModules/getGroups.jsx b/client/app/reusableModules/getGroups.jsx
new file mode 100644
index 0000000..5c8c3f9
--- /dev/null
+++ b/client/app/reusableModules/getGroups.jsx
@@ -0,0 +1,17 @@
+const CLIENT_TOKEN = process.env.NEXT_PUBLIC_CLIENT_TOKEN;
+const GROUP_API_URL = process.env.GROUP_API_URL;
+
+export default async function GetRosterGroups() {
+ const response = await fetch(GROUP_API_URL, {
+ headers: {
+ Authorization: CLIENT_TOKEN,
+ },
+ cache: "no-store",
+ });
+
+ if (!response.ok) {
+ throw new Error("HTTP Error! status: " + response.status);
+ }
+
+ return await response.json();
+}
diff --git a/server/controllers/cacheManager.js b/server/controllers/cacheManager.js
index 6470693..78c73de 100644
--- a/server/controllers/cacheManager.js
+++ b/server/controllers/cacheManager.js
@@ -6,11 +6,13 @@ let cacheStatus = {
combat: false,
reserve: false,
individual: false,
+ groups: false,
};
let cachedCombatRoster;
let cachedReserveRoster;
let cachedIndividual;
+let cachedGroups;
let cacheTime = {};
axiosRetry(axios, {
@@ -83,6 +85,30 @@ const updateCachedIndividual = async (userName) => {
}
};
+const updateCachedGroups = async () => {
+ try {
+ const response = await axios(
+ `https://api.7cav.us/api/v1/milpacs/position/groups`,
+ {
+ headers: {
+ Accept: "application/json",
+ "Content-Type": "application/json",
+ Authorization: "Bearer " + API_TOKEN,
+ "Accept-Encoding": "gzip",
+ },
+ }
+ );
+ cachedGroups = response.data;
+ cacheTime["individual"] = Date.now();
+ cacheStatus.groups = true;
+ return cachedGroups;
+ } catch (error) {
+ console.error("Failed to update individual user cache:", error);
+ cacheStatus.groups = false;
+ return null;
+ }
+};
+
const scheduleCacheUpdate = (updateFunction) => {
const now = new Date();
const delay =
@@ -99,9 +125,14 @@ const initializeCache = async () => {
// Initial cache update
await updateCombatRosterCache();
await updateReserveRosterCache();
+ await updateCachedGroups();
// Check if cache is valid
- if (!cacheStatus["combat"] || !cacheStatus["reserve"]) {
+ if (
+ !cacheStatus["combat"] ||
+ !cacheStatus["reserve"] ||
+ !cacheStatus["groups"]
+ ) {
console.error("Failed to initialize cache. Exiting...");
process.exit(1); // Exit to trigger Docker restart
}
@@ -109,6 +140,7 @@ const initializeCache = async () => {
// Schedule the updates
scheduleCacheUpdate(updateCombatRosterCache);
scheduleCacheUpdate(updateReserveRosterCache);
+ scheduleCacheUpdate(updateCachedGroups);
} catch (error) {
console.error("Critical error during cache initialization:", error);
process.exit(1); // Exit to trigger Docker restart
@@ -127,11 +159,16 @@ const getCachedIndividual = () => {
return cachedIndividual;
};
+const getCachedGroups = () => {
+ return cachedGroups;
+};
+
module.exports = {
updateCachedIndividual,
getCachedCombatRoster,
getCachedReserveRoster,
getCachedIndividual,
+ getCachedGroups,
cacheTime,
initializeCache,
};
diff --git a/server/controllers/gRequest.js b/server/controllers/gRequest.js
new file mode 100644
index 0000000..3a26d04
--- /dev/null
+++ b/server/controllers/gRequest.js
@@ -0,0 +1,11 @@
+const cacheManager = require("../controllers/cacheManager");
+
+module.exports = async (req, res) => {
+ const cachedGroups = cacheManager.getCachedGroups();
+
+ if (cachedGroups) {
+ res.send(cachedGroups);
+ } else {
+ res.status(503).send("Cache is empty");
+ }
+};
diff --git a/server/routes/index.js b/server/routes/index.js
index 67f962e..23878ef 100644
--- a/server/routes/index.js
+++ b/server/routes/index.js
@@ -4,6 +4,7 @@ const cors = require("cors");
const cRequest = require("../controllers/cRequest");
const rRequest = require("../controllers/rRequest");
const iRequest = require("../controllers/iRequest");
+const gRequest = require("../controllers/gRequest");
const app = express();
app.use(
@@ -21,4 +22,5 @@ router.get("/individual", (req, res) => {
}
iRequest(req, res, userName);
});
+router.get("/groups", gRequest);
module.exports = router;