@seamapi/react 0.16.1 → 0.17.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 (196) hide show
  1. package/README.md +5 -2
  2. package/index.css +294 -69
  3. package/index.css.map +1 -1
  4. package/index.min.css +1 -1
  5. package/index.min.css.map +1 -1
  6. package/lib/NavigationProvider.d.ts +27 -0
  7. package/lib/NavigationProvider.js +36 -0
  8. package/lib/NavigationProvider.js.map +1 -0
  9. package/lib/NavigationView.d.ts +5 -0
  10. package/lib/NavigationView.js +25 -0
  11. package/lib/NavigationView.js.map +1 -0
  12. package/lib/icons/LockLocked.d.ts +2 -0
  13. package/lib/icons/LockLocked.js +5 -0
  14. package/lib/icons/LockLocked.js.map +1 -0
  15. package/lib/icons/LockUnlocked.d.ts +2 -0
  16. package/lib/icons/LockUnlocked.js +5 -0
  17. package/lib/icons/LockUnlocked.js.map +1 -0
  18. package/lib/seam/access-codes/use-access-code.d.ts +8 -0
  19. package/lib/seam/access-codes/use-access-code.js +32 -0
  20. package/lib/seam/access-codes/use-access-code.js.map +1 -0
  21. package/lib/seam/access-codes/use-access-codes.d.ts +9 -0
  22. package/lib/seam/access-codes/use-access-codes.js +18 -0
  23. package/lib/seam/access-codes/use-access-codes.js.map +1 -0
  24. package/lib/seam/devices/types.d.ts +2 -0
  25. package/lib/seam/devices/types.js +2 -0
  26. package/lib/seam/devices/types.js.map +1 -0
  27. package/lib/seam/devices/use-device.d.ts +9 -0
  28. package/lib/seam/devices/use-device.js +56 -0
  29. package/lib/seam/devices/use-device.js.map +1 -0
  30. package/lib/seam/devices/use-devices.d.ts +4 -9
  31. package/lib/seam/devices/use-devices.js +2 -1
  32. package/lib/seam/devices/use-devices.js.map +1 -1
  33. package/lib/seam/index.d.ts +4 -1
  34. package/lib/seam/index.js +4 -1
  35. package/lib/seam/index.js.map +1 -1
  36. package/lib/seam/use-seam-client.js +3 -3
  37. package/lib/seam/use-seam-client.js.map +1 -1
  38. package/lib/seam/use-seam-query-result.js.map +1 -0
  39. package/lib/ui/AccessCodeDetails/AccessCodeDetails.d.ts +4 -0
  40. package/lib/ui/AccessCodeDetails/AccessCodeDetails.js +63 -0
  41. package/lib/ui/AccessCodeDetails/AccessCodeDetails.js.map +1 -0
  42. package/lib/ui/AccessCodeDetails/AccessCodeDevice.d.ts +3 -0
  43. package/lib/ui/AccessCodeDetails/AccessCodeDevice.js +25 -0
  44. package/lib/ui/AccessCodeDetails/AccessCodeDevice.js.map +1 -0
  45. package/lib/ui/AccessCodeTable/AccessCodeTable.d.ts +0 -1
  46. package/lib/ui/AccessCodeTable/AccessCodeTable.js +14 -4
  47. package/lib/ui/AccessCodeTable/AccessCodeTable.js.map +1 -1
  48. package/lib/ui/AccessCodeTable/AccessCodeTableContent.d.ts +0 -1
  49. package/lib/ui/AccessCodeTable/AccessCodeTableContent.js +7 -3
  50. package/lib/ui/AccessCodeTable/AccessCodeTableContent.js.map +1 -1
  51. package/lib/ui/AccessCodeTable/CodeDetails.js +1 -1
  52. package/lib/ui/AccessCodeTable/CodeDetails.js.map +1 -1
  53. package/lib/ui/Button.d.ts +8 -0
  54. package/lib/ui/Button.js +8 -0
  55. package/lib/ui/Button.js.map +1 -0
  56. package/lib/ui/DeviceDetails/DeviceDetails.d.ts +2 -3
  57. package/lib/ui/DeviceDetails/DeviceDetails.js +31 -13
  58. package/lib/ui/DeviceDetails/DeviceDetails.js.map +1 -1
  59. package/lib/ui/DeviceDetails/DeviceModel.d.ts +7 -0
  60. package/lib/ui/DeviceDetails/DeviceModel.js +18 -0
  61. package/lib/ui/DeviceDetails/DeviceModel.js.map +1 -0
  62. package/lib/ui/DeviceTable/DeviceTable.d.ts +7 -0
  63. package/lib/ui/DeviceTable/DeviceTable.js +43 -0
  64. package/lib/ui/DeviceTable/DeviceTable.js.map +1 -0
  65. package/lib/ui/IconButton.js +1 -1
  66. package/lib/ui/IconButton.js.map +1 -1
  67. package/lib/ui/Table/TableRow.d.ts +3 -1
  68. package/lib/ui/Table/TableRow.js +1 -1
  69. package/lib/ui/Table/TableRow.js.map +1 -1
  70. package/lib/ui/TextButton.d.ts +7 -0
  71. package/lib/ui/TextButton.js +5 -0
  72. package/lib/ui/TextButton.js.map +1 -0
  73. package/lib/ui/TextField/SearchTextField.d.ts +1 -1
  74. package/lib/ui/TextField/SearchTextField.js +1 -1
  75. package/lib/ui/TextField/SearchTextField.js.map +1 -1
  76. package/lib/ui/device/BatteryStatus.d.ts +5 -0
  77. package/lib/ui/{DeviceDetails → device}/BatteryStatus.js +5 -6
  78. package/lib/ui/device/BatteryStatus.js.map +1 -0
  79. package/lib/ui/{DeviceDetails → device}/DeviceImage.d.ts +2 -1
  80. package/lib/ui/{DeviceDetails → device}/DeviceImage.js +2 -2
  81. package/lib/ui/device/DeviceImage.js.map +1 -0
  82. package/lib/ui/device/LockStatus.d.ts +5 -0
  83. package/lib/ui/device/LockStatus.js +19 -0
  84. package/lib/ui/device/LockStatus.js.map +1 -0
  85. package/lib/ui/device/OnlineStatus.d.ts +5 -0
  86. package/lib/ui/{DeviceDetails → device}/OnlineStatus.js +4 -5
  87. package/lib/ui/device/OnlineStatus.js.map +1 -0
  88. package/lib/ui/index.d.ts +3 -1
  89. package/lib/ui/index.js +3 -1
  90. package/lib/ui/index.js.map +1 -1
  91. package/lib/ui/layout/ContentHeader.d.ts +1 -2
  92. package/lib/ui/layout/ContentHeader.js +7 -1
  93. package/lib/ui/layout/ContentHeader.js.map +1 -1
  94. package/package.json +4 -3
  95. package/src/icons/lock-locked.svg +8 -0
  96. package/src/icons/lock-unlocked.svg +9 -0
  97. package/src/lib/NavigationProvider.tsx +86 -0
  98. package/src/lib/NavigationView.tsx +32 -0
  99. package/src/lib/icons/LockLocked.tsx +32 -0
  100. package/src/lib/icons/LockUnlocked.tsx +34 -0
  101. package/src/lib/seam/access-codes/use-access-code.ts +45 -0
  102. package/src/lib/seam/access-codes/use-access-codes.ts +39 -0
  103. package/src/lib/seam/devices/types.ts +5 -0
  104. package/src/lib/seam/devices/use-device.ts +79 -0
  105. package/src/lib/seam/devices/use-devices.ts +13 -8
  106. package/src/lib/seam/index.ts +4 -1
  107. package/src/lib/seam/use-seam-client.ts +3 -3
  108. package/src/lib/ui/AccessCodeDetails/AccessCodeDetails.tsx +144 -0
  109. package/src/lib/ui/AccessCodeDetails/AccessCodeDevice.tsx +43 -0
  110. package/src/lib/ui/AccessCodeTable/AccessCodeTable.tsx +20 -16
  111. package/src/lib/ui/AccessCodeTable/AccessCodeTableContent.tsx +7 -11
  112. package/src/lib/ui/AccessCodeTable/CodeDetails.tsx +1 -1
  113. package/src/lib/ui/Button.tsx +26 -0
  114. package/src/lib/ui/DeviceDetails/DeviceDetails.tsx +54 -28
  115. package/src/lib/ui/DeviceDetails/DeviceModel.tsx +34 -0
  116. package/src/lib/ui/DeviceTable/DeviceTable.tsx +94 -0
  117. package/src/lib/ui/IconButton.tsx +1 -1
  118. package/src/lib/ui/Table/TableRow.tsx +8 -2
  119. package/src/lib/ui/TextButton.tsx +15 -0
  120. package/src/lib/ui/TextField/SearchTextField.tsx +1 -1
  121. package/src/lib/ui/{DeviceDetails → device}/BatteryStatus.tsx +12 -14
  122. package/src/lib/ui/device/DeviceImage.tsx +15 -0
  123. package/src/lib/ui/device/LockStatus.tsx +46 -0
  124. package/src/lib/ui/{DeviceDetails → device}/OnlineStatus.tsx +15 -11
  125. package/src/lib/ui/index.ts +3 -1
  126. package/src/lib/ui/layout/ContentHeader.tsx +11 -6
  127. package/src/styles/_access-code-details.scss +121 -0
  128. package/src/styles/_access-code-table.scss +34 -38
  129. package/src/styles/_buttons.scss +125 -8
  130. package/src/styles/_colors.scss +30 -0
  131. package/src/styles/_device-details.scss +21 -10
  132. package/src/styles/_device-table.scss +63 -0
  133. package/src/styles/_icons.scss +9 -0
  134. package/src/styles/_inputs.scss +3 -1
  135. package/src/styles/_layout.scss +5 -1
  136. package/src/styles/_main.scss +8 -14
  137. package/src/styles/_tables.scss +6 -0
  138. package/src/styles/_typography.scss +18 -2
  139. package/lib/hooks/use-access-codes.d.ts +0 -5
  140. package/lib/hooks/use-access-codes.js +0 -16
  141. package/lib/hooks/use-access-codes.js.map +0 -1
  142. package/lib/hooks/use-device.d.ts +0 -5
  143. package/lib/hooks/use-device.js +0 -17
  144. package/lib/hooks/use-device.js.map +0 -1
  145. package/lib/hooks/use-devices.d.ts +0 -1
  146. package/lib/hooks/use-devices.js +0 -2
  147. package/lib/hooks/use-devices.js.map +0 -1
  148. package/lib/hooks/use-seam-client.d.ts +0 -1
  149. package/lib/hooks/use-seam-client.js +0 -2
  150. package/lib/hooks/use-seam-client.js.map +0 -1
  151. package/lib/seam/devices/index.d.ts +0 -1
  152. package/lib/seam/devices/index.js +0 -2
  153. package/lib/seam/devices/index.js.map +0 -1
  154. package/lib/types/use-seam-query-result.js.map +0 -1
  155. package/lib/ui/AccessCodeTable/index.d.ts +0 -2
  156. package/lib/ui/AccessCodeTable/index.js +0 -3
  157. package/lib/ui/AccessCodeTable/index.js.map +0 -1
  158. package/lib/ui/DeviceDetails/BatteryStatus.d.ts +0 -4
  159. package/lib/ui/DeviceDetails/BatteryStatus.js.map +0 -1
  160. package/lib/ui/DeviceDetails/DeviceImage.js.map +0 -1
  161. package/lib/ui/DeviceDetails/ModelStatus.d.ts +0 -4
  162. package/lib/ui/DeviceDetails/ModelStatus.js +0 -13
  163. package/lib/ui/DeviceDetails/ModelStatus.js.map +0 -1
  164. package/lib/ui/DeviceDetails/OnlineStatus.d.ts +0 -4
  165. package/lib/ui/DeviceDetails/OnlineStatus.js.map +0 -1
  166. package/lib/ui/DeviceDetails/index.d.ts +0 -5
  167. package/lib/ui/DeviceDetails/index.js +0 -6
  168. package/lib/ui/DeviceDetails/index.js.map +0 -1
  169. package/lib/ui/DeviceManager/DeviceManager.d.ts +0 -6
  170. package/lib/ui/DeviceManager/DeviceManager.js +0 -24
  171. package/lib/ui/DeviceManager/DeviceManager.js.map +0 -1
  172. package/lib/ui/DeviceManager/index.d.ts +0 -1
  173. package/lib/ui/DeviceManager/index.js +0 -2
  174. package/lib/ui/DeviceManager/index.js.map +0 -1
  175. package/lib/ui/Table/index.d.ts +0 -5
  176. package/lib/ui/Table/index.js +0 -6
  177. package/lib/ui/Table/index.js.map +0 -1
  178. package/lib/ui/TextField/index.d.ts +0 -2
  179. package/lib/ui/TextField/index.js +0 -3
  180. package/lib/ui/TextField/index.js.map +0 -1
  181. package/src/lib/hooks/use-access-codes.ts +0 -21
  182. package/src/lib/hooks/use-device.ts +0 -26
  183. package/src/lib/hooks/use-devices.ts +0 -1
  184. package/src/lib/hooks/use-seam-client.ts +0 -1
  185. package/src/lib/seam/devices/index.ts +0 -1
  186. package/src/lib/ui/AccessCodeTable/index.ts +0 -2
  187. package/src/lib/ui/DeviceDetails/DeviceImage.tsx +0 -12
  188. package/src/lib/ui/DeviceDetails/ModelStatus.tsx +0 -25
  189. package/src/lib/ui/DeviceDetails/index.ts +0 -5
  190. package/src/lib/ui/DeviceManager/DeviceManager.tsx +0 -52
  191. package/src/lib/ui/DeviceManager/index.ts +0 -1
  192. package/src/lib/ui/Table/index.ts +0 -5
  193. package/src/lib/ui/TextField/index.ts +0 -2
  194. /package/lib/{types → seam}/use-seam-query-result.d.ts +0 -0
  195. /package/lib/{types → seam}/use-seam-query-result.js +0 -0
  196. /package/src/lib/{types → seam}/use-seam-query-result.ts +0 -0
@@ -1,22 +1,37 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import {} from 'seamapi';
3
2
  import { ChevronRightIcon } from '../../../lib/icons/ChevronRight.js';
4
- import { AccessCodeTable } from '../../../lib/ui/AccessCodeTable/AccessCodeTable.js';
5
- import { BatteryStatus } from '../../../lib/ui/DeviceDetails/BatteryStatus.js';
6
- import { DeviceImage } from '../../../lib/ui/DeviceDetails/DeviceImage.js';
7
- import { ModelStatus } from '../../../lib/ui/DeviceDetails/ModelStatus.js';
8
- import { OnlineStatus } from '../../../lib/ui/DeviceDetails/OnlineStatus.js';
3
+ import { useNavigation } from '../../../lib/NavigationProvider.js';
4
+ import { useAccessCodes } from '../../../lib/seam/access-codes/use-access-codes.js';
5
+ import { isLockDevice } from '../../../lib/seam/devices/types.js';
6
+ import { useFakeDevice } from '../../../lib/seam/devices/use-device.js';
7
+ import { Button } from '../../../lib/ui/Button.js';
8
+ import { BatteryStatus } from '../../../lib/ui/device/BatteryStatus.js';
9
+ import { DeviceImage } from '../../../lib/ui/device/DeviceImage.js';
10
+ import { OnlineStatus } from '../../../lib/ui/device/OnlineStatus.js';
11
+ import { DeviceModel } from '../../../lib/ui/DeviceDetails/DeviceModel.js';
9
12
  import { ContentHeader } from '../../../lib/ui/layout/ContentHeader.js';
10
- import useToggle from '../../../lib/use-toggle.js';
11
13
  export function DeviceDetails(props) {
12
- const { device } = props;
14
+ const { deviceId } = props;
15
+ const { isLoading: isLoadingDevice, device } = useFakeDevice({
16
+ device_id: deviceId,
17
+ });
18
+ const { isLoading: isLoadingAccessCodes, accessCodes } = useAccessCodes({
19
+ device_id: deviceId,
20
+ });
21
+ const isLoading = isLoadingDevice || isLoadingAccessCodes;
22
+ const { show } = useNavigation();
23
+ if (isLoading || !device) {
24
+ return null;
25
+ }
26
+ if (!isLockDevice(device)) {
27
+ return null;
28
+ }
13
29
  const lockStatus = device.properties.locked ? t.locked : t.unlocked;
30
+ const accessCodeCount = accessCodes?.length;
14
31
  const accessCodeLength = device.properties?.schlage_metadata?.access_code_length;
15
- const [showingAccessCodes, toggleAccessCodes] = useToggle();
16
- if (showingAccessCodes) {
17
- return (_jsx(AccessCodeTable, { deviceId: device.device_id, onClickBack: toggleAccessCodes }));
18
- }
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("span", { className: 'seam-label', children: t.device }), _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 })] })] })] }));
32
+ 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("span", { className: 'seam-label', children: t.device }), _jsx("h4", { className: 'seam-device-name', children: device.properties.name }), _jsxs("div", { className: 'seam-properties', children: [_jsxs("span", { className: 'seam-label', children: [t.status, ":"] }), ' ', _jsx(OnlineStatus, { device: device }), _jsxs("span", { className: 'seam-label', children: [t.power, ":"] }), ' ', _jsx(BatteryStatus, { device: device }), _jsx(DeviceModel, { device: device })] })] })] }) }), _jsx("div", { className: 'seam-box', children: _jsxs("div", { className: 'seam-content seam-access-codes', onClick: () => {
33
+ show({ name: 'access_code_table', deviceId: device.device_id });
34
+ }, children: [_jsxs("span", { className: 'seam-value', children: [accessCodeCount, " ", t.accessCodes] }), _jsx(ChevronRightIcon, {})] }) }), _jsxs("div", { className: 'seam-box', children: [_jsxs("div", { className: 'seam-content seam-lock-status', children: [_jsxs("div", { children: [_jsx("span", { className: 'seam-label', children: t.lockStatus }), _jsx("span", { className: 'seam-value', children: lockStatus })] }), _jsx("div", { className: 'seam-right', children: _jsx(Button, { size: 'small', children: t.unlock }) })] }), _jsx(AccessCodeLength, { accessCodeLength: accessCodeLength })] })] })] }));
20
35
  }
21
36
  function AccessCodeLength(props) {
22
37
  const { accessCodeLength } = props;
@@ -27,11 +42,14 @@ function AccessCodeLength(props) {
27
42
  }
28
43
  const t = {
29
44
  device: 'Device',
45
+ unlock: 'Unlock',
30
46
  locked: 'Locked',
31
47
  unlocked: 'Unlocked',
32
48
  accessCodes: 'access codes',
33
49
  codeLength: 'Code length',
34
50
  digits: 'digits',
35
51
  lockStatus: 'Lock status',
52
+ status: 'Status',
53
+ power: 'Power',
36
54
  };
37
55
  //# sourceMappingURL=DeviceDetails.js.map
@@ -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":";AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAA;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAA;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAM9D,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IAE1B,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC;QAC3D,SAAS,EAAE,QAAQ;KACpB,CAAC,CAAA;IAEF,MAAM,EAAE,SAAS,EAAE,oBAAoB,EAAE,WAAW,EAAE,GAAG,cAAc,CAAC;QACtE,SAAS,EAAE,QAAQ;KACpB,CAAC,CAAA;IAEF,MAAM,SAAS,GAAG,eAAe,IAAI,oBAAoB,CAAA;IAEzD,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAA;IAEhC,IAAI,SAAS,IAAI,CAAC,MAAM,EAAE;QACxB,OAAO,IAAI,CAAA;KACZ;IAED,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE;QACzB,OAAO,IAAI,CAAA;KACZ;IAED,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;IAEnE,MAAM,eAAe,GAAG,WAAW,EAAE,MAAM,CAAA;IAE3C,MAAM,gBAAgB,GACpB,MAAM,CAAC,UAAU,EAAE,gBAAgB,EAAE,kBAAkB,CAAA;IAEzD,OAAO,CACL,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,aAAa,IAAC,KAAK,EAAC,QAAQ,GAAG,EAChC,eAAK,SAAS,EAAC,WAAW,aACxB,cAAK,SAAS,EAAC,cAAc,YAC3B,eAAK,SAAS,EAAC,cAAc,aAC3B,cAAK,SAAS,EAAC,YAAY,YACzB,KAAC,WAAW,IAAC,MAAM,EAAE,MAAM,GAAI,GAC3B,EACN,eAAK,SAAS,EAAC,WAAW,aACxB,eAAM,SAAS,EAAC,YAAY,YAAE,CAAC,CAAC,MAAM,GAAQ,EAC9C,aAAI,SAAS,EAAC,kBAAkB,YAAE,MAAM,CAAC,UAAU,CAAC,IAAI,GAAM,EAC9D,eAAK,SAAS,EAAC,iBAAiB,aAC9B,gBAAM,SAAS,EAAC,YAAY,aAAE,CAAC,CAAC,MAAM,SAAS,EAAC,GAAG,EACnD,KAAC,YAAY,IAAC,MAAM,EAAE,MAAM,GAAI,EAChC,gBAAM,SAAS,EAAC,YAAY,aAAE,CAAC,CAAC,KAAK,SAAS,EAAC,GAAG,EAClD,KAAC,aAAa,IAAC,MAAM,EAAE,MAAM,GAAI,EACjC,KAAC,WAAW,IAAC,MAAM,EAAE,MAAM,GAAI,IAC3B,IACF,IACF,GACF,EACN,cAAK,SAAS,EAAC,UAAU,YACvB,eACE,SAAS,EAAC,gCAAgC,EAC1C,OAAO,EAAE,GAAG,EAAE;gCACZ,IAAI,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;4BACjE,CAAC,aAED,gBAAM,SAAS,EAAC,YAAY,aACzB,eAAe,OAAG,CAAC,CAAC,WAAW,IAC3B,EACP,KAAC,gBAAgB,KAAG,IAChB,GACF,EAEN,eAAK,SAAS,EAAC,UAAU,aACvB,eAAK,SAAS,EAAC,+BAA+B,aAC5C,0BACE,eAAM,SAAS,EAAC,YAAY,YAAE,CAAC,CAAC,UAAU,GAAQ,EAClD,eAAM,SAAS,EAAC,YAAY,YAAE,UAAU,GAAQ,IAC5C,EACN,cAAK,SAAS,EAAC,YAAY,YACzB,KAAC,MAAM,IAAC,IAAI,EAAC,OAAO,YAAE,CAAC,CAAC,MAAM,GAAU,GACpC,IACF,EACN,KAAC,gBAAgB,IAAC,gBAAgB,EAAE,gBAAgB,GAAI,IACpD,IACF,IACF,CACP,CAAA;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,KAEzB;IACC,MAAM,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAA;IAClC,IAAI,gBAAgB,IAAI,IAAI,EAAE;QAC5B,OAAO,IAAI,CAAA;KACZ;IAED,OAAO,CACL,eAAK,SAAS,EAAC,sCAAsC,aACnD,eAAM,SAAS,EAAC,YAAY,YAAE,CAAC,CAAC,UAAU,GAAQ,EAClD,gBAAM,SAAS,EAAC,YAAY,aACzB,gBAAgB,OAAG,CAAC,CAAC,MAAM,IACvB,IACH,CACP,CAAA;AACH,CAAC;AAED,MAAM,CAAC,GAAG;IACR,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;IACpB,WAAW,EAAE,cAAc;IAC3B,UAAU,EAAE,aAAa;IACzB,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE,aAAa;IACzB,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;CACf,CAAA"}
@@ -0,0 +1,7 @@
1
+ import type { LockDevice } from 'seamapi';
2
+ interface DeviceModelProps {
3
+ device: LockDevice;
4
+ }
5
+ export declare function DeviceModel({ device }: DeviceModelProps): JSX.Element | null;
6
+ export declare const getDeviceModel: ({ properties, }: LockDevice) => string | undefined;
7
+ export {};
@@ -0,0 +1,18 @@
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ export function DeviceModel({ device }) {
3
+ const model = getDeviceModel(device);
4
+ if (!model) {
5
+ return null;
6
+ }
7
+ return (_jsxs(_Fragment, { children: [_jsxs("span", { className: 'seam-label', children: [t.model, ":"] }), ' ', _jsx("div", { className: 'seam-device-model', children: model })] }));
8
+ }
9
+ export const getDeviceModel = ({ properties, }) => {
10
+ return (properties?.august_metadata?.model ??
11
+ properties?.schlage_metadata?.model ??
12
+ t.fallbackModel);
13
+ };
14
+ const t = {
15
+ model: 'Model',
16
+ fallbackModel: 'Unknown Lock',
17
+ };
18
+ //# sourceMappingURL=DeviceModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeviceModel.js","sourceRoot":"","sources":["../../../src/lib/ui/DeviceDetails/DeviceModel.tsx"],"names":[],"mappings":";AAMA,MAAM,UAAU,WAAW,CAAC,EAAE,MAAM,EAAoB;IACtD,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,CAAA;IACpC,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,IAAI,CAAA;KACZ;IAED,OAAO,CACL,8BACE,gBAAM,SAAS,EAAC,YAAY,aAAE,CAAC,CAAC,KAAK,SAAS,EAAC,GAAG,EAClD,cAAK,SAAS,EAAC,mBAAmB,YAAE,KAAK,GAAO,IAC/C,CACJ,CAAA;AACH,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAC7B,UAAU,GACC,EAAsB,EAAE;IACnC,OAAO,CACL,UAAU,EAAE,eAAe,EAAE,KAAK;QAClC,UAAU,EAAE,gBAAgB,EAAE,KAAK;QACnC,CAAC,CAAC,aAAa,CAChB,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,GAAG;IACR,KAAK,EAAE,OAAO;IACd,aAAa,EAAE,cAAc;CAC9B,CAAA"}
@@ -0,0 +1,7 @@
1
+ import { type UseDevicesParams } from '../../../lib/seam/devices/use-devices.js';
2
+ export type DeviceTableProps = Props & UseDevicesParams;
3
+ interface Props {
4
+ onBack?: () => void;
5
+ }
6
+ export declare function DeviceTable({ onBack, ...props }: DeviceTableProps): import("react/jsx-runtime").JSX.Element | null;
7
+ export {};
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useNavigation } from '../../../lib/NavigationProvider.js';
3
+ import { isLockDevice } from '../../../lib/seam/devices/types.js';
4
+ import { useDevices, } from '../../../lib/seam/devices/use-devices.js';
5
+ import { BatteryStatus } from '../../../lib/ui/device/BatteryStatus.js';
6
+ import { DeviceImage } from '../../../lib/ui/device/DeviceImage.js';
7
+ import { LockStatus } from '../../../lib/ui/device/LockStatus.js';
8
+ import { OnlineStatus } from '../../../lib/ui/device/OnlineStatus.js';
9
+ import { getDeviceModel } from '../../../lib/ui/DeviceDetails/DeviceModel.js';
10
+ import { ContentHeader } from '../../../lib/ui/layout/ContentHeader.js';
11
+ import { TableBody } from '../../../lib/ui/Table/TableBody.js';
12
+ import { TableCell } from '../../../lib/ui/Table/TableCell.js';
13
+ import { TableHeader } from '../../../lib/ui/Table/TableHeader.js';
14
+ import { TableRow } from '../../../lib/ui/Table/TableRow.js';
15
+ import { TableTitle } from '../../../lib/ui/Table/TableTitle.js';
16
+ import { Caption } from '../../../lib/ui/typography/Caption.js';
17
+ import { Title } from '../../../lib/ui/typography/Title.js';
18
+ export function DeviceTable({ onBack, ...props }) {
19
+ const { devices, isLoading, isError, error } = useDevices(props);
20
+ const { show } = useNavigation();
21
+ if (isLoading)
22
+ return _jsx("p", { children: "..." });
23
+ if (isError)
24
+ return _jsx("p", { children: error?.message });
25
+ if (devices == null)
26
+ return null;
27
+ const deviceCount = devices.length;
28
+ return (_jsxs("div", { className: 'seam-device-table', children: [_jsx(ContentHeader, {}), _jsx(TableHeader, { children: _jsxs(TableTitle, { children: [t.devices, " ", _jsxs(Caption, { children: ["(", deviceCount, ")"] })] }) }), _jsx(TableBody, { children: devices.map((device) => (_jsx(DeviceRow, { device: device, onClick: () => {
29
+ show({ name: 'device_detail', deviceId: device.device_id });
30
+ } }, device.device_id))) })] }));
31
+ }
32
+ function DeviceRow(props) {
33
+ const { device, onClick } = props;
34
+ if (!isLockDevice(device))
35
+ return null;
36
+ const deviceModel = getDeviceModel(device) ?? t.unknownLock;
37
+ return (_jsxs(TableRow, { onClick: onClick, children: [_jsx(TableCell, { className: 'seam-image-cell', children: _jsx(DeviceImage, { device: device }) }), _jsxs(TableCell, { className: 'seam-body-cell', children: [_jsx(Title, { children: device.properties.name }), _jsxs("div", { className: 'seam-bottom', children: [_jsx("span", { className: 'seam-device-model', children: deviceModel }), _jsxs("div", { className: 'seam-device-statuses', children: [_jsx(OnlineStatus, { device: device }), _jsx(BatteryStatus, { device: device }), _jsx(LockStatus, { device: device })] })] })] })] }, device.device_id));
38
+ }
39
+ const t = {
40
+ devices: 'Devices',
41
+ unknownLock: 'Unknown Lock',
42
+ };
43
+ //# sourceMappingURL=DeviceTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeviceTable.js","sourceRoot":"","sources":["../../../src/lib/ui/DeviceTable/DeviceTable.tsx"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  export function IconButton(props) {
3
- return _jsx("button", { ...props, className: 'seam-button seam-icon-button' });
3
+ return _jsx("button", { ...props, className: 'seam-icon-btn' });
4
4
  }
5
5
  //# sourceMappingURL=IconButton.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"IconButton.js","sourceRoot":"","sources":["../../src/lib/ui/IconButton.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,UAAU,CAAC,KAAkB;IAC3C,OAAO,oBAAY,KAAK,EAAE,SAAS,EAAC,8BAA8B,GAAG,CAAA;AACvE,CAAC"}
1
+ {"version":3,"file":"IconButton.js","sourceRoot":"","sources":["../../src/lib/ui/IconButton.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,UAAU,CAAC,KAAkB;IAC3C,OAAO,oBAAY,KAAK,EAAE,SAAS,EAAC,eAAe,GAAG,CAAA;AACxD,CAAC"}
@@ -1,2 +1,4 @@
1
1
  import type { DivProps } from '../../../lib/ui/types.js';
2
- export declare function TableRow(props: DivProps): JSX.Element;
2
+ export declare function TableRow(props: DivProps & {
3
+ onClick?: () => void;
4
+ }): JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  export function TableRow(props) {
3
- return _jsx("div", { className: 'seam-table-row', children: props.children });
3
+ return (_jsx("div", { className: 'seam-table-row', ...props, children: props.children }));
4
4
  }
5
5
  //# sourceMappingURL=TableRow.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TableRow.js","sourceRoot":"","sources":["../../../src/lib/ui/Table/TableRow.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,QAAQ,CAAC,KAAe;IACtC,OAAO,cAAK,SAAS,EAAC,gBAAgB,YAAE,KAAK,CAAC,QAAQ,GAAO,CAAA;AAC/D,CAAC"}
1
+ {"version":3,"file":"TableRow.js","sourceRoot":"","sources":["../../../src/lib/ui/Table/TableRow.tsx"],"names":[],"mappings":";AAEA,MAAM,UAAU,QAAQ,CACtB,KAA0C;IAE1C,OAAO,CACL,cAAK,SAAS,EAAC,gBAAgB,KAAK,KAAK,YACtC,KAAK,CAAC,QAAQ,GACX,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ButtonProps } from '../../lib/ui/types.js';
2
+ interface TextButtonProps extends ButtonProps {
3
+ color?: 'primary' | 'inherit';
4
+ disabled?: boolean;
5
+ }
6
+ export declare function TextButton({ color, ...buttonProps }: TextButtonProps): JSX.Element;
7
+ export {};
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ export function TextButton({ color = 'primary', ...buttonProps }) {
3
+ return (_jsx("button", { className: `seam-text-btn seam-color-${color}`, ...buttonProps }));
4
+ }
5
+ //# sourceMappingURL=TextButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextButton.js","sourceRoot":"","sources":["../../src/lib/ui/TextButton.tsx"],"names":[],"mappings":";AAOA,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,GAAG,SAAS,EACjB,GAAG,WAAW,EACE;IAChB,OAAO,CACL,iBAAQ,SAAS,EAAE,4BAA4B,KAAK,EAAE,KAAM,WAAW,GAAI,CAC5E,CAAA;AACH,CAAC"}
@@ -1,2 +1,2 @@
1
- import { type TextFieldProps } from '../../../lib/ui/TextField/index.js';
1
+ import { type TextFieldProps } from '../../../lib/ui/TextField/TextField.js';
2
2
  export declare function SearchTextField({ className, ...otherProps }: TextFieldProps): JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import classNames from 'classnames';
3
- import { TextField } from '../../../lib/ui/TextField/index.js';
3
+ import { TextField } from '../../../lib/ui/TextField/TextField.js';
4
4
  export function SearchTextField({ className, ...otherProps }) {
5
5
  return (_jsx(TextField, { ...otherProps, className: classNames(className, 'seam-search-text-field') }));
6
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SearchTextField.js","sourceRoot":"","sources":["../../../src/lib/ui/TextField/SearchTextField.tsx"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAA;AAEnC,OAAO,EAAE,SAAS,EAAuB,MAAM,2BAA2B,CAAA;AAE1E,MAAM,UAAU,eAAe,CAAC,EAC9B,SAAS,EACT,GAAG,UAAU,EACE;IACf,OAAO,CACL,KAAC,SAAS,OACJ,UAAU,EACd,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,wBAAwB,CAAC,GAC1D,CACH,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"SearchTextField.js","sourceRoot":"","sources":["../../../src/lib/ui/TextField/SearchTextField.tsx"],"names":[],"mappings":";AAAA,OAAO,UAAU,MAAM,YAAY,CAAA;AAEnC,OAAO,EAAE,SAAS,EAAuB,MAAM,+BAA+B,CAAA;AAE9E,MAAM,UAAU,eAAe,CAAC,EAC9B,SAAS,EACT,GAAG,UAAU,EACE;IACf,OAAO,CACL,KAAC,SAAS,OACJ,UAAU,EACd,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,wBAAwB,CAAC,GAC1D,CACH,CAAA;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { LockDevice } from 'seamapi';
2
+ export interface BatteryStatusProps {
3
+ device: LockDevice;
4
+ }
5
+ export declare function BatteryStatus(props: BatteryStatusProps): import("react/jsx-runtime").JSX.Element;
@@ -1,17 +1,17 @@
1
- import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { BatteryLevelCriticalIcon } from '../../../lib/icons/BatteryLevelCritical.js';
3
3
  import { BatteryLevelFullIcon } from '../../../lib/icons/BatteryLevelFull.js';
4
4
  import { BatteryLevelHighIcon } from '../../../lib/icons/BatteryLevelHigh.js';
5
5
  import { BatteryLevelLowIcon } from '../../../lib/icons/BatteryLevelLow.js';
6
6
  export function BatteryStatus(props) {
7
7
  const { device: { properties: { battery_level: batteryLevel }, }, } = props;
8
+ return (_jsx("div", { className: 'seam-battery-status', children: _jsx(Content, { batteryLevel: batteryLevel }) }));
9
+ }
10
+ function Content(props) {
11
+ const { batteryLevel } = props;
8
12
  if (batteryLevel == null) {
9
13
  return null;
10
14
  }
11
- return (_jsxs(_Fragment, { children: [_jsxs("span", { className: 'seam-label', children: [t.power, ":"] }), ' ', _jsx("div", { className: 'seam-battery-status', children: _jsx(Status, { batteryLevel: batteryLevel }) })] }));
12
- }
13
- function Status(props) {
14
- const { batteryLevel } = props;
15
15
  if (batteryLevel > batteryThreshold.full) {
16
16
  return (_jsxs(_Fragment, { children: [_jsx(BatteryLevelFullIcon, {}), _jsx("span", { className: 'seam-status-text', children: t.full })] }));
17
17
  }
@@ -29,7 +29,6 @@ const batteryThreshold = {
29
29
  low: 0.3,
30
30
  };
31
31
  const t = {
32
- power: 'Power',
33
32
  full: 'Good',
34
33
  high: 'Good',
35
34
  low: 'Low',
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BatteryStatus.js","sourceRoot":"","sources":["../../../src/lib/ui/device/BatteryStatus.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAA;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAMlE,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,EACJ,MAAM,EAAE,EACN,UAAU,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,GAC5C,GACF,GAAG,KAAK,CAAA;IAET,OAAO,CACL,cAAK,SAAS,EAAC,qBAAqB,YAClC,KAAC,OAAO,IAAC,YAAY,EAAE,YAAY,GAAI,GACnC,CACP,CAAA;AACH,CAAC;AAED,SAAS,OAAO,CAAC,KAAgC;IAC/C,MAAM,EAAE,YAAY,EAAE,GAAG,KAAK,CAAA;IAE9B,IAAI,YAAY,IAAI,IAAI,EAAE;QACxB,OAAO,IAAI,CAAA;KACZ;IAED,IAAI,YAAY,GAAG,gBAAgB,CAAC,IAAI,EAAE;QACxC,OAAO,CACL,8BACE,KAAC,oBAAoB,KAAG,EACxB,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,IAAI,GAAQ,IACjD,CACJ,CAAA;KACF;IAED,IAAI,YAAY,GAAG,gBAAgB,CAAC,IAAI,EAAE;QACxC,OAAO,CACL,8BACE,KAAC,oBAAoB,KAAG,EACxB,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,IAAI,GAAQ,IACjD,CACJ,CAAA;KACF;IAED,IAAI,YAAY,GAAG,gBAAgB,CAAC,GAAG,EAAE;QACvC,OAAO,CACL,8BACE,KAAC,mBAAmB,KAAG,EACvB,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,GAAG,GAAQ,IAChD,CACJ,CAAA;KACF;IAED,OAAO,CACL,8BACE,KAAC,wBAAwB,KAAG,EAC5B,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,QAAQ,GAAQ,IACrD,CACJ,CAAA;AACH,CAAC;AAED,MAAM,gBAAgB,GAAG;IACvB,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,GAAG;IACT,GAAG,EAAE,GAAG;CACT,CAAA;AAED,MAAM,CAAC,GAAG;IACR,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,KAAK;IACV,QAAQ,EAAE,MAAM;CACjB,CAAA"}
@@ -1,4 +1,5 @@
1
+ import type { HTMLAttributes } from 'react';
1
2
  import type { LockDevice } from 'seamapi';
2
3
  export declare function DeviceImage(props: {
3
4
  device: LockDevice;
4
- }): JSX.Element;
5
+ } & HTMLAttributes<HTMLImageElement>): JSX.Element;
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  export function DeviceImage(props) {
3
- const { device } = props;
3
+ const { device, ...imageProps } = props;
4
4
  const url = device.properties.image_url ?? fallbackImageUrl;
5
- return _jsx("img", { src: url, alt: device.properties.name });
5
+ return _jsx("img", { src: url, alt: device.properties.name, ...imageProps });
6
6
  }
7
7
  const fallbackImageUrl = 'https://connect.getseam.com/assets/images/devices/unknown-lock.png';
8
8
  //# sourceMappingURL=DeviceImage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeviceImage.js","sourceRoot":"","sources":["../../../src/lib/ui/device/DeviceImage.tsx"],"names":[],"mappings":";AAGA,MAAM,UAAU,WAAW,CACzB,KAAgE;IAEhE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,GAAG,KAAK,CAAA;IAEvC,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,IAAI,gBAAgB,CAAA;IAE3D,OAAO,cAAK,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,KAAM,UAAU,GAAI,CAAA;AACvE,CAAC;AAED,MAAM,gBAAgB,GACpB,oEAAoE,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { LockDevice } from 'seamapi';
2
+ export interface LockStatusProps {
3
+ device: LockDevice;
4
+ }
5
+ export declare function LockStatus(props: LockStatusProps): JSX.Element;
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { LockLockedIcon } from '../../../lib/icons/LockLocked.js';
3
+ import { LockUnlockedIcon } from '../../../lib/icons/LockUnlocked.js';
4
+ export function LockStatus(props) {
5
+ const { device: { properties: { locked }, }, } = props;
6
+ return (_jsx("div", { className: 'seam-lock-status', children: _jsx(Content, { isLocked: locked }) }));
7
+ }
8
+ function Content(props) {
9
+ const { isLocked } = props;
10
+ if (isLocked) {
11
+ return (_jsxs(_Fragment, { children: [_jsx(LockLockedIcon, { className: 'seam-lock-icon' }), _jsx("span", { className: 'seam-status-text', children: t.locked })] }));
12
+ }
13
+ return (_jsxs(_Fragment, { children: [_jsx(LockUnlockedIcon, { className: 'seam-lock-icon' }), _jsx("span", { className: 'seam-status-text', children: t.unlocked })] }));
14
+ }
15
+ const t = {
16
+ locked: 'Locked',
17
+ unlocked: 'Unlocked',
18
+ };
19
+ //# sourceMappingURL=LockStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LockStatus.js","sourceRoot":"","sources":["../../../src/lib/ui/device/LockStatus.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAM5D,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EACJ,MAAM,EAAE,EACN,UAAU,EAAE,EAAE,MAAM,EAAE,GACvB,GACF,GAAG,KAAK,CAAA;IAET,OAAO,CACL,cAAK,SAAS,EAAC,kBAAkB,YAC/B,KAAC,OAAO,IAAC,QAAQ,EAAE,MAAM,GAAI,GACzB,CACP,CAAA;AACH,CAAC;AAED,SAAS,OAAO,CAAC,KAA4B;IAC3C,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IAC1B,IAAI,QAAQ,EAAE;QACZ,OAAO,CACL,8BACE,KAAC,cAAc,IAAC,SAAS,EAAC,gBAAgB,GAAG,EAC7C,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,MAAM,GAAQ,IACnD,CACJ,CAAA;KACF;IAED,OAAO,CACL,8BACE,KAAC,gBAAgB,IAAC,SAAS,EAAC,gBAAgB,GAAG,EAC/C,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,QAAQ,GAAQ,IACrD,CACJ,CAAA;AACH,CAAC;AAED,MAAM,CAAC,GAAG;IACR,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;CACrB,CAAA"}
@@ -0,0 +1,5 @@
1
+ import type { LockDevice } from 'seamapi';
2
+ export interface OnlineStatusProps {
3
+ device: LockDevice;
4
+ }
5
+ export declare function OnlineStatus(props: OnlineStatusProps): JSX.Element;
@@ -1,11 +1,11 @@
1
- import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { OnlineStatusDeviceOfflineIcon } from '../../../lib/icons/OnlineStatusDeviceOffline.js';
3
3
  import { OnlineStatusOnlineIcon } from '../../../lib/icons/OnlineStatusOnline.js';
4
4
  export function OnlineStatus(props) {
5
- const { device } = props;
6
- return (_jsxs(_Fragment, { children: [_jsxs("span", { className: 'seam-label', children: [t.status, ":"] }), ' ', _jsx("div", { className: 'seam-online-status', children: _jsx(Status, { isOnline: device.properties.online }) })] }));
5
+ const { device: { properties: { online }, }, } = props;
6
+ return (_jsx("div", { className: 'seam-online-status', children: _jsx(Content, { isOnline: online }) }));
7
7
  }
8
- function Status(props) {
8
+ function Content(props) {
9
9
  const { isOnline } = props;
10
10
  if (isOnline) {
11
11
  return (_jsxs(_Fragment, { children: [_jsx(OnlineStatusOnlineIcon, {}), _jsx("span", { className: 'seam-status-text', children: t.online })] }));
@@ -14,7 +14,6 @@ function Status(props) {
14
14
  return (_jsxs(_Fragment, { children: [_jsx(OnlineStatusDeviceOfflineIcon, {}), _jsx("span", { className: 'seam-text-danger', children: t.deviceOffline })] }));
15
15
  }
16
16
  const t = {
17
- status: 'Status',
18
17
  online: 'Online',
19
18
  deviceOffline: 'Device Offline',
20
19
  };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OnlineStatus.js","sourceRoot":"","sources":["../../../src/lib/ui/device/OnlineStatus.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,6BAA6B,EAAE,MAAM,wCAAwC,CAAA;AACtF,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAA;AAMxE,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,EACJ,MAAM,EAAE,EACN,UAAU,EAAE,EAAE,MAAM,EAAE,GACvB,GACF,GAAG,KAAK,CAAA;IAET,OAAO,CACL,cAAK,SAAS,EAAC,oBAAoB,YACjC,KAAC,OAAO,IAAC,QAAQ,EAAE,MAAM,GAAI,GACzB,CACP,CAAA;AACH,CAAC;AAED,SAAS,OAAO,CAAC,KAA4B;IAC3C,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;IAC1B,IAAI,QAAQ,EAAE;QACZ,OAAO,CACL,8BACE,KAAC,sBAAsB,KAAG,EAC1B,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,MAAM,GAAQ,IACnD,CACJ,CAAA;KACF;IAED,yCAAyC;IAEzC,OAAO,CACL,8BACE,KAAC,6BAA6B,KAAG,EACjC,eAAM,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,aAAa,GAAQ,IAC1D,CACJ,CAAA;AACH,CAAC;AAED,MAAM,CAAC,GAAG;IACR,MAAM,EAAE,QAAQ;IAChB,aAAa,EAAE,gBAAgB;CAChC,CAAA"}
package/lib/ui/index.d.ts CHANGED
@@ -1 +1,3 @@
1
- export * from './DeviceManager/DeviceManager.js';
1
+ export * from './AccessCodeTable/AccessCodeTable.js';
2
+ export * from './DeviceDetails/DeviceDetails.js';
3
+ export * from './DeviceTable/DeviceTable.js';
package/lib/ui/index.js CHANGED
@@ -1,2 +1,4 @@
1
- export * from './DeviceManager/DeviceManager.js';
1
+ export * from './AccessCodeTable/AccessCodeTable.js';
2
+ export * from './DeviceDetails/DeviceDetails.js';
3
+ export * from './DeviceTable/DeviceTable.js';
2
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/ui/index.ts"],"names":[],"mappings":"AAAA,cAAc,kCAAkC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/ui/index.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAA;AACpD,cAAc,kCAAkC,CAAA;AAChD,cAAc,8BAA8B,CAAA"}
@@ -1,4 +1,3 @@
1
1
  export declare function ContentHeader(props: {
2
2
  title?: string;
3
- onClickBack?: () => void;
4
- }): JSX.Element;
3
+ }): JSX.Element | null;
@@ -1,7 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { ArrowBackIcon } from '../../../lib/icons/ArrowBack.js';
3
+ import { useNavigation } from '../../../lib/NavigationProvider.js';
3
4
  export function ContentHeader(props) {
4
- return (_jsxs("div", { className: 'seam-content-header', children: [_jsx(BackIcon, { onClick: props.onClickBack }), _jsx("span", { className: 'seam-title', children: props.title })] }));
5
+ const { title } = props;
6
+ const { goBack } = useNavigation();
7
+ if (!title && !goBack) {
8
+ return null;
9
+ }
10
+ return (_jsxs("div", { className: 'seam-content-header', children: [goBack && _jsx(BackIcon, { onClick: goBack }), _jsx("span", { className: 'seam-title', children: title })] }));
5
11
  }
6
12
  function BackIcon(props) {
7
13
  if (props.onClick == null) {
@@ -1 +1 @@
1
- {"version":3,"file":"ContentHeader.js","sourceRoot":"","sources":["../../../src/lib/ui/layout/ContentHeader.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAEtD,MAAM,UAAU,aAAa,CAAC,KAG7B;IACC,OAAO,CACL,eAAK,SAAS,EAAC,qBAAqB,aAClC,KAAC,QAAQ,IAAC,OAAO,EAAE,KAAK,CAAC,WAAW,GAAI,EACxC,eAAM,SAAS,EAAC,YAAY,YAAE,KAAK,CAAC,KAAK,GAAQ,IAC7C,CACP,CAAA;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAA+B;IAC/C,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,EAAE;QACzB,OAAO,IAAI,CAAA;KACZ;IAED,OAAO,KAAC,aAAa,IAAC,SAAS,EAAC,gBAAgB,EAAC,OAAO,EAAE,KAAK,CAAC,OAAO,GAAI,CAAA;AAC7E,CAAC"}
1
+ {"version":3,"file":"ContentHeader.js","sourceRoot":"","sources":["../../../src/lib/ui/layout/ContentHeader.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAEzD,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAA;IAEvB,MAAM,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAAA;IAClC,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE;QACrB,OAAO,IAAI,CAAA;KACZ;IAED,OAAO,CACL,eAAK,SAAS,EAAC,qBAAqB,aACjC,MAAM,IAAI,KAAC,QAAQ,IAAC,OAAO,EAAE,MAAM,GAAI,EACxC,eAAM,SAAS,EAAC,YAAY,YAAE,KAAK,GAAQ,IACvC,CACP,CAAA;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAA+B;IAC/C,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI,EAAE;QACzB,OAAO,IAAI,CAAA;KACZ;IAED,OAAO,KAAC,aAAa,IAAC,SAAS,EAAC,gBAAgB,EAAC,OAAO,EAAE,KAAK,CAAC,OAAO,GAAI,CAAA;AAC7E,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seamapi/react",
3
- "version": "0.16.1",
3
+ "version": "0.17.0",
4
4
  "description": "Seam React component library.",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -95,7 +95,7 @@
95
95
  "@tanstack/react-query": "^4.28.0",
96
96
  "classnames": "^2.3.2",
97
97
  "luxon": "^3.3.0",
98
- "seamapi": "^5.19.0-alpha.3",
98
+ "seamapi": "^5.21.0",
99
99
  "uuid": "^9.0.0"
100
100
  },
101
101
  "devDependencies": {
@@ -154,6 +154,7 @@
154
154
  "tsconfig-paths-webpack-plugin": "^4.0.1",
155
155
  "typescript": "^5.0.2",
156
156
  "vite": "^4.2.1",
157
- "vite-tsconfig-paths": "^4.0.8"
157
+ "vite-tsconfig-paths": "^4.0.8",
158
+ "zustand-hoist": "^1.0.0"
158
159
  }
159
160
  }
@@ -0,0 +1,8 @@
1
+ <svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <mask id="mask0_221_23114" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="25" height="25">
3
+ <rect x="0.460693" y="0.838623" width="24" height="24" fill="#D9D9D9"/>
4
+ </mask>
5
+ <g mask="url(#mask0_221_23114)">
6
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M5.924 3.89346C3.45898 3.89346 1.46069 5.89176 1.46069 8.35678V11.702C1.46069 12.2543 1.90841 12.702 2.46069 12.702C3.01298 12.702 3.46069 12.2543 3.46069 11.702V8.35678C3.46069 6.99633 4.56356 5.89346 5.924 5.89346C7.28445 5.89346 8.38731 6.99633 8.38731 8.35677V12.8385H7.72008C7.02454 12.8385 6.46069 13.4024 6.46069 14.0979V19.5791C6.46069 20.2747 7.02454 20.8385 7.72008 20.8385H17.2013C17.8968 20.8385 18.4607 20.2747 18.4607 19.5791V14.0979C18.4607 13.4024 17.8968 12.8385 17.2013 12.8385H10.3873V8.35677C10.3873 5.89176 8.38902 3.89346 5.924 3.89346Z" fill="#232B3A"/>
7
+ </g>
8
+ </svg>
@@ -0,0 +1,9 @@
1
+ <svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <mask id="mask0_221_23076" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="25" height="25">
3
+ <rect x="0.460693" y="0.838623" width="24" height="24" fill="#D9D9D9"/>
4
+ </mask>
5
+ <g mask="url(#mask0_221_23076)">
6
+ <rect x="6.46069" y="12.8386" width="12" height="8.15217" rx="1.25939" fill="#232B3A"/>
7
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M7.94067 10.3586C7.94067 7.8623 9.96435 5.83862 12.4607 5.83862C14.957 5.83862 16.9807 7.86229 16.9807 10.3586V16.0506C16.9807 16.6029 16.533 17.0506 15.9807 17.0506C15.4284 17.0506 14.9807 16.6029 14.9807 16.0506V10.3586C14.9807 8.96686 13.8524 7.83862 12.4607 7.83862C11.0689 7.83862 9.94067 8.96687 9.94067 10.3586V13.8902C9.94067 14.4425 9.49296 14.8902 8.94067 14.8902C8.38839 14.8902 7.94067 14.4425 7.94067 13.8902V10.3586Z" fill="#232B3A"/>
8
+ </g>
9
+ </svg>
@@ -0,0 +1,86 @@
1
+ import React, { useState } from 'react'
2
+
3
+ interface DeviceTableView {
4
+ name: 'device_table'
5
+ }
6
+
7
+ interface DeviceDetailView {
8
+ name: 'device_detail'
9
+ deviceId: string
10
+ }
11
+
12
+ interface AccessCodeTableView {
13
+ name: 'access_code_table'
14
+ deviceId: string
15
+ }
16
+
17
+ interface AccessCodeDetailView {
18
+ name: 'access_code_detail'
19
+ accessCodeId: string
20
+ }
21
+
22
+ export type View =
23
+ | DeviceTableView
24
+ | DeviceDetailView
25
+ | AccessCodeTableView
26
+ | AccessCodeDetailView
27
+
28
+ export interface NavigationStackProps {
29
+ children: JSX.Element
30
+ }
31
+
32
+ interface NavigationContextProps {
33
+ views: View[]
34
+ show: (view: View) => void
35
+ goBack?: () => void
36
+ }
37
+
38
+ const NavigationContext = React.createContext<
39
+ NavigationContextProps | undefined
40
+ >(undefined)
41
+
42
+ export default function NavigationProvider({ children }: NavigationStackProps) {
43
+ const [views, setViews] = useState<View[]>([])
44
+
45
+ const pushView = (view: View) => {
46
+ setViews((current) => [view, ...current])
47
+ }
48
+
49
+ const popView = () => {
50
+ setViews((current) => {
51
+ if (current.length === 0) {
52
+ return current
53
+ }
54
+
55
+ const [_showing, ...others] = current
56
+ return others
57
+ })
58
+ }
59
+
60
+ const hasViews = views.length > 0
61
+
62
+ return (
63
+ <NavigationContext.Provider
64
+ value={{
65
+ views,
66
+ show: pushView,
67
+ goBack: hasViews ? popView : undefined,
68
+ }}
69
+ >
70
+ {children}
71
+ </NavigationContext.Provider>
72
+ )
73
+ }
74
+
75
+ export function useNavigation(): NavigationContextProps {
76
+ const context = React.useContext(NavigationContext)
77
+ if (context === undefined) {
78
+ return {
79
+ show: () => {},
80
+ goBack: undefined,
81
+ views: [],
82
+ }
83
+ }
84
+
85
+ return context
86
+ }
@@ -0,0 +1,32 @@
1
+ import { AccessCodeTable, DeviceDetails, DeviceTable } from 'lib/index.js'
2
+
3
+ import { useNavigation, type View } from 'lib/NavigationProvider.js'
4
+ import AccessCodeDetails from 'lib/ui/AccessCodeDetails/AccessCodeDetails.js'
5
+
6
+ interface NavigationViewProps {
7
+ children: JSX.Element
8
+ }
9
+
10
+ export function NavigationView({ children: rootView }: NavigationViewProps) {
11
+ const { views } = useNavigation()
12
+
13
+ const firstView = views[0]
14
+ if (firstView != null) {
15
+ return <Subview view={firstView} />
16
+ }
17
+
18
+ return rootView
19
+ }
20
+
21
+ function Subview({ view }: { view: View }) {
22
+ switch (view.name) {
23
+ case 'device_detail':
24
+ return <DeviceDetails deviceId={view.deviceId} />
25
+ case 'access_code_detail':
26
+ return <AccessCodeDetails accessCodeId={view.accessCodeId} />
27
+ case 'device_table':
28
+ return <DeviceTable />
29
+ case 'access_code_table':
30
+ return <AccessCodeTable deviceId={view.deviceId} />
31
+ }
32
+ }