diff --git a/components/SocialMedia/SocialMediaItem/__tests__/__snapshots__/SocialMediaItem.test.tsx.snap b/components/SocialMedia/SocialMediaItem/__tests__/__snapshots__/SocialMediaItem.test.tsx.snap
index b168f469b..c08d2149c 100644
--- a/components/SocialMedia/SocialMediaItem/__tests__/__snapshots__/SocialMediaItem.test.tsx.snap
+++ b/components/SocialMedia/SocialMediaItem/__tests__/__snapshots__/SocialMediaItem.test.tsx.snap
@@ -11,28 +11,26 @@ exports[`SocialMediaItem > should render with required props 1`] = `
rel="noopener noreferrer"
target="_blank"
>
-
-
- Operation Code's
- Facebook
-
- Facebook Logo",
- }
+
+ Operation Code's
+ Facebook
+
+ Facebook Logo",
}
- viewBox="0 0 500 500"
- />
-
- Opens in new window
-
+ }
+ viewBox="0 0 500 500"
+ />
+
+ Opens in new window
From cdbc1095b01faf6e0bbb96639a24da6529121c98 Mon Sep 17 00:00:00 2001
From: Kyle Holmberg
Date: Mon, 10 Nov 2025 20:57:29 +0700
Subject: [PATCH 2/5] remove more unused stuff
---
common/utils/api-utils.ts | 31 +-----
common/utils/auth-utils.js | 66 -------------
common/utils/cookie-utils.ts | 34 -------
components/Nav/__tests__/Nav.test.tsx | 5 -
package.json | 4 -
pnpm-lock.yaml | 135 --------------------------
test-utils/createComponentInstance.js | 6 --
test-utils/flushPromises.js | 5 -
test-utils/jest-next-image.js | 12 ---
test-utils/mocks/jwtMock.js | 6 --
test-utils/mocks/nextContextMock.js | 59 -----------
test-utils/mocks/nextRouterMock.js | 19 ----
test-utils/mocks/passwordResetMock.js | 2 -
test-utils/mocks/svgMock.js | 8 --
test-utils/mocks/testFileMock.js | 1 -
test-utils/transforms/file.js | 13 ---
test-utils/wait.js | 1 -
17 files changed, 4 insertions(+), 403 deletions(-)
delete mode 100644 common/utils/auth-utils.js
delete mode 100644 common/utils/cookie-utils.ts
delete mode 100644 test-utils/createComponentInstance.js
delete mode 100644 test-utils/flushPromises.js
delete mode 100644 test-utils/jest-next-image.js
delete mode 100644 test-utils/mocks/jwtMock.js
delete mode 100644 test-utils/mocks/nextContextMock.js
delete mode 100644 test-utils/mocks/nextRouterMock.js
delete mode 100644 test-utils/mocks/passwordResetMock.js
delete mode 100644 test-utils/mocks/svgMock.js
delete mode 100644 test-utils/mocks/testFileMock.js
delete mode 100644 test-utils/transforms/file.js
delete mode 100644 test-utils/wait.js
diff --git a/common/utils/api-utils.ts b/common/utils/api-utils.ts
index 7b68dcc53..260973e0f 100644
--- a/common/utils/api-utils.ts
+++ b/common/utils/api-utils.ts
@@ -2,7 +2,6 @@ import type { AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios';
import axios from 'axios';
import { networkErrorMessages } from 'common/constants/messages';
import { apiUrl, resourcesAPIURL } from 'common/config/environment';
-import { setAuthorizationHeader } from 'common/utils/cookie-utils';
const baseAxiosConfig = {
baseURL: apiUrl,
@@ -37,17 +36,13 @@ const getRequestAbortionPieces = () => {
export const get = async (
path: string,
- {
- token,
- parameters,
- }: { token?: string; parameters?: Record } = {},
+ { parameters }: { parameters?: Record } = {},
axiosClient = OperationCodeAPI,
) => {
const { abort, connectionTimeout } = getRequestAbortionPieces();
return axiosClient
.get(path, {
- headers: setAuthorizationHeader(token),
cancelToken: abort.token,
params: parameters,
})
@@ -61,17 +56,11 @@ export const get = async (
});
};
-export const post = async (
- path: string,
- body: object,
- { token }: { token?: string } = {},
- axiosClient: AxiosInstance = axios,
-) => {
+export const post = async (path: string, body: object, axiosClient: AxiosInstance = axios) => {
const { abort, connectionTimeout } = getRequestAbortionPieces();
return axiosClient
.post(path, body, {
- headers: setAuthorizationHeader(token),
cancelToken: abort.token,
})
.then(response => {
@@ -84,17 +73,11 @@ export const post = async (
});
};
-export const patch = async (
- path: string,
- body: object,
- { token }: { token?: string } = {},
- axiosClient: AxiosInstance = axios,
-) => {
+export const patch = async (path: string, body: object, axiosClient: AxiosInstance = axios) => {
const { abort, connectionTimeout } = getRequestAbortionPieces();
return axiosClient
.patch(path, body, {
- headers: setAuthorizationHeader(token),
cancelToken: abort.token,
})
.then(response => {
@@ -107,17 +90,11 @@ export const patch = async (
});
};
-export const put = async (
- path: string,
- body: object,
- { token }: { token?: string } = {},
- axiosClient: AxiosInstance = axios,
-) => {
+export const put = async (path: string, body: object, axiosClient: AxiosInstance = axios) => {
const { abort, connectionTimeout } = getRequestAbortionPieces();
return axiosClient
.put(path, body, {
- headers: setAuthorizationHeader(token),
cancelToken: abort.token,
})
.then(response => {
diff --git a/common/utils/auth-utils.js b/common/utils/auth-utils.js
deleted file mode 100644
index 84e95488b..000000000
--- a/common/utils/auth-utils.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import Router from 'next/router';
-import nextCookie from 'next-cookies';
-import { setAuthCookies, removeAuthCookies, hasValidAuthToken } from './cookie-utils';
-
-export const login = async ({ token }, routeTo = '/profile') => {
- setAuthCookies({ token });
- await Router.push(routeTo);
-};
-
-export const logout = ({ routeTo = '/login', shouldRedirect = true } = {}) => {
- removeAuthCookies();
- window.localStorage.setItem('logout', Date.now()); // Log out from all windows
- if (shouldRedirect) {
- Router.push(routeTo);
- }
-};
-
-/**
- * @description This method examines ctx via `getInitialProps` and returns a token if it exists.
- * If a token does not exist, the user will be routed to /login
- *
- * @export
- * @param {{
- * pathname: string,
- * query: Object.,
- * asPath: string,
- * req: Object.,
- * res: Object.,
- * err: Object.
- * }} ctx
- * @returns {?string} token or null
- */
-export const authenticate = ctx => {
- const { token } = nextCookie(ctx);
-
- if (!token || !hasValidAuthToken(token)) {
- isomorphicRedirect('/login', ctx);
- return '';
- }
-
- return token;
-};
-
-/**
- * @description Utility for handling redirects. Works on both server during
- * SSR and on the client
- *
- * @export
- * @param {string} path
- * @param {{
- * pathname: string,
- * query: Object.,
- * asPath: string,
- * req: Object.,
- * res: Object.,
- * err: Object.
- * }} ctx
- */
-export const isomorphicRedirect = (path, ctx) => {
- if (ctx && ctx.res) {
- ctx.res.writeHead(302, { Location: path });
- ctx.res.end();
- } else {
- Router.push(path);
- }
-};
diff --git a/common/utils/cookie-utils.ts b/common/utils/cookie-utils.ts
deleted file mode 100644
index 658cfbff2..000000000
--- a/common/utils/cookie-utils.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import cookie from 'js-cookie';
-import jwtDecode from 'jwt-decode';
-
-export const setAuthCookies = ({ token }: { token: string }) => {
- cookie.set('token', token);
-};
-
-export const removeAuthCookies = () => {
- cookie.remove('token');
-};
-
-export const setAuthorizationHeader = (token = getAuthToken()) => {
- if (hasValidAuthToken(token)) {
- return { Authorization: `Bearer ${token}` };
- }
-
- return {};
-};
-
-export const getAuthToken = () => {
- return cookie.get('token');
-};
-
-export const hasValidAuthToken = (token = cookie.get('token')) => {
- if (token === undefined) {
- return false;
- }
-
- const jwt = jwtDecode<{ exp: number }>(token);
- const currentTime = new Date().getTime() / 1000;
-
- // Valid if jwt expiry is in the future
- return currentTime < jwt.exp;
-};
diff --git a/components/Nav/__tests__/Nav.test.tsx b/components/Nav/__tests__/Nav.test.tsx
index 456e2dbca..49fc4c9de 100644
--- a/components/Nav/__tests__/Nav.test.tsx
+++ b/components/Nav/__tests__/Nav.test.tsx
@@ -1,4 +1,3 @@
-import cookie from 'js-cookie';
import { fireEvent, render, screen } from '@testing-library/react';
import { CLOSE_BUTTON } from 'common/constants/testIDs';
import createShallowSnapshotTest from 'test-utils/createShallowSnapshotTest';
@@ -6,10 +5,6 @@ import createShallowSnapshotTest from 'test-utils/createShallowSnapshotTest';
import { Nav } from '../Nav';
describe('Nav', () => {
- beforeEach(() => {
- cookie.get = vi.fn().mockImplementation(() => undefined);
- });
-
it('should render with no props passed', () => createShallowSnapshotTest());
it('should render both desktop and mobile navigations', () => {
diff --git a/package.json b/package.json
index a7b343dfa..c58b99f7e 100644
--- a/package.json
+++ b/package.json
@@ -38,7 +38,6 @@
"@sentry/nextjs": "^7.77.0",
"@storybook/blocks": "^7.4.1",
"@types/airtable": "^0.10.5",
- "@types/js-cookie": "^3.0.6",
"airtable": "^0.12.2",
"axios": "^1.12.2",
"cva": "^1.0.0-beta.4",
@@ -47,8 +46,6 @@
"fontfaceobserver": "^2.3.0",
"formik": "^2.4.6",
"intersection-observer": "^0.12.2",
- "js-cookie": "^3.0.1",
- "jwt-decode": "^3.1.2",
"lodash": "^4.17.21",
"logrocket": "^10.1.0",
"logrocket-react": "^6.0.3",
@@ -83,7 +80,6 @@
"@testing-library/react": "^12.1.5",
"@types/fingerprintjs2": "2",
"@types/fontfaceobserver": "^2.1.3",
- "@types/jest": "^29.5.14",
"@types/lodash": "^4.17.20",
"@types/logrocket-react": "^3.0.3",
"@types/node": "^24.9.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index eafc33fa9..493d31c13 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -26,9 +26,6 @@ importers:
'@types/airtable':
specifier: ^0.10.5
version: 0.10.5
- '@types/js-cookie':
- specifier: ^3.0.6
- version: 3.0.6
airtable:
specifier: ^0.12.2
version: 0.12.2
@@ -53,12 +50,6 @@ importers:
intersection-observer:
specifier: ^0.12.2
version: 0.12.2
- js-cookie:
- specifier: ^3.0.1
- version: 3.0.5
- jwt-decode:
- specifier: ^3.1.2
- version: 3.1.2
lodash:
specifier: ^4.17.21
version: 4.17.21
@@ -156,9 +147,6 @@ importers:
'@types/fontfaceobserver':
specifier: ^2.1.3
version: 2.1.3
- '@types/jest':
- specifier: ^29.5.14
- version: 29.5.14
'@types/lodash':
specifier: ^4.17.20
version: 4.17.20
@@ -1391,10 +1379,6 @@ packages:
resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==}
engines: {node: '>=8'}
- '@jest/expect-utils@29.7.0':
- resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
'@jest/schemas@29.6.3':
resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -2950,12 +2934,6 @@ packages:
'@types/istanbul-reports@3.0.4':
resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==}
- '@types/jest@29.5.14':
- resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==}
-
- '@types/js-cookie@3.0.6':
- resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==}
-
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
@@ -3049,9 +3027,6 @@ packages:
'@types/serve-static@1.15.10':
resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==}
- '@types/stack-utils@2.0.3':
- resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==}
-
'@types/unist@2.0.11':
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
@@ -4288,10 +4263,6 @@ packages:
engines: {node: '>= 4.0.0'}
hasBin: true
- diff-sequences@29.6.3:
- resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
diffie-hellman@5.0.3:
resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==}
@@ -4509,10 +4480,6 @@ packages:
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
engines: {node: '>=0.8.0'}
- escape-string-regexp@2.0.0:
- resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
- engines: {node: '>=8'}
-
escape-string-regexp@4.0.0:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
@@ -4728,10 +4695,6 @@ packages:
resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==}
engines: {node: '>=12.0.0'}
- expect@29.7.0:
- resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
express@4.21.2:
resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==}
engines: {node: '>= 0.10.0'}
@@ -5532,26 +5495,10 @@ packages:
engines: {node: '>=10'}
hasBin: true
- jest-diff@29.7.0:
- resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-get-type@29.6.3:
- resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
jest-haste-map@29.7.0:
resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- jest-matcher-utils@29.7.0:
- resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
- jest-message-util@29.7.0:
- resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
jest-regex-util@29.6.3:
resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -5579,10 +5526,6 @@ packages:
joi@17.13.3:
resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==}
- js-cookie@3.0.5:
- resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
- engines: {node: '>=14'}
-
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -5651,9 +5594,6 @@ packages:
resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
engines: {node: '>=4.0'}
- jwt-decode@3.1.2:
- resolution: {integrity: sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==}
-
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@@ -6630,10 +6570,6 @@ packages:
resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
- pretty-format@29.7.0:
- resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-
pretty-hrtime@1.0.3:
resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==}
engines: {node: '>= 0.8'}
@@ -7284,10 +7220,6 @@ packages:
resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
- stack-utils@2.0.6:
- resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
- engines: {node: '>=10'}
-
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
@@ -9372,10 +9304,6 @@ snapshots:
'@istanbuljs/schema@0.1.3': {}
- '@jest/expect-utils@29.7.0':
- dependencies:
- jest-get-type: 29.6.3
-
'@jest/schemas@29.6.3':
dependencies:
'@sinclair/typebox': 0.27.8
@@ -11457,13 +11385,6 @@ snapshots:
dependencies:
'@types/istanbul-lib-report': 3.0.3
- '@types/jest@29.5.14':
- dependencies:
- expect: 29.7.0
- pretty-format: 29.7.0
-
- '@types/js-cookie@3.0.6': {}
-
'@types/json-schema@7.0.15': {}
'@types/json5@0.0.29': {}
@@ -11556,8 +11477,6 @@ snapshots:
'@types/node': 24.10.0
'@types/send': 0.17.6
- '@types/stack-utils@2.0.3': {}
-
'@types/unist@2.0.11': {}
'@types/uuid@9.0.8': {}
@@ -12981,8 +12900,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- diff-sequences@29.6.3: {}
-
diffie-hellman@5.0.3:
dependencies:
bn.js: 4.12.2
@@ -13326,8 +13243,6 @@ snapshots:
escape-string-regexp@1.0.5: {}
- escape-string-regexp@2.0.0: {}
-
escape-string-regexp@4.0.0: {}
escodegen@2.1.0:
@@ -13637,14 +13552,6 @@ snapshots:
expect-type@1.2.2: {}
- expect@29.7.0:
- dependencies:
- '@jest/expect-utils': 29.7.0
- jest-get-type: 29.6.3
- jest-matcher-utils: 29.7.0
- jest-message-util: 29.7.0
- jest-util: 29.7.0
-
express@4.21.2:
dependencies:
accepts: 1.3.8
@@ -14519,15 +14426,6 @@ snapshots:
filelist: 1.0.4
picocolors: 1.1.1
- jest-diff@29.7.0:
- dependencies:
- chalk: 4.1.2
- diff-sequences: 29.6.3
- jest-get-type: 29.6.3
- pretty-format: 29.7.0
-
- jest-get-type@29.6.3: {}
-
jest-haste-map@29.7.0:
dependencies:
'@jest/types': 29.6.3
@@ -14544,25 +14442,6 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
- jest-matcher-utils@29.7.0:
- dependencies:
- chalk: 4.1.2
- jest-diff: 29.7.0
- jest-get-type: 29.6.3
- pretty-format: 29.7.0
-
- jest-message-util@29.7.0:
- dependencies:
- '@babel/code-frame': 7.27.1
- '@jest/types': 29.6.3
- '@types/stack-utils': 2.0.3
- chalk: 4.1.2
- graceful-fs: 4.2.11
- micromatch: 4.0.8
- pretty-format: 29.7.0
- slash: 3.0.0
- stack-utils: 2.0.6
-
jest-regex-util@29.6.3: {}
jest-util@29.7.0:
@@ -14599,8 +14478,6 @@ snapshots:
'@sideway/formula': 3.0.1
'@sideway/pinpoint': 2.0.0
- js-cookie@3.0.5: {}
-
js-tokens@4.0.0: {}
js-tokens@9.0.1: {}
@@ -14699,8 +14576,6 @@ snapshots:
object.assign: 4.1.7
object.values: 1.2.1
- jwt-decode@3.1.2: {}
-
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
@@ -15675,12 +15550,6 @@ snapshots:
ansi-styles: 5.2.0
react-is: 17.0.2
- pretty-format@29.7.0:
- dependencies:
- '@jest/schemas': 29.6.3
- ansi-styles: 5.2.0
- react-is: 18.3.1
-
pretty-hrtime@1.0.3: {}
process-nextick-args@2.0.1: {}
@@ -16463,10 +16332,6 @@ snapshots:
stable@0.1.8: {}
- stack-utils@2.0.6:
- dependencies:
- escape-string-regexp: 2.0.0
-
stackback@0.0.2: {}
stackframe@1.3.4: {}
diff --git a/test-utils/createComponentInstance.js b/test-utils/createComponentInstance.js
deleted file mode 100644
index c6cc1e888..000000000
--- a/test-utils/createComponentInstance.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import TestRenderer from 'react-test-renderer';
-
-export default function createComponentInstance(Component) {
- const root = TestRenderer.create(Component);
- return root.getInstance();
-}
diff --git a/test-utils/flushPromises.js b/test-utils/flushPromises.js
deleted file mode 100644
index f65f1f627..000000000
--- a/test-utils/flushPromises.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Flush all promsises in a test so that Jest won't finish before they are handled
-// Taken from: https://github.com/facebook/jest/issues/2157#issuecomment-279171856
-const flushPromises = () => new Promise(resolve => setImmediate(resolve));
-
-export default flushPromises;
diff --git a/test-utils/jest-next-image.js b/test-utils/jest-next-image.js
deleted file mode 100644
index 8e740aafc..000000000
--- a/test-utils/jest-next-image.js
+++ /dev/null
@@ -1,12 +0,0 @@
-const { s3hostName } = require('../common/constants/urls');
-
-process.env = {
- ...process.env,
- __NEXT_IMAGE_OPTS: {
- deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
- imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
- domains: [s3hostName, 'user-images.githubusercontent.com'],
- path: '/',
- loader: 'default',
- },
-};
diff --git a/test-utils/mocks/jwtMock.js b/test-utils/mocks/jwtMock.js
deleted file mode 100644
index 15e314502..000000000
--- a/test-utils/mocks/jwtMock.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/* eslint-disable import/prefer-default-export */
-/* eslint-disable max-len */
-
-// JWT with an expiration set to Fri Jan 11 2143
-export const VALID_AUTH_TOKEN =
- 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InRlc3Q1NUB0ZXN0LnRlc3QiLCJmaXJzdE5hbWUiOiJUZXN0IiwibGFzdE5hbWUiOiJUZXN0ZXJzb24iLCJ6aXBjb2RlIjoiMTExMTEiLCJpc01lbnRvciI6ZmFsc2UsImV4cCI6NTQ2MDI2MDA0NCwib3JpZ19pYXQiOjE1NjAyNTY0NDR9._XI7rnMB1X1zpj960LFKYQZZWjJSxur1sgMYFlav9Bc';
diff --git a/test-utils/mocks/nextContextMock.js b/test-utils/mocks/nextContextMock.js
deleted file mode 100644
index 36c56d9cc..000000000
--- a/test-utils/mocks/nextContextMock.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import { Component } from 'react';
-import { any, object } from 'prop-types';
-import MockedRouter from './nextRouterMock';
-
-// Reason for this mock's existence:
-// https://github.com/vercel/next.js/issues/5205#issuecomment-422846339
-
-export default class MockNextContext extends Component {
- static propTypes = {
- children: any.isRequired, // eslint-disable-line react/forbid-prop-types
- headManager: object,
- router: object,
- };
-
- // eslint-disable-next-line react/sort-comp
- static defaultProps = {
- headManager: {},
- router: {},
- };
-
- static childContextTypes = {
- headManager: object,
- router: object,
- };
-
- getChildContext() {
- const { headManager, router } = this.props;
- return {
- headManager: {
- updateHead() {},
- ...headManager,
- },
- router: {
- asPath: '/',
- route: '/',
- pathname: '/',
- query: {},
- back() {},
- beforePopState() {},
- prefetch() {},
- push() {},
- reload() {},
- replace() {},
- events: {
- on() {},
- off() {},
- trigger() {},
- },
- ...MockedRouter,
- ...router,
- },
- };
- }
-
- render() {
- const { children } = this.props;
- return children;
- }
-}
diff --git a/test-utils/mocks/nextRouterMock.js b/test-utils/mocks/nextRouterMock.js
deleted file mode 100644
index b84be1846..000000000
--- a/test-utils/mocks/nextRouterMock.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import { action } from '@storybook/addon-actions';
-
-/* Necessary to mock Next's router */
-// https://github.com/vercel/next.js/issues/1827#issuecomment-323721221
-const actionWithPromise = () => {
- action('clicked link')();
- // we need to return promise because it is needed by Link.linkClicked
- return new Promise((resolve, reject) => reject());
-};
-
-const mockedRouter = {
- pathname: 'mock-path',
- prefetch: () => {},
- push: actionWithPromise,
- replace: actionWithPromise,
- route: '/mock-route',
-};
-
-export default mockedRouter;
diff --git a/test-utils/mocks/passwordResetMock.js b/test-utils/mocks/passwordResetMock.js
deleted file mode 100644
index 142f0be2a..000000000
--- a/test-utils/mocks/passwordResetMock.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export const uid = 'Mjg';
-export const token = '56m-53bcc9ef792551752cd3';
diff --git a/test-utils/mocks/svgMock.js b/test-utils/mocks/svgMock.js
deleted file mode 100644
index 3afdb855b..000000000
--- a/test-utils/mocks/svgMock.js
+++ /dev/null
@@ -1,8 +0,0 @@
-const { createElement } = require('react');
-
-const Svg = props => createElement('svg', props, null);
-
-module.exports = {
- __esModule: true,
- default: Svg,
-};
diff --git a/test-utils/mocks/testFileMock.js b/test-utils/mocks/testFileMock.js
deleted file mode 100644
index d906d5b49..000000000
--- a/test-utils/mocks/testFileMock.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = 'test-file-mock';
diff --git a/test-utils/transforms/file.js b/test-utils/transforms/file.js
deleted file mode 100644
index b3c21e374..000000000
--- a/test-utils/transforms/file.js
+++ /dev/null
@@ -1,13 +0,0 @@
-'use strict'; // eslint-disable-line strict, lines-around-directive
-
-const path = require('path');
-
-// This is a custom Jest transformer turning file imports into filenames.
-// http://facebook.github.io/jest/docs/en/webpack.html
-module.exports = {
- process(source, filename) {
- const assetFilename = JSON.stringify(path.basename(filename));
-
- return `module.exports = ${assetFilename};`;
- },
-};
diff --git a/test-utils/wait.js b/test-utils/wait.js
deleted file mode 100644
index 1b2fa31b2..000000000
--- a/test-utils/wait.js
+++ /dev/null
@@ -1 +0,0 @@
-export default (ms = 0) => new Promise(resolve => setTimeout(resolve, ms));
From 48c1bc798466dee2dd1018ce7a3612df92e5d6e3 Mon Sep 17 00:00:00 2001
From: Kyle Holmberg
Date: Mon, 10 Nov 2025 20:57:49 +0700
Subject: [PATCH 3/5] fix .vscode/settings.json
---
.vscode/settings.json | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/.vscode/settings.json b/.vscode/settings.json
index e99350a39..62e7c2cad 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,5 +1,5 @@
{
- "typescript.tsdk": "node_modules/typescript/lib"
+ "typescript.tsdk": "node_modules/typescript/lib",
"tailwindCSS.classAttributes": ["className"],
"tailwindCSS.classFunctions": ["cx", "cva", "clsx", "classMerge", "twMerge"],
"tailwindCSS.lint.cssConflict": "ignore",
@@ -8,5 +8,4 @@
"clsx",
"tailwind-merge"
]
-
}
From 766bd3372c7ffe84264fbf1968eace1799a7b455 Mon Sep 17 00:00:00 2001
From: Kyle Holmberg
Date: Mon, 10 Nov 2025 21:20:01 +0700
Subject: [PATCH 4/5] convert some stuff to TS
---
.../config/{environment.js => environment.ts} | 2 +-
common/constants/{partners.js => partners.ts} | 2 +-
common/constants/successStories.js | 24 -------
common/constants/{testIDs.js => testIDs.ts} | 0
.../{unitsOfTime.js => unitsOfTime.ts} | 4 +-
common/constants/urls.js | 7 --
common/constants/urls.ts | 6 ++
common/utils/thirdParty/{gtag.js => gtag.ts} | 66 ++++++++++++-------
.../SponsorsSection/SponsorsSection.tsx | 6 +-
.../__tests__/SponsorsSection.test.tsx | 4 +-
pages/index.tsx | 22 ++++++-
11 files changed, 79 insertions(+), 64 deletions(-)
rename common/config/{environment.js => environment.ts} (95%)
rename common/constants/{partners.js => partners.ts} (98%)
delete mode 100644 common/constants/successStories.js
rename common/constants/{testIDs.js => testIDs.ts} (100%)
rename common/constants/{unitsOfTime.js => unitsOfTime.ts} (64%)
delete mode 100644 common/constants/urls.js
create mode 100644 common/constants/urls.ts
rename common/utils/thirdParty/{gtag.js => gtag.ts} (66%)
diff --git a/common/config/environment.js b/common/config/environment.ts
similarity index 95%
rename from common/config/environment.js
rename to common/config/environment.ts
index 64ac53b5d..7973de37c 100644
--- a/common/config/environment.js
+++ b/common/config/environment.ts
@@ -1,7 +1,7 @@
/*
* This file should only contain environment variables that are non-secret.
*/
-const isProduction = process.env.PRODUCTION_DEPLOYMENT === 'true';
+export const isProduction = process.env.PRODUCTION_DEPLOYMENT === 'true';
// These are all exposed by the client, so there's no way to protect them anyways.
export const clientTokens = isProduction
diff --git a/common/constants/partners.js b/common/constants/partners.ts
similarity index 98%
rename from common/constants/partners.js
rename to common/constants/partners.ts
index 2239248e6..fcaca60d5 100644
--- a/common/constants/partners.js
+++ b/common/constants/partners.ts
@@ -137,4 +137,4 @@ const partners = [
{ name: 'Airbnb', logoSource: airbnb.src, url: 'https://airbnb.com', type: PARTNER_TYPES.KIND },
];
-export default sortBy(partners, 'name');
+export const partnersSortedByName = sortBy(partners, 'name');
diff --git a/common/constants/successStories.js b/common/constants/successStories.js
deleted file mode 100644
index 2f680ff5f..000000000
--- a/common/constants/successStories.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import { s3 } from 'common/constants/urls';
-
-const successStories = [
- {
- title: 'Ali Cipolla-Taylor, Talent Acquisition at Microsoft',
- quote:
- 'I finished MSTA the last week of February, and then COVID hit. Employment was not going to happen…to anyone. I kept making calls, working on my skills, and throwing myself out there, and I got a role as a vendor at Microsoft. I’m half of the Data Privacy, Compliance, and Controls team for Talent Acquisition now. I had a lot of hard conversations with myself. I learned to lean into a support network, locally and online, through OpCode. I’m notoriously shy on the internet, but I knew that I couldn’t do this alone. Change happens when the discomfort of making the change is less than the life you’re living.',
- imageSource: `${s3}headshots/ali.jpg`,
- },
- {
- title: 'Princeton Baker, Enterprise Security Analyst',
- quote:
- 'I am a Navy vet. I started at the US Navy Ceremonial Guard then to Norfolk to work on ship weapon systems to Miami then San Diego as a Corpsman. I struggled mentally when I first got out. I really had to dig deep and find who I am not what I think I am. I am not just a veteran or software developer or the annoying security guy. I think many veterans are looking for a title and a clear path. I found out quickly on this side of civilization you have to make your own path. I did a 16-week full time coding boot camp while full time in school with a wife and two young boys during quarantine. Right now I am an Enterprise Security Analyst for a payment company and I love it. It is my first role in tech.',
- imageSource: `${s3}headshots/princeton.jpg`,
- },
- {
- title: 'Jose Camilo, Full-Stack Developer',
- quote:
- 'I joined the Army in 2014 as an active duty Calvary Scout. In 2017, I left active duty to continue college and joined the Army Reserves as a Human Resources Specialist. Still serving in the Reserves now. I doubted myself a lot, wondering the type of role I should focus on, the type of tech/ tools I should learn. Starting courses that I would not finish, and starting projects that I would not finish. It sounds like I been training for 2 years to get to this point, but in reality, there were many occasions in which I did not code for weeks due to being overwhelmed and option paralysis. This was also around the time I discovered Operation Code. I am now a Full Stack Developer at UBS.',
- imageSource: `${s3}headshots/jose.jpg`,
- },
-];
-
-export default successStories;
diff --git a/common/constants/testIDs.js b/common/constants/testIDs.ts
similarity index 100%
rename from common/constants/testIDs.js
rename to common/constants/testIDs.ts
diff --git a/common/constants/unitsOfTime.js b/common/constants/unitsOfTime.ts
similarity index 64%
rename from common/constants/unitsOfTime.js
rename to common/constants/unitsOfTime.ts
index 936e9485a..ae36423d1 100644
--- a/common/constants/unitsOfTime.js
+++ b/common/constants/unitsOfTime.ts
@@ -1,4 +1,6 @@
-// In seconds
+/** In seconds */
export const ONE_DAY = 86400;
+/** In seconds */
export const ONE_WEEK = 604800;
+/** In seconds */
export const TWO_WEEKS = 1209600;
diff --git a/common/constants/urls.js b/common/constants/urls.js
deleted file mode 100644
index fb4f84545..000000000
--- a/common/constants/urls.js
+++ /dev/null
@@ -1,7 +0,0 @@
-const s3hostName = 'operation-code-assets.s3.us-east-2.amazonaws.com';
-const s3 = `https://${s3hostName}/`;
-const leadershipCircleLink = 'https://secure.lglforms.com/form_engine/s/L428AQ2rrsFJQyy5Fbglvg';
-const codeOfConduct = `https://github.com/OperationCode/operationcode_docs/blob/master/community/code_of_conduct.md`;
-const slackGuidelines = `https://github.com/OperationCode/START_HERE/blob/master/community_guidelines.md`;
-
-module.exports = { s3hostName, s3, leadershipCircleLink, codeOfConduct, slackGuidelines };
diff --git a/common/constants/urls.ts b/common/constants/urls.ts
new file mode 100644
index 000000000..25f7c2310
--- /dev/null
+++ b/common/constants/urls.ts
@@ -0,0 +1,6 @@
+export const s3hostName = 'operation-code-assets.s3.us-east-2.amazonaws.com';
+export const s3 = `https://${s3hostName}/`;
+export const leadershipCircleLink =
+ 'https://secure.lglforms.com/form_engine/s/L428AQ2rrsFJQyy5Fbglvg';
+export const codeOfConduct = `https://github.com/OperationCode/operationcode_docs/blob/master/community/code_of_conduct.md`;
+export const slackGuidelines = `https://github.com/OperationCode/START_HERE/blob/master/community_guidelines.md`;
diff --git a/common/utils/thirdParty/gtag.js b/common/utils/thirdParty/gtag.ts
similarity index 66%
rename from common/utils/thirdParty/gtag.js
rename to common/utils/thirdParty/gtag.ts
index 9aa04cb69..45bfea61c 100644
--- a/common/utils/thirdParty/gtag.js
+++ b/common/utils/thirdParty/gtag.ts
@@ -1,15 +1,28 @@
import snakeCase from 'lodash/snakeCase';
-import { clientTokens } from 'common/config/environment';
+import { clientTokens, isProduction } from 'common/config/environment';
+
+declare global {
+ interface Window {
+ gtag?: (
+ command: 'config' | 'event',
+ targetId: string,
+ config?: Record,
+ ) => void;
+ }
+}
// TODO: Leverage prod-build-time-only env vars instead NODE_ENV for prod check
-const isProduction = process.env.NODE_ENV === 'production';
const isDevelopment = process.env.NODE_ENV === 'development';
+interface LogParams {
+ methodName: string;
+ [key: string]: unknown;
+}
+
/**
* @description dev-only logging of gtag methods
- * @param {{ methodName: string }} { methodName, ...rest }
*/
-const log = ({ methodName, ...rest }) => {
+const log = ({ methodName, ...rest }: LogParams): void => {
if (isDevelopment) {
console.log(`gtag.${methodName}\n`, rest); // eslint-disable-line no-console
}
@@ -17,11 +30,9 @@ const log = ({ methodName, ...rest }) => {
/**
* @description Log a pageview with gtag
- * @param {string} url
- * @param {boolean?} isModalView
* @see https://developers.google.com/analytics/devguides/collection/gtagjs/pages
*/
-const pageView = (url, isModalView = false) => {
+const pageView = (url: string, isModalView = false): void => {
log({ methodName: 'pageview', url, isModalView });
if (isProduction && !!window && !!window.gtag) {
@@ -31,16 +42,21 @@ const pageView = (url, isModalView = false) => {
}
};
+interface EventParams {
+ action: string;
+ /** Callback function to execute after the event */
+ callback?: () => void;
+ category: string;
+ /** Optional label for the event */
+ label?: string;
+ /** Optional numeric value for the event */
+ value?: number;
+ /** Additional event parameters */
+ otherEventParameters?: Record;
+}
+
/**
* @description Log an event with gtag
- * @param {{
- * action: string,
- * callback?: () => void,
- * category: string,
- * label?: string,
- * otherEventParameters?: object,
- * value?: number,
- * }}
* @see https://developers.google.com/analytics/devguides/collection/gtagjs/events
*/
const event = ({
@@ -50,7 +66,7 @@ const event = ({
label = undefined,
value = undefined,
otherEventParameters = {}, // https://developers.google.com/gtagjs/reference/parameter
-}) => {
+}: EventParams): void => {
if (!action || !category) {
throw new Error('Google Events must be called with at least an action and category.');
}
@@ -76,11 +92,17 @@ const event = ({
}
};
+interface ConversionEventParams {
+ /** Google Ads conversion ID */
+ adId: string;
+ /** Category for the conversion event */
+ category?: string;
+}
+
/**
* @description Log a conversion event with gtag (connected to Google Ads ID of a conversion)
- * @param {{ adId: string, category?: string }} { adId, category = 'engagement' }
*/
-const conversionEvent = ({ adId, category = 'engagement' }) => {
+const conversionEvent = ({ adId, category = 'engagement' }: ConversionEventParams): void => {
log({ methodName: 'adEvent', adId, category });
if (isProduction) {
@@ -94,23 +116,19 @@ const conversionEvent = ({ adId, category = 'engagement' }) => {
/**
* @description Log a link click which takes users away from our site
- * @param {string} label describe where the user is going
- * @param {string} url
*/
-const outboundLink = (label, url) => {
+const outboundLink = (label: string, url: string): void => {
event({
action: `To: ${label}`,
category: 'Outbound',
label: `URL: ${url}`,
- value: url,
});
};
/**
* @description Log a modal view as if it were a gtag page view event
- * @param {string} modalName
*/
-const modalView = modalName => {
+const modalView = (modalName: string): void => {
const url = `/modal/${snakeCase(modalName.toLowerCase())}`;
const isModalView = true;
diff --git a/components/ReusableSections/SponsorsSection/SponsorsSection.tsx b/components/ReusableSections/SponsorsSection/SponsorsSection.tsx
index 04b533b48..a0a28cbee 100644
--- a/components/ReusableSections/SponsorsSection/SponsorsSection.tsx
+++ b/components/ReusableSections/SponsorsSection/SponsorsSection.tsx
@@ -1,7 +1,7 @@
import Container from 'components/Container/Container';
import Heading from 'components/Heading/Heading';
import PartnerLogoLink from 'components/PartnerLogoLink/PartnerLogoLink';
-import partners, { PARTNER_TYPES } from 'common/constants/partners';
+import { PARTNER_TYPES, partnersSortedByName } from 'common/constants/partners';
interface Partner {
name: string;
@@ -20,7 +20,7 @@ const SponsorsSection = () => (
may or may not have also donated to our cause via others means.
- {partners
+ {partnersSortedByName
.filter(x => isPaidSponsor(x))
.map(partner => (
@@ -33,7 +33,7 @@ const SponsorsSection = () => (
advertisements, scholarships, or sponsorships. We thank them for their contributions.
- {partners
+ {partnersSortedByName
.filter(x => !isPaidSponsor(x))
.map(partner => (
diff --git a/components/ReusableSections/SponsorsSection/__tests__/SponsorsSection.test.tsx b/components/ReusableSections/SponsorsSection/__tests__/SponsorsSection.test.tsx
index 4479fe6a9..79c7a23f7 100644
--- a/components/ReusableSections/SponsorsSection/__tests__/SponsorsSection.test.tsx
+++ b/components/ReusableSections/SponsorsSection/__tests__/SponsorsSection.test.tsx
@@ -1,6 +1,6 @@
import { render } from '@testing-library/react';
import createSnapshotTest from 'test-utils/createSnapshotTest';
-import partners from 'common/constants/partners';
+import { partnersSortedByName } from 'common/constants/partners';
import SponsorsSection from '../SponsorsSection';
describe('SponsorsSection', () => {
@@ -14,7 +14,7 @@ describe('SponsorsSection', () => {
it('should render a secure link and image for each partner', () => {
const component = render();
- partners.forEach(partner => {
+ partnersSortedByName.forEach(partner => {
const image = component.queryByAltText(`${partner.name} logo`)!;
const link = image.closest('a') as HTMLAnchorElement;
expect(image).toBeInTheDocument();
diff --git a/pages/index.tsx b/pages/index.tsx
index 0614b5360..571adbf34 100644
--- a/pages/index.tsx
+++ b/pages/index.tsx
@@ -6,10 +6,30 @@ import SponsorsSection from 'components/ReusableSections/SponsorsSection/Sponsor
import SuccessStory from 'components/SuccessStory/SuccessStory';
import Heading from 'components/Heading/Heading';
import LinkButton from 'components/Buttons/LinkButton/LinkButton';
-import successStories from 'common/constants/successStories';
import { s3 } from 'common/constants/urls';
import { cx } from 'common/utils/cva';
+const successStories = [
+ {
+ title: 'Ali Cipolla-Taylor, Talent Acquisition at Microsoft',
+ quote:
+ 'I finished MSTA the last week of February, and then COVID hit. Employment was not going to happen…to anyone. I kept making calls, working on my skills, and throwing myself out there, and I got a role as a vendor at Microsoft. I’m half of the Data Privacy, Compliance, and Controls team for Talent Acquisition now. I had a lot of hard conversations with myself. I learned to lean into a support network, locally and online, through OpCode. I’m notoriously shy on the internet, but I knew that I couldn’t do this alone. Change happens when the discomfort of making the change is less than the life you’re living.',
+ imageSource: `${s3}headshots/ali.jpg`,
+ },
+ {
+ title: 'Princeton Baker, Enterprise Security Analyst',
+ quote:
+ 'I am a Navy vet. I started at the US Navy Ceremonial Guard then to Norfolk to work on ship weapon systems to Miami then San Diego as a Corpsman. I struggled mentally when I first got out. I really had to dig deep and find who I am not what I think I am. I am not just a veteran or software developer or the annoying security guy. I think many veterans are looking for a title and a clear path. I found out quickly on this side of civilization you have to make your own path. I did a 16-week full time coding boot camp while full time in school with a wife and two young boys during quarantine. Right now I am an Enterprise Security Analyst for a payment company and I love it. It is my first role in tech.',
+ imageSource: `${s3}headshots/princeton.jpg`,
+ },
+ {
+ title: 'Jose Camilo, Full-Stack Developer',
+ quote:
+ 'I joined the Army in 2014 as an active duty Calvary Scout. In 2017, I left active duty to continue college and joined the Army Reserves as a Human Resources Specialist. Still serving in the Reserves now. I doubted myself a lot, wondering the type of role I should focus on, the type of tech/ tools I should learn. Starting courses that I would not finish, and starting projects that I would not finish. It sounds like I been training for 2 years to get to this point, but in reality, there were many occasions in which I did not code for weeks due to being overwhelmed and option paralysis. This was also around the time I discovered Operation Code. I am now a Full Stack Developer at UBS.',
+ imageSource: `${s3}headshots/jose.jpg`,
+ },
+];
+
function Home() {
return (
From 2217ec50c3a2f6679d974b8ce7973ce5730bae02 Mon Sep 17 00:00:00 2001
From: Kyle Holmberg
Date: Mon, 10 Nov 2025 21:24:18 +0700
Subject: [PATCH 5/5] remove more
---
components/Press/PressLinks/Articles.ts | 8 +-
components/Press/PressLinks/PressLinks.tsx | 11 ++-
.../__snapshots__/PressLinks.test.tsx.snap | 78 +++++++++----------
components/Timeline/Timeline.tsx | 7 +-
.../__snapshots__/Timeline.test.tsx.snap | 14 ++--
next.config.js | 3 +-
utils/types.ts | 2 -
7 files changed, 58 insertions(+), 65 deletions(-)
delete mode 100644 utils/types.ts
diff --git a/components/Press/PressLinks/Articles.ts b/components/Press/PressLinks/Articles.ts
index 063c91a8f..0e070a3c7 100644
--- a/components/Press/PressLinks/Articles.ts
+++ b/components/Press/PressLinks/Articles.ts
@@ -1,4 +1,4 @@
-const Boston = [
+export const Boston = [
{
title: 'How Tech Pros Can Volunteer in Fun Ways',
url: 'https://insights.dice.com/2017/01/11/tech-pros-volunteer-fun-ways/',
@@ -33,7 +33,7 @@ const Boston = [
},
];
-const General = [
+export const General = [
{
title: 'TechHire Educator Spotlight: Operation Code',
url: 'https://blog.opportunityatwork.org/techhire-educator-spotlight-operation-code-debd0a796f9d',
@@ -170,7 +170,7 @@ const General = [
},
];
-const NYC = [
+export const NYC = [
{
title: 'New program aims to help veterans land jobs in tech industry',
url: 'https://wtkr.com/2018/05/16/new-program-aims-to-help-veterans-land-jobs-in-tech-industry/',
@@ -184,5 +184,3 @@ const NYC = [
url: 'https://www.wework.com/blog/posts/after-flying-solo-veterans-find-others-who-have-their-back',
},
];
-
-export { NYC, Boston, General };
diff --git a/components/Press/PressLinks/PressLinks.tsx b/components/Press/PressLinks/PressLinks.tsx
index b2b7e7ea6..33c4fe383 100644
--- a/components/Press/PressLinks/PressLinks.tsx
+++ b/components/Press/PressLinks/PressLinks.tsx
@@ -1,15 +1,14 @@
import * as Tabs from '@radix-ui/react-tabs';
import OutboundLink from 'components/OutboundLink/OutboundLink';
-import { objectKeys } from 'utils/types';
import { cx } from 'common/utils/cva';
-import * as Articles from './Articles';
+import * as articlesMap from './Articles';
function PressLinks() {
return (