@seamapi/react 0.15.0 → 0.16.0

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 (35) hide show
  1. package/lib/SeamProvider.d.ts +14 -6
  2. package/lib/SeamProvider.js +62 -16
  3. package/lib/SeamProvider.js.map +1 -1
  4. package/lib/hooks/use-access-codes.d.ts +5 -0
  5. package/lib/hooks/use-access-codes.js +16 -0
  6. package/lib/hooks/use-access-codes.js.map +1 -0
  7. package/lib/hooks/use-device.d.ts +5 -0
  8. package/lib/hooks/use-device.js +17 -0
  9. package/lib/hooks/use-device.js.map +1 -0
  10. package/lib/hooks/use-devices.d.ts +1 -0
  11. package/lib/hooks/use-devices.js +2 -0
  12. package/lib/hooks/use-devices.js.map +1 -0
  13. package/lib/hooks/use-seam-client.d.ts +1 -0
  14. package/lib/hooks/use-seam-client.js +2 -0
  15. package/lib/hooks/use-seam-client.js.map +1 -0
  16. package/lib/seam/use-seam-client.js +28 -26
  17. package/lib/seam/use-seam-client.js.map +1 -1
  18. package/lib/types/use-seam-query-result.d.ts +5 -0
  19. package/lib/types/use-seam-query-result.js +2 -0
  20. package/lib/types/use-seam-query-result.js.map +1 -0
  21. package/lib/ui/AccessCodeTable/AccessCodeTable.d.ts +3 -5
  22. package/lib/ui/AccessCodeTable/AccessCodeTable.js +8 -2
  23. package/lib/ui/AccessCodeTable/AccessCodeTable.js.map +1 -1
  24. package/lib/ui/DeviceDetails/DeviceDetails.js +1 -3
  25. package/lib/ui/DeviceDetails/DeviceDetails.js.map +1 -1
  26. package/package.json +5 -3
  27. package/src/lib/SeamProvider.tsx +102 -30
  28. package/src/lib/hooks/use-access-codes.ts +21 -0
  29. package/src/lib/hooks/use-device.ts +26 -0
  30. package/src/lib/hooks/use-devices.ts +1 -0
  31. package/src/lib/hooks/use-seam-client.ts +1 -0
  32. package/src/lib/seam/use-seam-client.ts +45 -39
  33. package/src/lib/types/use-seam-query-result.ts +7 -0
  34. package/src/lib/ui/AccessCodeTable/AccessCodeTable.tsx +9 -7
  35. package/src/lib/ui/DeviceDetails/DeviceDetails.tsx +2 -5
@@ -1,20 +1,28 @@
1
1
  import { type PropsWithChildren } from 'react';
2
2
  import type { Seam, SeamClientOptions } from 'seamapi';
3
3
  declare global {
4
- var seam: Omit<SeamProviderProps, 'children'> | undefined;
4
+ var seam: SeamProviderProps | undefined;
5
5
  }
6
6
  export interface SeamContext {
7
7
  client: Seam | null;
8
- clientOptions?: SeamClientOptions | undefined;
8
+ clientOptions?: AllowedSeamClientOptions | undefined;
9
9
  publishableKey?: string | undefined;
10
10
  userIdentifierKey?: string | undefined;
11
+ clientSessionToken?: string | undefined;
11
12
  }
12
- export interface SeamProviderProps {
13
- client?: Seam;
14
- publishableKey?: string;
13
+ type SeamProviderProps = SeamProviderPropsWithClient | (SeamProviderPropsWithPublishableKey & AllowedSeamClientOptions) | (SeamProviderPropsWithClientSessionToken & AllowedSeamClientOptions);
14
+ interface SeamProviderPropsWithClient {
15
+ client: Seam;
16
+ }
17
+ interface SeamProviderPropsWithPublishableKey {
18
+ publishableKey: string;
15
19
  userIdentifierKey?: string;
16
- endpoint?: string;
17
20
  }
21
+ interface SeamProviderPropsWithClientSessionToken {
22
+ clientSessionToken: string;
23
+ }
24
+ type AllowedSeamClientOptions = Pick<SeamClientOptions, 'endpoint'>;
18
25
  export declare function SeamProvider({ children, ...props }: PropsWithChildren<SeamProviderProps>): JSX.Element;
19
26
  export declare const seamContext: import("react").Context<SeamContext>;
20
27
  export declare function useSeamContext(): SeamContext;
28
+ export {};
@@ -17,8 +17,7 @@ export function SeamProvider({ children, ...props }) {
17
17
  return (_jsx("div", { className: 'seam-components', children: _jsx(QueryClientProvider, { client: queryClientRef.current, children: _jsx(Provider, { value: { ...contextRef.current }, children: children }) }) }));
18
18
  }
19
19
  const createDefaultSeamContextValue = () => {
20
- if (globalThis.seam?.client == null &&
21
- globalThis.seam?.publishableKey == null) {
20
+ if (globalThis.seam == null) {
22
21
  return { client: null };
23
22
  }
24
23
  try {
@@ -30,23 +29,28 @@ const createDefaultSeamContextValue = () => {
30
29
  return { client: null };
31
30
  }
32
31
  };
33
- const createSeamContextValue = ({ client, ...options }) => {
34
- if (client == null && Object.keys(options).length === 0) {
35
- return { client: null };
32
+ const createSeamContextValue = (options) => {
33
+ if (isSeamProviderPropsWithClient(options)) {
34
+ return options;
36
35
  }
37
- if (client != null && Object.values(options).some((v) => v == null)) {
38
- throw new Error('Cannot provide both a Seam client along with other options.');
36
+ if (isSeamProviderPropsWithClientSessionToken(options)) {
37
+ const { clientSessionToken, ...clientOptions } = options;
38
+ return {
39
+ clientSessionToken,
40
+ clientOptions,
41
+ client: null,
42
+ };
39
43
  }
40
- const { publishableKey, userIdentifierKey, ...clientOptions } = options;
41
- if (client != null) {
42
- return { client };
44
+ if (isSeamProviderPropsWithPublishableKey(options)) {
45
+ const { publishableKey, userIdentifierKey, ...clientOptions } = options;
46
+ return {
47
+ publishableKey,
48
+ userIdentifierKey,
49
+ clientOptions,
50
+ client: null,
51
+ };
43
52
  }
44
- return {
45
- client: null,
46
- publishableKey,
47
- userIdentifierKey,
48
- clientOptions,
49
- };
53
+ throw new Error('Invalid SeamProvider options');
50
54
  };
51
55
  const defaultSeamContextValue = createDefaultSeamContextValue();
52
56
  export const seamContext = createContext(defaultSeamContextValue);
@@ -57,4 +61,46 @@ export function useSeamContext() {
57
61
  }
58
62
  return context;
59
63
  }
64
+ const isSeamProviderPropsWithClient = (props) => {
65
+ if (!('client' in props))
66
+ return false;
67
+ const { client } = props;
68
+ if (client == null)
69
+ return false;
70
+ if (Object.values(props).some((v) => v == null)) {
71
+ throw new Error('Cannot provide a Seam client along with other options.');
72
+ }
73
+ return true;
74
+ };
75
+ const isSeamProviderPropsWithPublishableKey = (props) => {
76
+ if (!('publishableKey' in props))
77
+ return false;
78
+ const { publishableKey } = props;
79
+ if (publishableKey == null)
80
+ return false;
81
+ if ('client' in props && props.client != null) {
82
+ throw new Error('Cannot provide a Seam client along with other options.');
83
+ }
84
+ if ('clientSessionToken' in props && props.clientSessionToken != null) {
85
+ throw new Error('Cannot provide both a publishableKey and a clientSessionToken.');
86
+ }
87
+ return true;
88
+ };
89
+ const isSeamProviderPropsWithClientSessionToken = (props) => {
90
+ if (!('clientSessionToken' in props))
91
+ return false;
92
+ const { clientSessionToken } = props;
93
+ if (clientSessionToken == null)
94
+ return false;
95
+ if ('client' in props && props.client != null) {
96
+ throw new Error('Cannot provide a Seam client along with other options.');
97
+ }
98
+ if ('publishableKey' in props && props.publishableKey != null) {
99
+ throw new Error('Cannot provide both a clientSessionToken and a publishableKey .');
100
+ }
101
+ if ('userIdentifierKey' in props && props.userIdentifierKey != null) {
102
+ throw new Error('Cannot use a userIdentifierKey with a clientSessionToken.');
103
+ }
104
+ return true;
105
+ };
60
106
  //# sourceMappingURL=SeamProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SeamProvider.js","sourceRoot":"","sources":["../src/lib/SeamProvider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SeamProvider.js","sourceRoot":"","sources":["../src/lib/SeamProvider.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { AccessCode } from 'seamapi';
2
+ import type { UseSeamQueryResult } from '../../lib/types/use-seam-query-result.js';
3
+ export declare function useAccessCodes(params: {
4
+ device_id: string;
5
+ }): UseSeamQueryResult<'accessCodes', AccessCode[]>;
@@ -0,0 +1,16 @@
1
+ import { useQuery } from '@tanstack/react-query';
2
+ import { useSeamClient } from '../../lib/seam/use-seam-client.js';
3
+ export function useAccessCodes(params) {
4
+ const { client } = useSeamClient();
5
+ const { data, ...rest } = useQuery({
6
+ enabled: client != null,
7
+ queryKey: ['access_codes', 'list', params],
8
+ queryFn: async () => {
9
+ if (client == null)
10
+ return [];
11
+ return await client?.accessCodes.list(params);
12
+ },
13
+ });
14
+ return { ...rest, accessCodes: data };
15
+ }
16
+ //# sourceMappingURL=use-access-codes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-access-codes.js","sourceRoot":"","sources":["../../src/lib/hooks/use-access-codes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAGhD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAG3D,MAAM,UAAU,cAAc,CAAC,MAE9B;IACC,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAAA;IAClC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,CAAiB;QACjD,OAAO,EAAE,MAAM,IAAI,IAAI;QACvB,QAAQ,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC;QAC1C,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,MAAM,IAAI,IAAI;gBAAE,OAAO,EAAE,CAAA;YAC7B,OAAO,MAAM,MAAM,EAAE,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC/C,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAA;AACvC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Device } from 'seamapi';
2
+ import type { UseSeamQueryResult } from '../../lib/types/use-seam-query-result.js';
3
+ export declare function useDevice(params: {
4
+ device_id: string;
5
+ } | string): UseSeamQueryResult<'device', Device<any>>;
@@ -0,0 +1,17 @@
1
+ import { useQuery } from '@tanstack/react-query';
2
+ import { useSeamClient } from '../../lib/seam/use-seam-client.js';
3
+ export function useDevice(params) {
4
+ const objParams = typeof params === 'string' ? { device_id: params } : params;
5
+ const { client } = useSeamClient();
6
+ const { data, ...rest } = useQuery({
7
+ enabled: client != null,
8
+ queryKey: ['devices', 'get', params],
9
+ queryFn: async () => {
10
+ if (client == null)
11
+ return [];
12
+ return await client?.devices.get(objParams);
13
+ },
14
+ });
15
+ return { ...rest, device: data };
16
+ }
17
+ //# sourceMappingURL=use-device.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-device.js","sourceRoot":"","sources":["../../src/lib/hooks/use-device.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAGhD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAG3D,MAAM,UAAU,SAAS,CACvB,MAIU;IAEV,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAA;IAC7E,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAAA;IAClC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,CAAiB;QACjD,OAAO,EAAE,MAAM,IAAI,IAAI;QACvB,QAAQ,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC;QACpC,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,MAAM,IAAI,IAAI;gBAAE,OAAO,EAAE,CAAA;YAC7B,OAAO,MAAM,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAC7C,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;AAClC,CAAC"}
@@ -0,0 +1 @@
1
+ export { useDevices } from '../../lib/seam/devices/use-devices.js';
@@ -0,0 +1,2 @@
1
+ export { useDevices } from '../../lib/seam/devices/use-devices.js';
2
+ //# sourceMappingURL=use-devices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-devices.js","sourceRoot":"","sources":["../../src/lib/hooks/use-devices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAA"}
@@ -0,0 +1 @@
1
+ export { useSeamClient } from '../../lib/seam/use-seam-client.js';
@@ -0,0 +1,2 @@
1
+ export { useSeamClient } from '../../lib/seam/use-seam-client.js';
2
+ //# sourceMappingURL=use-seam-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-seam-client.js","sourceRoot":"","sources":["../../src/lib/hooks/use-seam-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA"}
@@ -3,23 +3,31 @@ import { Seam } from 'seamapi';
3
3
  import { v4 as uuidv4 } from 'uuid';
4
4
  import { useSeamContext } from '../../lib/SeamProvider.js';
5
5
  export function useSeamClient() {
6
- const { client, clientOptions, publishableKey, ...context } = useSeamContext();
7
- const [clientSession, setClientSession] = useClientSession();
8
- const userIdentifierKey = useUserIdentifierKey(context.userIdentifierKey);
6
+ const { client, clientOptions, publishableKey, clientSessionToken, ...context } = useSeamContext();
7
+ const userIdentifierKey = useUserIdentifierKeyOrFingerprint(clientSessionToken != null ? '' : context.userIdentifierKey);
9
8
  const { isLoading, isError, error, data } = useQuery({
10
- queryKey: ['client', { client, clientSession, userIdentifierKey }],
9
+ queryKey: [
10
+ 'client',
11
+ {
12
+ client,
13
+ clientOptions,
14
+ publishableKey,
15
+ userIdentifierKey,
16
+ clientSessionToken,
17
+ },
18
+ ],
11
19
  queryFn: async () => {
12
20
  if (client != null)
13
21
  return client;
14
- if (publishableKey == null) {
15
- throw new Error('Missing publishableKey');
16
- }
17
- if (clientSession != null) {
22
+ if (clientSessionToken != null) {
18
23
  return new Seam({
19
24
  ...clientOptions,
20
- clientSessionToken: clientSession.token,
25
+ clientSessionToken,
21
26
  });
22
27
  }
28
+ if (publishableKey == null) {
29
+ throw new Error('Missing either a client, publishableKey, or clientSessionToken');
30
+ }
23
31
  const res = await Seam.getClientSessionToken({
24
32
  ...clientOptions,
25
33
  publishableKey,
@@ -28,7 +36,6 @@ export function useSeamClient() {
28
36
  if (!res.ok || res.client_session?.token == null) {
29
37
  throw new Error('Failed to get client access token');
30
38
  }
31
- setClientSession(res.client_session);
32
39
  return new Seam({
33
40
  ...clientOptions,
34
41
  clientSessionToken: res.client_session.token,
@@ -37,24 +44,19 @@ export function useSeamClient() {
37
44
  });
38
45
  return { client: data ?? null, isLoading, isError, error };
39
46
  }
40
- function useClientSession() {
41
- const localStorageKey = 'seam_client_session';
42
- const setClientSession = (clientSession) => {
43
- globalThis?.localStorage?.setItem(localStorageKey, JSON.stringify(clientSession));
44
- };
45
- const cachedClientSession = globalThis?.localStorage?.getItem(localStorageKey);
46
- return [
47
- cachedClientSession != null ? JSON.parse(cachedClientSession) : null,
48
- setClientSession,
49
- ];
50
- }
51
- function useUserIdentifierKey(userIdentifierKey) {
47
+ /**
48
+ * You'll almost always want to supply a user identifier key, but if you don't
49
+ * we'll automatically pick a fingerprint for this user. The user interface
50
+ * will show warnings when you use a fingerprint because this client session
51
+ * is bound to this machine, and is effectively ephemeral.
52
+ */
53
+ function useUserIdentifierKeyOrFingerprint(userIdentifierKey) {
52
54
  if (userIdentifierKey != null) {
53
55
  return userIdentifierKey;
54
56
  }
55
- const localStorageKey = 'seam_user_identifier_key';
56
- const key = globalThis?.localStorage?.getItem(localStorageKey) ?? uuidv4();
57
- globalThis?.localStorage?.setItem(localStorageKey, key);
58
- return key;
57
+ const fingerprintValue = globalThis?.localStorage?.getItem('seam_user_fingerprint') ??
58
+ `fingerprint_${uuidv4()}`;
59
+ globalThis?.localStorage?.setItem('seam_user_fingerprint', fingerprintValue);
60
+ return fingerprintValue;
59
61
  }
60
62
  //# sourceMappingURL=use-seam-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-seam-client.js","sourceRoot":"","sources":["../../src/lib/seam/use-seam-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-seam-client.js","sourceRoot":"","sources":["../../src/lib/seam/use-seam-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAC9B,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAA;AAEnC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,MAAM,UAAU,aAAa;IAM3B,MAAM,EACJ,MAAM,EACN,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,GAAG,OAAO,EACX,GAAG,cAAc,EAAE,CAAA;IACpB,MAAM,iBAAiB,GAAG,iCAAiC,CACzD,kBAAkB,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAC5D,CAAA;IAED,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAO;QACzD,QAAQ,EAAE;YACR,QAAQ;YACR;gBACE,MAAM;gBACN,aAAa;gBACb,cAAc;gBACd,iBAAiB;gBACjB,kBAAkB;aACnB;SACF;QACD,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,MAAM,IAAI,IAAI;gBAAE,OAAO,MAAM,CAAA;YAEjC,IAAI,kBAAkB,IAAI,IAAI,EAAE;gBAC9B,OAAO,IAAI,IAAI,CAAC;oBACd,GAAG,aAAa;oBAChB,kBAAkB;iBACnB,CAAC,CAAA;aACH;YAED,IAAI,cAAc,IAAI,IAAI,EAAE;gBAC1B,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAA;aACF;YAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC;gBAC3C,GAAG,aAAa;gBAChB,cAAc;gBACd,iBAAiB;aAClB,CAAC,CAAA;YAEF,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,cAAc,EAAE,KAAK,IAAI,IAAI,EAAE;gBAChD,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;aACrD;YAED,OAAO,IAAI,IAAI,CAAC;gBACd,GAAG,aAAa;gBAChB,kBAAkB,EAAE,GAAG,CAAC,cAAc,CAAC,KAAK;aAC7C,CAAC,CAAA;QACJ,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,EAAE,MAAM,EAAE,IAAI,IAAI,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;AAC5D,CAAC;AAED;;;;;GAKG;AACH,SAAS,iCAAiC,CACxC,iBAAqC;IAErC,IAAI,iBAAiB,IAAI,IAAI,EAAE;QAC7B,OAAO,iBAAiB,CAAA;KACzB;IAED,MAAM,gBAAgB,GACpB,UAAU,EAAE,YAAY,EAAE,OAAO,CAAC,uBAAuB,CAAC;QAC1D,eAAe,MAAM,EAAE,EAAE,CAAA;IAE3B,UAAU,EAAE,YAAY,EAAE,OAAO,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAAA;IAE5E,OAAO,gBAAgB,CAAA;AACzB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { UseQueryResult } from '@tanstack/react-query';
2
+ import type { SeamError } from 'seamapi';
3
+ export type UseSeamQueryResult<Field extends string, ResponsePayload> = Omit<UseQueryResult<ResponsePayload, SeamError>, 'data'> & {
4
+ [key in Field]?: ResponsePayload;
5
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=use-seam-query-result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-seam-query-result.js","sourceRoot":"","sources":["../../src/lib/types/use-seam-query-result.ts"],"names":[],"mappings":""}
@@ -1,6 +1,4 @@
1
- import type { AccessCode } from 'seamapi';
2
- export interface AccessCodeTableProps {
3
- accessCodes: AccessCode[];
1
+ export declare function AccessCodeTable(props: {
2
+ deviceId: string;
4
3
  onClickBack?: () => void;
5
- }
6
- export declare function AccessCodeTable(props: AccessCodeTableProps): JSX.Element;
4
+ }): JSX.Element;
@@ -1,12 +1,18 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { TableBody, TableCell, TableHeader, TableRow, TableTitle, } from '../../../lib/ui/Table/index.js';
3
+ import { useAccessCodes } from '../../../lib/hooks/use-access-codes.js';
3
4
  import { AccessCodeKeyIcon } from '../../../lib/icons/AccessCodeKey.js';
4
5
  import { CodeDetails } from '../../../lib/ui/AccessCodeTable/CodeDetails.js';
5
6
  import { ContentHeader } from '../../../lib/ui/layout/ContentHeader.js';
6
7
  import { Caption } from '../../../lib/ui/typography/Caption.js';
7
8
  import { Title } from '../../../lib/ui/typography/Title.js';
8
9
  export function AccessCodeTable(props) {
9
- const { accessCodes, onClickBack } = props;
10
+ const { accessCodes } = useAccessCodes({
11
+ device_id: props.deviceId,
12
+ });
13
+ const { onClickBack } = props;
14
+ if (!accessCodes)
15
+ return _jsx(_Fragment, { children: null });
10
16
  return (_jsxs("div", { className: 'seam-access-code-table', children: [_jsx(ContentHeader, { onClickBack: onClickBack }), _jsx(TableHeader, { children: _jsxs(TableTitle, { children: [t.accessCodes, " ", _jsxs(Caption, { children: ["(", accessCodes.length, ")"] })] }) }), _jsx(TableBody, { children: accessCodes.map((code) => (_jsxs(TableRow, { children: [_jsx(TableCell, { className: 'seam-icon-cell', children: _jsx("div", { children: _jsx(AccessCodeKeyIcon, {}) }) }), _jsxs(TableCell, { className: 'seam-name-cell', children: [_jsx(Title, { children: code.name }), _jsx(CodeDetails, { accessCode: code })] }), _jsx(TableCell, { className: 'seam-action-cell' })] }, code.access_code_id))) })] }));
11
17
  }
12
18
  const t = {
@@ -1 +1 @@
1
- {"version":3,"file":"AccessCodeTable.js","sourceRoot":"","sources":["../../../src/lib/ui/AccessCodeTable/AccessCodeTable.tsx"],"names":[],"mappings":";AAEA,OAAO,EACL,SAAS,EACT,SAAS,EACT,WAAW,EACX,QAAQ,EACR,UAAU,GACX,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAA;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAA;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAOlD,MAAM,UAAU,eAAe,CAAC,KAA2B;IACzD,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,KAAK,CAAA;IAE1C,OAAO,CACL,eAAK,SAAS,EAAC,wBAAwB,aACrC,KAAC,aAAa,IAAC,WAAW,EAAE,WAAW,GAAI,EAC3C,KAAC,WAAW,cACV,MAAC,UAAU,eACR,CAAC,CAAC,WAAW,OAAE,MAAC,OAAO,oBAAG,WAAW,CAAC,MAAM,SAAY,IAC9C,GACD,EACd,KAAC,SAAS,cACP,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACzB,MAAC,QAAQ,eACP,KAAC,SAAS,IAAC,SAAS,EAAC,gBAAgB,YACnC,wBACE,KAAC,iBAAiB,KAAG,GACjB,GACI,EACZ,MAAC,SAAS,IAAC,SAAS,EAAC,gBAAgB,aACnC,KAAC,KAAK,cAAE,IAAI,CAAC,IAAI,GAAS,EAC1B,KAAC,WAAW,IAAC,UAAU,EAAE,IAAI,GAAI,IACvB,EACZ,KAAC,SAAS,IAAC,SAAS,EAAC,kBAAkB,GAI3B,KAdC,IAAI,CAAC,cAAc,CAevB,CACZ,CAAC,GACQ,IACR,CACP,CAAA;AACH,CAAC;AAED,MAAM,CAAC,GAAG;IACR,WAAW,EAAE,cAAc;CAC5B,CAAA"}
1
+ {"version":3,"file":"AccessCodeTable.js","sourceRoot":"","sources":["../../../src/lib/ui/AccessCodeTable/AccessCodeTable.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,SAAS,EACT,SAAS,EACT,WAAW,EACX,QAAQ,EACR,UAAU,GACX,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAA;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAA;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAElD,MAAM,UAAU,eAAe,CAAC,KAG/B;IACC,MAAM,EAAE,WAAW,EAAE,GAAG,cAAc,CAAC;QACrC,SAAS,EAAE,KAAK,CAAC,QAAQ;KAC1B,CAAC,CAAA;IACF,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAA;IAE7B,IAAI,CAAC,WAAW;QAAE,OAAO,4BAAG,IAAI,GAAI,CAAA;IAEpC,OAAO,CACL,eAAK,SAAS,EAAC,wBAAwB,aACrC,KAAC,aAAa,IAAC,WAAW,EAAE,WAAW,GAAI,EAC3C,KAAC,WAAW,cACV,MAAC,UAAU,eACR,CAAC,CAAC,WAAW,OAAE,MAAC,OAAO,oBAAG,WAAW,CAAC,MAAM,SAAY,IAC9C,GACD,EACd,KAAC,SAAS,cACP,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACzB,MAAC,QAAQ,eACP,KAAC,SAAS,IAAC,SAAS,EAAC,gBAAgB,YACnC,wBACE,KAAC,iBAAiB,KAAG,GACjB,GACI,EACZ,MAAC,SAAS,IAAC,SAAS,EAAC,gBAAgB,aACnC,KAAC,KAAK,cAAE,IAAI,CAAC,IAAI,GAAS,EAC1B,KAAC,WAAW,IAAC,UAAU,EAAE,IAAI,GAAI,IACvB,EACZ,KAAC,SAAS,IAAC,SAAS,EAAC,kBAAkB,GAI3B,KAdC,IAAI,CAAC,cAAc,CAevB,CACZ,CAAC,GACQ,IACR,CACP,CAAA;AACH,CAAC;AAED,MAAM,CAAC,GAAG;IACR,WAAW,EAAE,cAAc;CAC5B,CAAA"}
@@ -12,11 +12,9 @@ export function DeviceDetails(props) {
12
12
  const { device } = props;
13
13
  const lockStatus = device.properties.locked ? t.locked : t.unlocked;
14
14
  const accessCodeLength = device.properties?.schlage_metadata?.access_code_length;
15
- // TODO : Fetch access codes
16
- const accessCodes = [];
17
15
  const [showingAccessCodes, toggleAccessCodes] = useToggle();
18
16
  if (showingAccessCodes) {
19
- return (_jsx(AccessCodeTable, { accessCodes: accessCodes, onClickBack: toggleAccessCodes }));
17
+ return (_jsx(AccessCodeTable, { deviceId: device.device_id, onClickBack: toggleAccessCodes }));
20
18
  }
21
19
  return (_jsxs("div", { className: 'seam-device-details', children: [_jsx(ContentHeader, { title: 'Device' }), _jsxs("div", { className: 'seam-body', children: [_jsx("div", { className: 'seam-summary', children: _jsxs("div", { className: 'seam-content', children: [_jsx("div", { className: 'seam-image', children: _jsx(DeviceImage, { device: device }) }), _jsxs("div", { className: 'seam-info', children: [_jsx("h4", { className: 'seam-device-name', children: device.properties.name }), _jsxs("div", { className: 'seam-properties', children: [_jsx(OnlineStatus, { device: device }), _jsx(BatteryStatus, { device: device }), _jsx(ModelStatus, { device: device })] })] })] }) }), _jsx("div", { className: 'seam-box', children: _jsxs("div", { className: 'seam-content seam-access-codes', onClick: toggleAccessCodes, children: [_jsxs("span", { className: 'seam-value', children: ["49 ", t.accessCodes] }), _jsx(ChevronRightIcon, {})] }) }), _jsxs("div", { className: 'seam-box', children: [_jsxs("div", { className: 'seam-content', children: [_jsx("span", { className: 'seam-label', children: t.lockStatus }), _jsx("span", { className: 'seam-value', children: lockStatus })] }), _jsx(AccessCodeLength, { accessCodeLength: accessCodeLength })] })] })] }));
22
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceDetails.js","sourceRoot":"","sources":["../../../src/lib/ui/DeviceDetails/DeviceDetails.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DeviceDetails.js","sourceRoot":"","sources":["../../../src/lib/ui/DeviceDetails/DeviceDetails.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamapi/react",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "Seam React component library.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -45,6 +45,7 @@
45
45
  ],
46
46
  "scripts": {
47
47
  "start": "concurrently --raw --kill-others npm:examples npm:storybook",
48
+ "dev": "npm run start",
48
49
  "build": "npm run build:js",
49
50
  "prebuild": "del 'index.*' lib",
50
51
  "postbuild": "node ./index.js",
@@ -93,17 +94,17 @@
93
94
  "@tanstack/react-query": "^4.28.0",
94
95
  "classnames": "^2.3.2",
95
96
  "luxon": "^3.3.0",
96
- "seamapi": "^5.19.0-alpha.2",
97
+ "seamapi": "^5.19.0-alpha.3",
97
98
  "uuid": "^9.0.0"
98
99
  },
99
100
  "devDependencies": {
100
101
  "@babel/preset-env": "^7.21.4",
101
102
  "@babel/preset-react": "^7.18.6",
102
103
  "@babel/preset-typescript": "^7.21.4",
103
- "@seamapi/fake-seam-connect": "^0.3.0-alpha.5",
104
104
  "@emotion/styled": "^11.10.6",
105
105
  "@mui/icons-material": "^5.11.16",
106
106
  "@mui/material": "^5.12.2",
107
+ "@seamapi/fake-seam-connect": "^0.3.0-alpha.5",
107
108
  "@storybook/addon-essentials": "^7.0.2",
108
109
  "@storybook/addon-interactions": "^7.0.2",
109
110
  "@storybook/addon-links": "^7.0.2",
@@ -135,6 +136,7 @@
135
136
  "eslint-plugin-unused-imports": "^2.0.0",
136
137
  "fast-glob": "^3.2.12",
137
138
  "http-proxy-middleware": "^2.0.6",
139
+ "isomorphic-fetch": "^3.0.0",
138
140
  "jest": "^29.5.0",
139
141
  "jest-environment-jsdom": "^29.5.0",
140
142
  "prettier": "^2.3.0",
@@ -11,23 +11,37 @@ import type { Seam, SeamClientOptions } from 'seamapi'
11
11
 
12
12
  declare global {
13
13
  // eslint-disable-next-line no-var
14
- var seam: Omit<SeamProviderProps, 'children'> | undefined
14
+ var seam: SeamProviderProps | undefined
15
15
  }
16
16
 
17
17
  export interface SeamContext {
18
18
  client: Seam | null
19
- clientOptions?: SeamClientOptions | undefined
19
+ clientOptions?: AllowedSeamClientOptions | undefined
20
20
  publishableKey?: string | undefined
21
21
  userIdentifierKey?: string | undefined
22
+ clientSessionToken?: string | undefined
22
23
  }
23
24
 
24
- export interface SeamProviderProps {
25
- client?: Seam
26
- publishableKey?: string
25
+ type SeamProviderProps =
26
+ | SeamProviderPropsWithClient
27
+ | (SeamProviderPropsWithPublishableKey & AllowedSeamClientOptions)
28
+ | (SeamProviderPropsWithClientSessionToken & AllowedSeamClientOptions)
29
+
30
+ interface SeamProviderPropsWithClient {
31
+ client: Seam
32
+ }
33
+
34
+ interface SeamProviderPropsWithPublishableKey {
35
+ publishableKey: string
27
36
  userIdentifierKey?: string
28
- endpoint?: string
29
37
  }
30
38
 
39
+ interface SeamProviderPropsWithClientSessionToken {
40
+ clientSessionToken: string
41
+ }
42
+
43
+ type AllowedSeamClientOptions = Pick<SeamClientOptions, 'endpoint'>
44
+
31
45
  export function SeamProvider({
32
46
  children,
33
47
  ...props
@@ -61,10 +75,7 @@ export function SeamProvider({
61
75
  }
62
76
 
63
77
  const createDefaultSeamContextValue = (): SeamContext => {
64
- if (
65
- globalThis.seam?.client == null &&
66
- globalThis.seam?.publishableKey == null
67
- ) {
78
+ if (globalThis.seam == null) {
68
79
  return { client: null }
69
80
  }
70
81
 
@@ -77,32 +88,31 @@ const createDefaultSeamContextValue = (): SeamContext => {
77
88
  }
78
89
  }
79
90
 
80
- const createSeamContextValue = ({
81
- client,
82
- ...options
83
- }: Omit<SeamProviderProps, 'children'>): SeamContext => {
84
- if (client == null && Object.keys(options).length === 0) {
85
- return { client: null }
91
+ const createSeamContextValue = (options: SeamProviderProps): SeamContext => {
92
+ if (isSeamProviderPropsWithClient(options)) {
93
+ return options
86
94
  }
87
95
 
88
- if (client != null && Object.values(options).some((v) => v == null)) {
89
- throw new Error(
90
- 'Cannot provide both a Seam client along with other options.'
91
- )
96
+ if (isSeamProviderPropsWithClientSessionToken(options)) {
97
+ const { clientSessionToken, ...clientOptions } = options
98
+ return {
99
+ clientSessionToken,
100
+ clientOptions,
101
+ client: null,
102
+ }
92
103
  }
93
104
 
94
- const { publishableKey, userIdentifierKey, ...clientOptions } = options
95
-
96
- if (client != null) {
97
- return { client }
105
+ if (isSeamProviderPropsWithPublishableKey(options)) {
106
+ const { publishableKey, userIdentifierKey, ...clientOptions } = options
107
+ return {
108
+ publishableKey,
109
+ userIdentifierKey,
110
+ clientOptions,
111
+ client: null,
112
+ }
98
113
  }
99
114
 
100
- return {
101
- client: null,
102
- publishableKey,
103
- userIdentifierKey,
104
- clientOptions,
105
- }
115
+ throw new Error('Invalid SeamProvider options')
106
116
  }
107
117
 
108
118
  const defaultSeamContextValue = createDefaultSeamContextValue()
@@ -118,3 +128,65 @@ export function useSeamContext(): SeamContext {
118
128
 
119
129
  return context
120
130
  }
131
+
132
+ const isSeamProviderPropsWithClient = (
133
+ props: SeamProviderProps
134
+ ): props is SeamProviderPropsWithClient => {
135
+ if (!('client' in props)) return false
136
+
137
+ const { client } = props
138
+ if (client == null) return false
139
+
140
+ if (Object.values(props).some((v) => v == null)) {
141
+ throw new Error('Cannot provide a Seam client along with other options.')
142
+ }
143
+
144
+ return true
145
+ }
146
+
147
+ const isSeamProviderPropsWithPublishableKey = (
148
+ props: SeamProviderProps
149
+ ): props is SeamProviderPropsWithPublishableKey & AllowedSeamClientOptions => {
150
+ if (!('publishableKey' in props)) return false
151
+
152
+ const { publishableKey } = props
153
+ if (publishableKey == null) return false
154
+
155
+ if ('client' in props && props.client != null) {
156
+ throw new Error('Cannot provide a Seam client along with other options.')
157
+ }
158
+
159
+ if ('clientSessionToken' in props && props.clientSessionToken != null) {
160
+ throw new Error(
161
+ 'Cannot provide both a publishableKey and a clientSessionToken.'
162
+ )
163
+ }
164
+
165
+ return true
166
+ }
167
+
168
+ const isSeamProviderPropsWithClientSessionToken = (
169
+ props: SeamProviderProps
170
+ ): props is SeamProviderPropsWithClientSessionToken &
171
+ AllowedSeamClientOptions => {
172
+ if (!('clientSessionToken' in props)) return false
173
+
174
+ const { clientSessionToken } = props
175
+ if (clientSessionToken == null) return false
176
+
177
+ if ('client' in props && props.client != null) {
178
+ throw new Error('Cannot provide a Seam client along with other options.')
179
+ }
180
+
181
+ if ('publishableKey' in props && props.publishableKey != null) {
182
+ throw new Error(
183
+ 'Cannot provide both a clientSessionToken and a publishableKey .'
184
+ )
185
+ }
186
+
187
+ if ('userIdentifierKey' in props && props.userIdentifierKey != null) {
188
+ throw new Error('Cannot use a userIdentifierKey with a clientSessionToken.')
189
+ }
190
+
191
+ return true
192
+ }
@@ -0,0 +1,21 @@
1
+ import { useQuery } from '@tanstack/react-query'
2
+ import type { AccessCode, SeamError } from 'seamapi'
3
+
4
+ import { useSeamClient } from 'lib/seam/use-seam-client.js'
5
+ import type { UseSeamQueryResult } from 'lib/types/use-seam-query-result.js'
6
+
7
+ export function useAccessCodes(params: {
8
+ device_id: string
9
+ }): UseSeamQueryResult<'accessCodes', AccessCode[]> {
10
+ const { client } = useSeamClient()
11
+ const { data, ...rest } = useQuery<any, SeamError>({
12
+ enabled: client != null,
13
+ queryKey: ['access_codes', 'list', params],
14
+ queryFn: async () => {
15
+ if (client == null) return []
16
+ return await client?.accessCodes.list(params)
17
+ },
18
+ })
19
+
20
+ return { ...rest, accessCodes: data }
21
+ }
@@ -0,0 +1,26 @@
1
+ import { useQuery } from '@tanstack/react-query'
2
+ import type { Device, SeamError } from 'seamapi'
3
+
4
+ import { useSeamClient } from 'lib/seam/use-seam-client.js'
5
+ import type { UseSeamQueryResult } from 'lib/types/use-seam-query-result.js'
6
+
7
+ export function useDevice(
8
+ params:
9
+ | {
10
+ device_id: string
11
+ }
12
+ | string
13
+ ): UseSeamQueryResult<'device', Device<any>> {
14
+ const objParams = typeof params === 'string' ? { device_id: params } : params
15
+ const { client } = useSeamClient()
16
+ const { data, ...rest } = useQuery<any, SeamError>({
17
+ enabled: client != null,
18
+ queryKey: ['devices', 'get', params],
19
+ queryFn: async () => {
20
+ if (client == null) return []
21
+ return await client?.devices.get(objParams)
22
+ },
23
+ })
24
+
25
+ return { ...rest, device: data }
26
+ }
@@ -0,0 +1 @@
1
+ export { useDevices } from 'lib/seam/devices/use-devices.js'
@@ -0,0 +1 @@
1
+ export { useSeamClient } from 'lib/seam/use-seam-client.js'
@@ -1,5 +1,5 @@
1
1
  import { useQuery } from '@tanstack/react-query'
2
- import { type ClientSession, Seam } from 'seamapi'
2
+ import { Seam } from 'seamapi'
3
3
  import { v4 as uuidv4 } from 'uuid'
4
4
 
5
5
  import { useSeamContext } from 'lib/SeamProvider.js'
@@ -10,26 +10,44 @@ export function useSeamClient(): {
10
10
  isError: boolean
11
11
  error: unknown
12
12
  } {
13
- const { client, clientOptions, publishableKey, ...context } = useSeamContext()
14
- const [clientSession, setClientSession] = useClientSession()
15
- const userIdentifierKey = useUserIdentifierKey(context.userIdentifierKey)
13
+ const {
14
+ client,
15
+ clientOptions,
16
+ publishableKey,
17
+ clientSessionToken,
18
+ ...context
19
+ } = useSeamContext()
20
+ const userIdentifierKey = useUserIdentifierKeyOrFingerprint(
21
+ clientSessionToken != null ? '' : context.userIdentifierKey
22
+ )
16
23
 
17
24
  const { isLoading, isError, error, data } = useQuery<Seam>({
18
- queryKey: ['client', { client, clientSession, userIdentifierKey }],
25
+ queryKey: [
26
+ 'client',
27
+ {
28
+ client,
29
+ clientOptions,
30
+ publishableKey,
31
+ userIdentifierKey,
32
+ clientSessionToken,
33
+ },
34
+ ],
19
35
  queryFn: async () => {
20
36
  if (client != null) return client
21
37
 
22
- if (publishableKey == null) {
23
- throw new Error('Missing publishableKey')
24
- }
25
-
26
- if (clientSession != null) {
38
+ if (clientSessionToken != null) {
27
39
  return new Seam({
28
40
  ...clientOptions,
29
- clientSessionToken: clientSession.token,
41
+ clientSessionToken,
30
42
  })
31
43
  }
32
44
 
45
+ if (publishableKey == null) {
46
+ throw new Error(
47
+ 'Missing either a client, publishableKey, or clientSessionToken'
48
+ )
49
+ }
50
+
33
51
  const res = await Seam.getClientSessionToken({
34
52
  ...clientOptions,
35
53
  publishableKey,
@@ -40,8 +58,6 @@ export function useSeamClient(): {
40
58
  throw new Error('Failed to get client access token')
41
59
  }
42
60
 
43
- setClientSession(res.client_session)
44
-
45
61
  return new Seam({
46
62
  ...clientOptions,
47
63
  clientSessionToken: res.client_session.token,
@@ -52,34 +68,24 @@ export function useSeamClient(): {
52
68
  return { client: data ?? null, isLoading, isError, error }
53
69
  }
54
70
 
55
- function useClientSession(): [
56
- clientSession: ClientSession | null,
57
- setClientSession: (clientSession: ClientSession) => void
58
- ] {
59
- const localStorageKey = 'seam_client_session'
60
-
61
- const setClientSession = (clientSession: ClientSession): void => {
62
- globalThis?.localStorage?.setItem(
63
- localStorageKey,
64
- JSON.stringify(clientSession)
65
- )
66
- }
67
-
68
- const cachedClientSession = globalThis?.localStorage?.getItem(localStorageKey)
69
-
70
- return [
71
- cachedClientSession != null ? JSON.parse(cachedClientSession) : null,
72
- setClientSession,
73
- ]
74
- }
75
-
76
- function useUserIdentifierKey(userIdentifierKey: string | undefined): string {
71
+ /**
72
+ * You'll almost always want to supply a user identifier key, but if you don't
73
+ * we'll automatically pick a fingerprint for this user. The user interface
74
+ * will show warnings when you use a fingerprint because this client session
75
+ * is bound to this machine, and is effectively ephemeral.
76
+ */
77
+ function useUserIdentifierKeyOrFingerprint(
78
+ userIdentifierKey: string | undefined
79
+ ): string {
77
80
  if (userIdentifierKey != null) {
78
81
  return userIdentifierKey
79
82
  }
80
83
 
81
- const localStorageKey = 'seam_user_identifier_key'
82
- const key = globalThis?.localStorage?.getItem(localStorageKey) ?? uuidv4()
83
- globalThis?.localStorage?.setItem(localStorageKey, key)
84
- return key
84
+ const fingerprintValue =
85
+ globalThis?.localStorage?.getItem('seam_user_fingerprint') ??
86
+ `fingerprint_${uuidv4()}`
87
+
88
+ globalThis?.localStorage?.setItem('seam_user_fingerprint', fingerprintValue)
89
+
90
+ return fingerprintValue
85
91
  }
@@ -0,0 +1,7 @@
1
+ import type { UseQueryResult } from '@tanstack/react-query'
2
+ import type { SeamError } from 'seamapi'
3
+
4
+ export type UseSeamQueryResult<Field extends string, ResponsePayload> = Omit<
5
+ UseQueryResult<ResponsePayload, SeamError>,
6
+ 'data'
7
+ > & { [key in Field]?: ResponsePayload }
@@ -1,5 +1,3 @@
1
- import type { AccessCode } from 'seamapi'
2
-
3
1
  import {
4
2
  TableBody,
5
3
  TableCell,
@@ -8,19 +6,23 @@ import {
8
6
  TableTitle,
9
7
  } from 'lib/ui/Table/index.js'
10
8
 
9
+ import { useAccessCodes } from 'lib/hooks/use-access-codes.js'
11
10
  import { AccessCodeKeyIcon } from 'lib/icons/AccessCodeKey.js'
12
11
  import { CodeDetails } from 'lib/ui/AccessCodeTable/CodeDetails.js'
13
12
  import { ContentHeader } from 'lib/ui/layout/ContentHeader.js'
14
13
  import { Caption } from 'lib/ui/typography/Caption.js'
15
14
  import { Title } from 'lib/ui/typography/Title.js'
16
15
 
17
- export interface AccessCodeTableProps {
18
- accessCodes: AccessCode[]
16
+ export function AccessCodeTable(props: {
17
+ deviceId: string
19
18
  onClickBack?: () => void
20
- }
19
+ }): JSX.Element {
20
+ const { accessCodes } = useAccessCodes({
21
+ device_id: props.deviceId,
22
+ })
23
+ const { onClickBack } = props
21
24
 
22
- export function AccessCodeTable(props: AccessCodeTableProps): JSX.Element {
23
- const { accessCodes, onClickBack } = props
25
+ if (!accessCodes) return <>{null}</>
24
26
 
25
27
  return (
26
28
  <div className='seam-access-code-table'>
@@ -1,4 +1,4 @@
1
- import { type AccessCode, type LockDevice } from 'seamapi'
1
+ import { type LockDevice } from 'seamapi'
2
2
 
3
3
  import { ChevronRightIcon } from 'lib/icons/ChevronRight.js'
4
4
  import { AccessCodeTable } from 'lib/ui/AccessCodeTable/AccessCodeTable.js'
@@ -21,15 +21,12 @@ export function DeviceDetails(props: DeviceDetailsProps): JSX.Element {
21
21
  const accessCodeLength =
22
22
  device.properties?.schlage_metadata?.access_code_length
23
23
 
24
- // TODO : Fetch access codes
25
- const accessCodes: AccessCode[] = []
26
-
27
24
  const [showingAccessCodes, toggleAccessCodes] = useToggle()
28
25
 
29
26
  if (showingAccessCodes) {
30
27
  return (
31
28
  <AccessCodeTable
32
- accessCodes={accessCodes}
29
+ deviceId={device.device_id}
33
30
  onClickBack={toggleAccessCodes}
34
31
  />
35
32
  )