@caseparts-org/casecore 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +60 -60
  2. package/dist/environment.d.ts +3 -0
  3. package/dist/environment.js +2 -0
  4. package/dist/src/App.d.ts +3 -0
  5. package/dist/src/App.js +46 -0
  6. package/dist/src/lib/authentication/AuthContext.d.ts +34 -0
  7. package/dist/src/lib/authentication/AuthContext.js +252 -0
  8. package/dist/src/lib/authentication/AuthContext.test.js +214 -0
  9. package/dist/src/lib/authentication/AuthTypes.d.ts +82 -0
  10. package/dist/src/lib/authentication/AuthTypes.js +1 -0
  11. package/dist/src/lib/hooks/useLocalStorage.d.ts +14 -0
  12. package/dist/src/lib/hooks/useLocalStorage.js +41 -0
  13. package/dist/src/lib/hooks/useMicroFlex.d.ts +28 -0
  14. package/dist/src/lib/hooks/useMicroFlex.js +138 -0
  15. package/dist/src/lib/index.d.ts +6 -0
  16. package/dist/src/lib/index.js +6 -0
  17. package/dist/src/lib/utils/ClaimsUtils.d.ts +16 -0
  18. package/dist/src/lib/utils/ClaimsUtils.js +76 -0
  19. package/dist/src/lib/utils/SessionUtils.d.ts +7 -0
  20. package/dist/src/lib/utils/SessionUtils.js +18 -0
  21. package/dist/src/local/impersonate/Impersonate.d.ts +1 -0
  22. package/dist/src/local/impersonate/Impersonate.js +62 -0
  23. package/dist/src/local/layout/Layout.d.ts +4 -0
  24. package/dist/src/local/layout/Layout.js +33 -0
  25. package/dist/src/local/login/Login.d.ts +1 -0
  26. package/dist/src/local/login/Login.js +53 -0
  27. package/dist/src/local/microflex/MicroFlex.d.ts +1 -0
  28. package/dist/src/local/microflex/MicroFlex.js +47 -0
  29. package/dist/src/local/util/AppSettings.d.ts +109 -0
  30. package/dist/src/local/util/AppSettings.js +138 -0
  31. package/dist/src/main.d.ts +1 -0
  32. package/dist/src/main.js +6 -0
  33. package/package.json +54 -53
  34. package/dist/authentication/AuthContext.d.ts +0 -14
  35. package/dist/authentication/AuthContext.helpers.d.ts +0 -0
  36. package/dist/authentication/AuthContext.helpers.js +0 -1
  37. package/dist/authentication/AuthContext.js +0 -21
  38. package/dist/authentication/AuthContext.test.js +0 -29
  39. package/dist/index.d.ts +0 -2
  40. package/dist/index.js +0 -1
  41. /package/dist/{authentication → src/lib/authentication}/AuthContext.test.d.ts +0 -0
  42. /package/dist/{test → src/lib/test}/setup.d.ts +0 -0
  43. /package/dist/{test → src/lib/test}/setup.js +0 -0
@@ -0,0 +1,62 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import Layout from '../layout/Layout';
4
+ import { useAuthContext } from '../../lib/authentication/AuthContext';
5
+ import AppSettings from '../util/AppSettings';
6
+ export default function Impersonate() {
7
+ const { fetch, impersonate } = useAuthContext() || {};
8
+ const [search, setSearch] = useState('');
9
+ const [results, setResults] = useState([]);
10
+ const [loading, setLoading] = useState(false);
11
+ const [error, setError] = useState(null);
12
+ const handleSearch = async () => {
13
+ if (!fetch || !search)
14
+ return;
15
+ setLoading(true);
16
+ setError(null);
17
+ try {
18
+ const url = AppSettings.Authentication.ImpersonateSearch + encodeURIComponent(search);
19
+ const res = await fetch(url);
20
+ if (!res)
21
+ throw new Error('No response');
22
+ const data = await res.json();
23
+ setResults(Array.isArray(data) ? data : (data.results || []));
24
+ }
25
+ catch (e) {
26
+ setError(e.message || 'Search failed');
27
+ setResults([]);
28
+ }
29
+ finally {
30
+ setLoading(false);
31
+ }
32
+ };
33
+ const handleKeyDown = (e) => {
34
+ if (e.key === 'Enter')
35
+ handleSearch();
36
+ };
37
+ const handleSelect = async (email) => {
38
+ if (!impersonate)
39
+ return;
40
+ try {
41
+ await impersonate(email);
42
+ // Optionally, redirect or show a message
43
+ }
44
+ catch {
45
+ setError('Impersonation failed');
46
+ }
47
+ };
48
+ return (_jsx(Layout, { children: _jsxs("div", { style: { display: 'flex', flexDirection: 'column', height: '100vh' }, children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'column', alignItems: 'center', marginBottom: 24 }, children: [_jsx("h1", { style: { margin: 0, marginRight: 24, marginBottom: 12 }, children: "Impersonate" }), _jsxs("div", { children: [_jsx("input", { type: "text", placeholder: "Search user by email or name", value: search, onChange: e => setSearch(e.target.value), onKeyDown: handleKeyDown, style: { minWidth: 300, marginRight: 8, height: '30px', paddingLeft: '4px' }, autoComplete: "impersonate-email" }), _jsx("button", { onClick: handleSearch, disabled: loading, children: "Search" })] })] }), error && _jsx("div", { style: { color: 'red', marginTop: 8 }, children: error }), _jsx("div", { style: { marginTop: 16, flex: 1, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 16 }, children: results.map((user, idx) => (_jsxs("div", { style: {
49
+ border: '1px solid #ccc',
50
+ borderRadius: 8,
51
+ padding: 16,
52
+ minWidth: 260,
53
+ marginBottom: 8,
54
+ boxShadow: '0 2px 8px rgba(0,0,0,0.04)',
55
+ cursor: 'pointer',
56
+ background: '#111',
57
+ transition: 'box-shadow 0.2s',
58
+ userSelect: 'none',
59
+ height: 'min-content'
60
+ }, onClick: () => handleSelect(user.UserName), tabIndex: 0, onKeyDown: e => { if (e.key === 'Enter')
61
+ handleSelect(user.UserName); }, children: [_jsx("div", { style: { fontWeight: 600, fontSize: 16, marginBottom: 2 }, children: user.CustId }), _jsx("div", { style: { marginBottom: 2 }, children: user.UserName }), _jsx("div", { style: { color: '#777', fontSize: 14 }, children: user.CustName })] }, user.Id || user.email || idx))) })] }) }));
62
+ }
@@ -0,0 +1,4 @@
1
+ export default function Layout({ children }: {
2
+ children: React.ReactNode;
3
+ }): import("react/jsx-runtime").JSX.Element;
4
+ export declare function Navigation(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Link } from 'react-router-dom';
3
+ import { useAuthContext } from '../../lib';
4
+ export default function Layout({ children }) {
5
+ return (_jsxs("div", { style: {
6
+ minHeight: '100vh',
7
+ width: '100vw',
8
+ display: 'flex',
9
+ flexDirection: 'column',
10
+ }, children: [_jsx(Navigation, {}), _jsx("main", { style: {
11
+ flex: 1,
12
+ display: 'flex',
13
+ alignItems: 'center',
14
+ justifyContent: 'center',
15
+ width: '100%',
16
+ }, children: children })] }));
17
+ }
18
+ export function Navigation() {
19
+ const auth = useAuthContext();
20
+ return (_jsx("nav", { style: {
21
+ width: '100%',
22
+ background: '#222',
23
+ color: '#fff',
24
+ padding: '0.5rem 1rem',
25
+ marginBottom: '2rem',
26
+ boxSizing: 'border-box',
27
+ }, children: _jsxs("ul", { style: {
28
+ display: 'flex',
29
+ listStyle: 'none',
30
+ margin: 0,
31
+ padding: 0,
32
+ }, children: [_jsx("li", { style: { marginRight: '1.5rem' }, children: _jsx(Link, { to: "/", style: { color: '#fff', textDecoration: 'none' }, children: "Home" }) }), _jsx("li", { style: { marginRight: '1.5rem' }, children: _jsx(Link, { to: "/login", style: { color: '#fff', textDecoration: 'none' }, children: auth?.email ? _jsx(_Fragment, { children: auth.email }) : _jsx(_Fragment, { children: "Login" }) }) }), _jsx("li", { style: { marginRight: '1.5rem' }, children: _jsx(Link, { to: "/impersonate", style: { color: '#fff', textDecoration: 'none' }, children: "Impersonate" }) }), _jsx("li", { style: { marginRight: '1.5rem' }, children: _jsx(Link, { to: "/microflex", style: { color: '#fff', textDecoration: 'none' }, children: "MicroFlex" }) })] }) }));
33
+ }
@@ -0,0 +1 @@
1
+ export default function Login(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,53 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { useAuthContext } from '../../lib/authentication/AuthContext';
4
+ import Layout from '../layout/Layout';
5
+ export default function Login() {
6
+ const auth = useAuthContext();
7
+ console.log(auth);
8
+ if (!auth || auth.userType === "Guest") {
9
+ return _jsx(LoginForm, {});
10
+ }
11
+ const userName = auth.claims?.Customer?.FirstName && auth.claims?.Customer?.LastName
12
+ ? `${auth.claims.Customer.FirstName} ${auth.claims.Customer.LastName}`
13
+ : auth.claims?.Employee?.NickName || auth.claims?.Employee?.UserName || "";
14
+ return (_jsx(Layout, { children: _jsxs("div", { style: {
15
+ minWidth: 320,
16
+ maxWidth: 600,
17
+ width: '100%',
18
+ background: '#181818',
19
+ color: '#fff',
20
+ padding: 24,
21
+ borderRadius: 8,
22
+ boxShadow: '0 2px 8px rgba(0,0,0,0.2)',
23
+ overflow: 'auto',
24
+ // maxHeight: 500,
25
+ }, children: [_jsx("h1", { style: { marginBottom: 12 }, children: "Account" }), _jsxs("div", { style: { marginBottom: 12 }, children: [_jsx("strong", { children: "Email:" }), " ", auth.email] }), _jsxs("div", { style: { marginBottom: 12 }, children: [_jsx("strong", { children: "Name:" }), " ", userName] }), _jsxs("div", { style: { marginBottom: 12 }, children: [_jsx("strong", { children: "Claims:" }), _jsx("pre", { style: {
26
+ background: '#222',
27
+ color: '#fff',
28
+ padding: 12,
29
+ borderRadius: 4,
30
+ maxHeight: 300,
31
+ overflow: 'auto',
32
+ fontSize: 13,
33
+ }, children: JSON.stringify(auth.claims, null, 2) })] }), _jsxs("div", { style: { width: '100%', display: 'flex', flexDirection: 'row', gap: 8, justifyContent: 'center' }, children: [_jsx("button", { onClick: () => auth.logout(), children: "Logout" }), auth.userType === "Employee" && auth.claims?.Customer &&
34
+ _jsx("button", { onClick: () => auth.impersonate(null), children: "Cancel Impersonation" })] })] }) }));
35
+ }
36
+ function LoginForm() {
37
+ const auth = useAuthContext();
38
+ const [email, setEmail] = useState('');
39
+ const [password, setPassword] = useState('');
40
+ const [error, setError] = useState(null);
41
+ const handleSubmit = async (e) => {
42
+ e.preventDefault();
43
+ setError(null);
44
+ try {
45
+ await auth?.login(email, password);
46
+ // Optionally redirect or show success
47
+ }
48
+ catch (err) {
49
+ setError(err?.message || 'Login failed');
50
+ }
51
+ };
52
+ return (_jsx(Layout, { children: _jsxs("div", { style: { minWidth: 300 }, children: [_jsx("h1", { children: "Login" }), _jsxs("form", { onSubmit: handleSubmit, children: [_jsx("div", { style: { marginBottom: 12 }, children: _jsxs("label", { children: ["Email:", _jsx("input", { type: "email", value: email, onChange: e => setEmail(e.target.value), required: true, style: { width: '100%', height: '30px', paddingLeft: '4px' } })] }) }), _jsx("div", { style: { marginBottom: 12 }, children: _jsxs("label", { children: ["Password:", _jsx("input", { type: "password", value: password, onChange: e => setPassword(e.target.value), required: true, style: { width: '100%', height: '30px', paddingLeft: '4px' } })] }) }), error && _jsx("div", { style: { color: 'red', marginBottom: 12 }, children: error }), _jsx("button", { type: "submit", style: { width: '100%' }, children: "Login" })] })] }) }));
53
+ }
@@ -0,0 +1 @@
1
+ export default function MicroFlex(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,47 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import useMicroFlex from "../../lib/hooks/useMicroFlex";
4
+ import AppSettings from "../util/AppSettings";
5
+ import { useAuthContext } from "../../lib";
6
+ import Layout from "../layout/Layout";
7
+ export default function MicroFlex() {
8
+ let port = '';
9
+ if (window.location.hostname.includes("localhost"))
10
+ port = window.location.port;
11
+ const auth = useAuthContext();
12
+ const apiURL = AppSettings.Endpoints.MicroFlexFormAuth(port);
13
+ // Ensure fetchFn is always defined and returns Promise<Response>
14
+ const fetchFn = (auth?.fetch ??
15
+ (async (_url, _options) => {
16
+ // fallback: throw error if fetch is not available
17
+ throw new Error("fetchFn is not defined");
18
+ }));
19
+ const { validate, cardToken, cardError, setupError, autoCompleteData, } = useMicroFlex({ initializeForm: !!auth?.initialized, apiURL, fetchFn });
20
+ const [validationResult, setValidationResult] = useState(undefined);
21
+ const [validationError, setValidationError] = useState(undefined);
22
+ const handleValidate = async () => {
23
+ setValidationResult(undefined);
24
+ setValidationError(undefined);
25
+ try {
26
+ const token = await validate();
27
+ setValidationResult(token);
28
+ }
29
+ catch (err) {
30
+ setValidationError(err?.message || String(err));
31
+ }
32
+ };
33
+ return (_jsx(Layout, { children: _jsxs("div", { style: { width: 400, maxWidth: 400 }, children: [_jsx("h2", { children: "MicroFlex Manual Test UI" }), _jsxs("div", { children: [_jsx("div", { id: "number", style: { height: 30, marginBottom: 12, borderRadius: 8, border: "1px solid #ccc", padding: 4 } }), _jsx("div", { id: "securityCode", style: { height: 30, marginBottom: 12, borderRadius: 8, border: "1px solid #ccc", padding: 4 } })] }), _jsx("button", { onClick: handleValidate, style: { marginBottom: 16 }, children: "Validate Card" }), _jsxs("div", { style: { marginBottom: 16 }, children: [validationResult && (_jsxs("div", { style: { color: "green", wordBreak: "break-all", whiteSpace: "pre-wrap", maxHeight: 200, overflow: "auto" }, children: ["Token: ", validationResult] })), validationError && (_jsxs("div", { style: { color: "red", wordBreak: "break-all", whiteSpace: "pre-wrap", maxHeight: 200, overflow: "auto" }, children: ["Validation Error: ", validationError] }))] }), _jsxs("div", { children: [_jsx("strong", { children: "Hook State:" }), _jsx("pre", { style: {
34
+ background: '#222',
35
+ color: '#fff',
36
+ padding: 12,
37
+ borderRadius: 4,
38
+ maxHeight: 300,
39
+ overflow: 'auto',
40
+ fontSize: 13,
41
+ }, children: JSON.stringify({
42
+ cardToken,
43
+ cardError,
44
+ setupError,
45
+ autoCompleteData,
46
+ }, null, 2) })] })] }) }));
47
+ }
@@ -0,0 +1,109 @@
1
+ interface IAuthentication {
2
+ ConfirmEmail: string;
3
+ ResendConfirmationEmail: string;
4
+ ForgotPassword: string;
5
+ ResetPassword: string;
6
+ Login: string;
7
+ Logout: string;
8
+ Register: string;
9
+ ImpersonateSearch: string;
10
+ Impersonate: (_email?: string | null) => string;
11
+ ForgotPasswordUrl: string;
12
+ }
13
+ interface ICatalog {
14
+ Sections: () => string;
15
+ Blocks: (_section: string) => string;
16
+ Parts: (_block: string) => string;
17
+ Part: (_item: string, _block: string) => string;
18
+ Search: (_input: string, _count?: number, _showAll?: boolean) => string;
19
+ SearchCount: (_input: string) => string;
20
+ Images: (_name?: string) => string;
21
+ Inventory: (_partId: string) => string;
22
+ InventoryBatch: () => string;
23
+ PartPrice: (_partId: string) => string;
24
+ PartPriceBatch: () => string;
25
+ }
26
+ interface ICasePics {
27
+ PartImages: (_itemKey: string) => string;
28
+ Report: (_report: string) => string;
29
+ TopUsers: () => string;
30
+ Progress: () => string;
31
+ SaveImages: () => string;
32
+ SignalRHub: () => string;
33
+ }
34
+ interface ICheckout {
35
+ AccountInfo: (_custId: string) => string;
36
+ VerifyOrder: () => string;
37
+ GetRequestId: () => string;
38
+ SubmitOrder: () => string;
39
+ }
40
+ interface ICustomParts {
41
+ GasketProfile: (_profile: string) => string;
42
+ Heaters: () => string;
43
+ Coils: () => string;
44
+ Shelves: () => string;
45
+ }
46
+ interface IIntegrations {
47
+ CybersourceUrl: string;
48
+ Loupe: string;
49
+ }
50
+ interface IEndpoints {
51
+ Exemptions: (_custId: string) => string;
52
+ ExemptionsUrl: () => string;
53
+ Users: () => string;
54
+ Addresses: () => string;
55
+ EmployeeUsers: () => string;
56
+ Payments: () => string;
57
+ OrderDetail: (_op: string, _requestId?: string) => string;
58
+ MicroFlexFormAuth: (_port: string | null) => string;
59
+ }
60
+ interface IImages {
61
+ WebSpin: (_itemId: string) => string;
62
+ SpinStill: (_itemId: string) => string;
63
+ Supplemental: (_itemId: string) => string;
64
+ }
65
+ interface IPages {
66
+ PartFinder: string;
67
+ Intranet: string;
68
+ Account: string;
69
+ UserManager: string;
70
+ Custom: string;
71
+ Faq: string;
72
+ About: string;
73
+ Contact: string;
74
+ Forms: string;
75
+ Dashboard: string;
76
+ OrdersChart: string;
77
+ ReportClient: string;
78
+ EmployeeFaq: string;
79
+ CsrFaq: string;
80
+ ForgotPassword: string;
81
+ Register: string;
82
+ Orders: string;
83
+ Benefits: string;
84
+ CustomCoilForm: string;
85
+ CustomDoorForm: string;
86
+ CustomShelfForm: string;
87
+ }
88
+ interface IAnalytics {
89
+ GaHostname: string;
90
+ }
91
+ interface IAppSettings {
92
+ CustomerSite: string;
93
+ Version: string;
94
+ Env: string;
95
+ IsProd: boolean;
96
+ SignalR: string;
97
+ Authentication: IAuthentication;
98
+ Catalog: ICatalog;
99
+ CasePics: ICasePics;
100
+ Checkout: ICheckout;
101
+ CustomParts: ICustomParts;
102
+ Integrations: IIntegrations;
103
+ Endpoints: IEndpoints;
104
+ Images: IImages;
105
+ Pages: IPages;
106
+ Analytics: IAnalytics;
107
+ }
108
+ declare const AppSettings: IAppSettings;
109
+ export default AppSettings;
@@ -0,0 +1,138 @@
1
+ import environment from "../../../environment";
2
+ const Version = "3.6";
3
+ const IsProd = environment === "Prod";
4
+ const IsLocalRequestServer = false;
5
+ const IsLocalApi = false;
6
+ const CustomerSite = IsProd ? "https://www.caseparts.com" : "https://dev.caseparts.com";
7
+ const ApiServer = IsLocalApi
8
+ ? "https://localhost:44340/api/"
9
+ : IsProd
10
+ ? "https://my.caseparts.com/core/api/"
11
+ : "https://mydev.caseparts.com/core/api/";
12
+ const BaseUrl = IsLocalRequestServer
13
+ ? "https://localhost:44340/"
14
+ : IsProd
15
+ ? "https://my.caseparts.com/core/"
16
+ : "https://mydev.caseparts.com/core/";
17
+ const MyServer = IsLocalRequestServer
18
+ ? "http://localhost:44340"
19
+ : IsProd
20
+ ? "https://my.caseparts.com"
21
+ : "https://mydev.caseparts.com";
22
+ const CatalogServer = IsLocalRequestServer
23
+ ? "http://localhost:44340"
24
+ : IsProd
25
+ ? "https://www.caseparts.com"
26
+ : "https://dev.caseparts.com";
27
+ // const MobileServer: string = environment === "local"
28
+ // ? "http://localhost:3000"
29
+ // : IsProd
30
+ // ? "https://mobile.caseparts.com"
31
+ // : "https://mobiledev.caseparts.com";
32
+ const CatalogImageServer = IsProd ? "https://www.caseparts.com/graphics" : "https://dev.caseparts.com/graphics";
33
+ const Api = (endpoint) => ApiServer + endpoint;
34
+ const SignalR = (hub) => BaseUrl + hub;
35
+ const My = (url) => MyServer + url;
36
+ const Main = (url) => CatalogServer + url;
37
+ const AppSettings = {
38
+ CustomerSite: CustomerSite,
39
+ Version: Version,
40
+ Env: environment,
41
+ IsProd: IsProd,
42
+ SignalR: SignalR("signalr/"),
43
+ Authentication: {
44
+ ConfirmEmail: Api("authenticate/confirmemail/"),
45
+ ResendConfirmationEmail: Api("authenticate/resendconfirmemail"),
46
+ ForgotPassword: Api("authenticate/forgotpassword"),
47
+ ResetPassword: Api("authenticate/resetpassword"),
48
+ Login: Api("authenticate/login"),
49
+ Logout: Api("authenticate/logout"),
50
+ Register: Api("authenticate/register"),
51
+ ImpersonateSearch: Api("myaccount/search?val="),
52
+ Impersonate: (_email) => _email ? Api("authenticate/impersonate?email=") + _email : Api("authenticate/impersonate"),
53
+ ForgotPasswordUrl: My("/account/forgotpassword"),
54
+ },
55
+ Catalog: {
56
+ Sections: () => Api("mobilecatalog/sections"),
57
+ Blocks: (_section) => Api(`mobilecatalog/blocks/${_section}`),
58
+ Parts: (_block) => Api(`mobilecatalog/block/${_block}/parts`),
59
+ Part: (_item, _block) => Api(`mobilecatalog/parts/${_item}/${_block}`),
60
+ Search: (_input, _count = 20, _showAll = false) => Api(`mobilecatalog/search/?keywords=${_input}&rowCount=${_count}&showAll=${_showAll}`),
61
+ SearchCount: (_input) => Api(`mobilecatalog/searchCount/?keywords=${_input}`),
62
+ Images: (_name) => `${CatalogImageServer}/${_name ?? ''}`,
63
+ Inventory: (_partId) => Api(`part/inventory/${_partId}`),
64
+ InventoryBatch: () => Api(`part/inventory/batch`),
65
+ PartPrice: (_partId) => Api(`part/pricing/${_partId}`),
66
+ PartPriceBatch: () => Api(`part/pricing`),
67
+ },
68
+ CasePics: {
69
+ PartImages: (_itemKey) => Api(`casepics/part/${_itemKey}`),
70
+ Report: (_report) => Api(`casepics/report/${_report}`),
71
+ TopUsers: () => Api("casepics/top-users"),
72
+ Progress: () => Api("casepics/progress"),
73
+ SaveImages: () => Api("casepics/save"),
74
+ SignalRHub: () => SignalR("casepicshub"),
75
+ },
76
+ Checkout: {
77
+ AccountInfo: (_custId) => Api(`checkout/GetCheckoutInfo?customerid=${_custId}`),
78
+ VerifyOrder: () => Api("checkout/VerifyOrder"),
79
+ GetRequestId: () => Api("requests"),
80
+ SubmitOrder: () => Api("checkout/CreateQuote"),
81
+ },
82
+ CustomParts: {
83
+ GasketProfile: (_profile) => `${CatalogImageServer}%2fDrawings%5c${_profile}.png`,
84
+ Heaters: () => Api("part/heaters"),
85
+ Coils: () => Api("mobilecatalog/block/evaporator-coils-index/parts"),
86
+ Shelves: () => Api("mobilecatalog/block/wire-shelf-index/parts"),
87
+ },
88
+ Integrations: {
89
+ CybersourceUrl: Api("cybersource"),
90
+ Loupe: `${MyServer}/core`,
91
+ },
92
+ Endpoints: {
93
+ Exemptions: (_custId) => Api(`avatax/customers/${_custId}/exemptions`),
94
+ ExemptionsUrl: () => Api("avatax/certexpress"),
95
+ Users: () => Api("myaccount/users"),
96
+ Addresses: () => Api("myaccount/addresses"),
97
+ EmployeeUsers: () => Api("myaccount/internal/users"),
98
+ Payments: () => Api("myaccount/cards"),
99
+ OrderDetail: (_op, _requestId) => {
100
+ let url = Api(`myaccount/order/view/${_op}`);
101
+ url += _requestId ? `/${_requestId}` : "";
102
+ return url;
103
+ },
104
+ MicroFlexFormAuth: (_port) => Api(`cybersource/publickey/${_port || ''}`)
105
+ },
106
+ Images: {
107
+ WebSpin: (_itemId) => `${CatalogServer}/Ortery/360/Optimized/${_itemId}_/`,
108
+ SpinStill: (_itemId) => `${CatalogServer}/Ortery/360/Optimized/${_itemId}_/`,
109
+ Supplemental: (_itemId) => `${CatalogServer}/Ortery/2D/Optimized/${_itemId}/`,
110
+ },
111
+ Pages: {
112
+ PartFinder: Main(""),
113
+ Intranet: My("/home"),
114
+ Account: Main("/account"),
115
+ UserManager: Main("/account/cpc/users"),
116
+ Custom: Main("/custom"),
117
+ Faq: Main("/faq"),
118
+ About: Main("/about"),
119
+ Contact: Main("/account/contactus"),
120
+ Forms: Main("/forms"),
121
+ Dashboard: Main("/dash"),
122
+ OrdersChart: Main("/orders"),
123
+ ReportClient: My("/reports"),
124
+ EmployeeFaq: Main("/cpc"),
125
+ CsrFaq: Main("/csr"),
126
+ ForgotPassword: Main("/account/forgotpassword"),
127
+ Register: Main("/account/register"),
128
+ Orders: Main("/account/orders"),
129
+ Benefits: Main("/account/benefits"),
130
+ CustomCoilForm: My("/pdf/Custom Coil Order Form.pdf"),
131
+ CustomDoorForm: My("/pdf/Walk-In%20Door%20Order%20Form.pdf"),
132
+ CustomShelfForm: My("/pdf/Wire%20Shelf%20Order%20Form.pdf"),
133
+ },
134
+ Analytics: {
135
+ GaHostname: "www.caseparts.com",
136
+ },
137
+ };
138
+ export default AppSettings;
@@ -0,0 +1 @@
1
+ import './index.css';
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { StrictMode } from 'react';
3
+ import { createRoot } from 'react-dom/client';
4
+ import './index.css';
5
+ import App from './App';
6
+ createRoot(document.getElementById('root')).render(_jsx(StrictMode, { children: _jsx(App, {}) }));
package/package.json CHANGED
@@ -1,53 +1,54 @@
1
- {
2
- "name": "@caseparts-org/casecore",
3
- "private": false,
4
- "version": "0.0.3",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js",
12
- "require": "./dist/index.js"
13
- }
14
- },
15
- "files": [
16
- "dist"
17
- ],
18
- "peerDependencies": {
19
- "react": "^18.0.0"
20
- },
21
- "scripts": {
22
- "dev": "vite",
23
- "build": "tsc -p tsconfig.json",
24
- "lint": "eslint .",
25
- "preview": "vite preview",
26
- "test": "vitest",
27
- "test:ci": "vitest run"
28
- },
29
- "dependencies": {
30
- "jwt-decode": "^4.0.0",
31
- "react": "^18.0.0",
32
- "react-dom": "^18.0.0",
33
- "uuid": "^11.1.0"
34
- },
35
- "devDependencies": {
36
- "@eslint/js": "^9.29.0",
37
- "@testing-library/jest-dom": "^6.6.3",
38
- "@testing-library/react": "^16.3.0",
39
- "@types/node": "^24.0.4",
40
- "@types/react": "^19.1.8",
41
- "@types/react-dom": "^19.1.6",
42
- "@vitejs/plugin-react": "^4.5.2",
43
- "eslint": "^9.29.0",
44
- "eslint-plugin-react-hooks": "^5.2.0",
45
- "eslint-plugin-react-refresh": "^0.4.20",
46
- "globals": "^16.2.0",
47
- "jsdom": "^26.1.0",
48
- "typescript": "~5.8.3",
49
- "typescript-eslint": "^8.34.1",
50
- "vite": "^7.0.0",
51
- "vitest": "^3.2.4"
52
- }
53
- }
1
+ {
2
+ "name": "@caseparts-org/casecore",
3
+ "private": false,
4
+ "version": "0.0.5",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "peerDependencies": {
19
+ "react": "^18.0.0"
20
+ },
21
+ "scripts": {
22
+ "dev": "vite",
23
+ "build": "tsc -p tsconfig.json",
24
+ "lint": "eslint .",
25
+ "preview": "vite preview",
26
+ "test": "vitest",
27
+ "test:ci": "vitest run"
28
+ },
29
+ "dependencies": {
30
+ "jwt-decode": "^4.0.0",
31
+ "react": "^18.0.0",
32
+ "react-dom": "^18.0.0",
33
+ "uuid": "^11.1.0"
34
+ },
35
+ "devDependencies": {
36
+ "@eslint/js": "^9.29.0",
37
+ "@testing-library/jest-dom": "^6.6.3",
38
+ "@testing-library/react": "^16.3.0",
39
+ "@types/node": "^24.0.4",
40
+ "@types/react": "^19.1.8",
41
+ "@types/react-dom": "^19.1.6",
42
+ "@vitejs/plugin-react": "^4.5.2",
43
+ "eslint": "^9.29.0",
44
+ "eslint-plugin-react-hooks": "^5.2.0",
45
+ "eslint-plugin-react-refresh": "^0.4.20",
46
+ "globals": "^16.2.0",
47
+ "jsdom": "^26.1.0",
48
+ "react-router-dom": "^7.6.3",
49
+ "typescript": "~5.8.3",
50
+ "typescript-eslint": "^8.34.1",
51
+ "vite": "^7.0.0",
52
+ "vitest": "^3.2.4"
53
+ }
54
+ }
@@ -1,14 +0,0 @@
1
- import React from "react";
2
- export interface AuthContextValue {
3
- initialized: string;
4
- login: (_email: string, _password: string) => void;
5
- user: string | null;
6
- }
7
- export declare const AuthContext: React.Context<AuthContextValue | undefined>;
8
- export declare const useAuthContext: () => AuthContextValue;
9
- export interface AuthProviderProps {
10
- children: React.ReactNode;
11
- apiKey: string;
12
- loginUrl: string;
13
- }
14
- export declare const AuthProvider: React.FC<AuthProviderProps>;
File without changes
@@ -1 +0,0 @@
1
- "use strict";
@@ -1,21 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { createContext, useContext, useState } from "react";
3
- export const AuthContext = createContext(undefined);
4
- export const useAuthContext = () => {
5
- const ctx = useContext(AuthContext);
6
- if (!ctx)
7
- throw new Error("Must be inside AuthProvider");
8
- return ctx;
9
- };
10
- export const AuthProvider = ({ children, apiKey, loginUrl, }) => {
11
- const [initialized] = useState("OK");
12
- const [user, setUser] = useState(null);
13
- const login = (email, password) => {
14
- // Use both email and password to avoid unused variable error
15
- console.log(`Logging in with email: ${email} and password: ${password}`);
16
- setUser(`${email}.${password}`);
17
- };
18
- console.log(apiKey);
19
- console.log(loginUrl);
20
- return (_jsx(AuthContext.Provider, { value: { initialized, login, user }, children: children }));
21
- };
@@ -1,29 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { describe, it, expect } from 'vitest';
3
- import { render, screen } from '@testing-library/react';
4
- import { AuthProvider, useAuthContext } from './AuthContext';
5
- /**
6
- * Dummy component to consume the AuthContext
7
- */
8
- function ShowAuthState() {
9
- const { initialized } = useAuthContext();
10
- return _jsx("span", { "data-testid": "auth-state", children: initialized });
11
- }
12
- describe('AuthContext', () => {
13
- it('provides initialized state to children', () => {
14
- render(_jsx(AuthProvider, { loginUrl: '/login', apiKey: '123', children: _jsx(ShowAuthState, {}) }));
15
- // The initial state should be "OK"
16
- expect(screen.getByTestId('auth-state')).toHaveTextContent('OK');
17
- });
18
- it('throws error if used outside AuthProvider', () => {
19
- // Expect the hook to throw if used outside the provider
20
- // (React Testing Library can't render hooks directly; need to use a component)
21
- // We'll use a function to capture the error:
22
- function CallWithoutProvider() {
23
- useAuthContext();
24
- return null;
25
- }
26
- // Wrap in a function to capture the thrown error
27
- expect(() => render(_jsx(CallWithoutProvider, {}))).toThrow(/Must be inside AuthProvider/);
28
- });
29
- });