@canva/cli 1.19.0 → 1.20.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 (231) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +1 -9
  3. package/cli.js +408 -409
  4. package/package.json +1 -2
  5. package/templates/base/backend/base_backend/create.ts +0 -114
  6. package/templates/base/backend/database/database.ts +0 -42
  7. package/templates/base/backend/routers/auth.ts +0 -288
  8. package/templates/base/declarations/declarations.d.ts +0 -29
  9. package/templates/base/eslint.config.mjs +0 -14
  10. package/templates/base/package.json +0 -91
  11. package/templates/base/scripts/copy_env.ts +0 -13
  12. package/templates/base/scripts/ssl/ssl.ts +0 -131
  13. package/templates/base/scripts/start/app_runner.ts +0 -223
  14. package/templates/base/scripts/start/context.ts +0 -171
  15. package/templates/base/scripts/start/start.ts +0 -46
  16. package/templates/base/scripts/start.tests.ts +0 -61
  17. package/templates/base/styles/components.css +0 -38
  18. package/templates/base/tsconfig.json +0 -56
  19. package/templates/base/webpack.config.ts +0 -247
  20. package/templates/common/.env.template +0 -6
  21. package/templates/common/.gitignore.template +0 -8
  22. package/templates/common/.nvmrc +0 -1
  23. package/templates/common/.prettierrc +0 -21
  24. package/templates/common/LICENSE.md +0 -48
  25. package/templates/common/README.md +0 -179
  26. package/templates/common/jest.config.mjs +0 -35
  27. package/templates/common/jest.setup.ts +0 -35
  28. package/templates/content_publisher/README.md +0 -58
  29. package/templates/content_publisher/canva-app.json +0 -17
  30. package/templates/content_publisher/declarations/declarations.d.ts +0 -29
  31. package/templates/content_publisher/eslint.config.mjs +0 -14
  32. package/templates/content_publisher/package.json +0 -90
  33. package/templates/content_publisher/scripts/copy_env.ts +0 -13
  34. package/templates/content_publisher/scripts/ssl/ssl.ts +0 -131
  35. package/templates/content_publisher/scripts/start/app_runner.ts +0 -223
  36. package/templates/content_publisher/scripts/start/context.ts +0 -171
  37. package/templates/content_publisher/scripts/start/start.ts +0 -46
  38. package/templates/content_publisher/src/index.tsx +0 -4
  39. package/templates/content_publisher/src/intents/content_publisher/index.tsx +0 -107
  40. package/templates/content_publisher/src/intents/content_publisher/post_preview.tsx +0 -240
  41. package/templates/content_publisher/src/intents/content_publisher/preview_ui.tsx +0 -62
  42. package/templates/content_publisher/src/intents/content_publisher/settings_ui.tsx +0 -81
  43. package/templates/content_publisher/src/intents/content_publisher/types.ts +0 -29
  44. package/templates/content_publisher/styles/components.css +0 -38
  45. package/templates/content_publisher/styles/preview_ui.css +0 -49
  46. package/templates/content_publisher/tsconfig.json +0 -56
  47. package/templates/content_publisher/webpack.config.ts +0 -247
  48. package/templates/dam/backend/routers/dam.ts +0 -108
  49. package/templates/dam/backend/server.ts +0 -65
  50. package/templates/dam/canva-app.json +0 -25
  51. package/templates/dam/declarations/declarations.d.ts +0 -29
  52. package/templates/dam/eslint.config.mjs +0 -14
  53. package/templates/dam/package.json +0 -97
  54. package/templates/dam/scripts/copy_env.ts +0 -13
  55. package/templates/dam/scripts/ssl/ssl.ts +0 -131
  56. package/templates/dam/scripts/start/app_runner.ts +0 -223
  57. package/templates/dam/scripts/start/context.ts +0 -171
  58. package/templates/dam/scripts/start/start.ts +0 -46
  59. package/templates/dam/src/index.tsx +0 -4
  60. package/templates/dam/src/intents/design_editor/adapter.ts +0 -44
  61. package/templates/dam/src/intents/design_editor/app.tsx +0 -35
  62. package/templates/dam/src/intents/design_editor/config.ts +0 -220
  63. package/templates/dam/src/intents/design_editor/index.css +0 -3
  64. package/templates/dam/src/intents/design_editor/index.tsx +0 -25
  65. package/templates/dam/tsconfig.json +0 -56
  66. package/templates/dam/utils/backend/base_backend/create.ts +0 -114
  67. package/templates/dam/webpack.config.ts +0 -247
  68. package/templates/data_connector/README.md +0 -84
  69. package/templates/data_connector/canva-app.json +0 -21
  70. package/templates/data_connector/declarations/declarations.d.ts +0 -29
  71. package/templates/data_connector/eslint.config.mjs +0 -14
  72. package/templates/data_connector/package.json +0 -92
  73. package/templates/data_connector/scripts/copy_env.ts +0 -13
  74. package/templates/data_connector/scripts/ssl/ssl.ts +0 -131
  75. package/templates/data_connector/scripts/start/app_runner.ts +0 -223
  76. package/templates/data_connector/scripts/start/context.ts +0 -171
  77. package/templates/data_connector/scripts/start/start.ts +0 -46
  78. package/templates/data_connector/src/api/connect_client.ts +0 -6
  79. package/templates/data_connector/src/api/data_source.ts +0 -97
  80. package/templates/data_connector/src/api/data_sources/designs.tsx +0 -296
  81. package/templates/data_connector/src/api/data_sources/index.ts +0 -4
  82. package/templates/data_connector/src/api/data_sources/templates.tsx +0 -328
  83. package/templates/data_connector/src/api/fetch_data_table.ts +0 -55
  84. package/templates/data_connector/src/api/index.ts +0 -4
  85. package/templates/data_connector/src/api/oauth.ts +0 -8
  86. package/templates/data_connector/src/api/tests/data_source.test.tsx +0 -99
  87. package/templates/data_connector/src/components/app_error.tsx +0 -15
  88. package/templates/data_connector/src/components/footer.tsx +0 -26
  89. package/templates/data_connector/src/components/header.tsx +0 -40
  90. package/templates/data_connector/src/components/index.ts +0 -3
  91. package/templates/data_connector/src/components/inputs/messages.tsx +0 -95
  92. package/templates/data_connector/src/components/inputs/search_filter.tsx +0 -109
  93. package/templates/data_connector/src/components/inputs/select_field.tsx +0 -26
  94. package/templates/data_connector/src/context/app_context.tsx +0 -125
  95. package/templates/data_connector/src/context/index.ts +0 -2
  96. package/templates/data_connector/src/context/use_app_context.ts +0 -17
  97. package/templates/data_connector/src/index.tsx +0 -4
  98. package/templates/data_connector/src/intents/data_connector/app.tsx +0 -20
  99. package/templates/data_connector/src/intents/data_connector/entrypoint.tsx +0 -70
  100. package/templates/data_connector/src/intents/data_connector/home.tsx +0 -21
  101. package/templates/data_connector/src/intents/data_connector/index.tsx +0 -56
  102. package/templates/data_connector/src/pages/data_source_config.tsx +0 -9
  103. package/templates/data_connector/src/pages/error.tsx +0 -37
  104. package/templates/data_connector/src/pages/index.ts +0 -4
  105. package/templates/data_connector/src/pages/login.tsx +0 -145
  106. package/templates/data_connector/src/pages/select_source.tsx +0 -24
  107. package/templates/data_connector/src/routes/index.ts +0 -2
  108. package/templates/data_connector/src/routes/paths.ts +0 -7
  109. package/templates/data_connector/src/routes/protected_route.tsx +0 -26
  110. package/templates/data_connector/src/routes/routes.tsx +0 -42
  111. package/templates/data_connector/src/utils/data_params.ts +0 -17
  112. package/templates/data_connector/src/utils/data_table.ts +0 -116
  113. package/templates/data_connector/src/utils/fetch_result.ts +0 -36
  114. package/templates/data_connector/src/utils/index.ts +0 -2
  115. package/templates/data_connector/src/utils/tests/data_table.test.ts +0 -133
  116. package/templates/data_connector/styles/components.css +0 -38
  117. package/templates/data_connector/tsconfig.json +0 -56
  118. package/templates/data_connector/webpack.config.ts +0 -247
  119. package/templates/gen_ai/README.md +0 -27
  120. package/templates/gen_ai/backend/routers/image.ts +0 -232
  121. package/templates/gen_ai/backend/server.ts +0 -65
  122. package/templates/gen_ai/canva-app.json +0 -25
  123. package/templates/gen_ai/declarations/declarations.d.ts +0 -29
  124. package/templates/gen_ai/eslint.config.mjs +0 -14
  125. package/templates/gen_ai/package.json +0 -101
  126. package/templates/gen_ai/scripts/copy_env.ts +0 -13
  127. package/templates/gen_ai/scripts/ssl/ssl.ts +0 -131
  128. package/templates/gen_ai/scripts/start/app_runner.ts +0 -223
  129. package/templates/gen_ai/scripts/start/context.ts +0 -171
  130. package/templates/gen_ai/scripts/start/start.ts +0 -46
  131. package/templates/gen_ai/src/api/api.ts +0 -194
  132. package/templates/gen_ai/src/api/index.ts +0 -1
  133. package/templates/gen_ai/src/components/app_error.tsx +0 -18
  134. package/templates/gen_ai/src/components/footer.messages.ts +0 -48
  135. package/templates/gen_ai/src/components/footer.tsx +0 -156
  136. package/templates/gen_ai/src/components/image_grid.tsx +0 -103
  137. package/templates/gen_ai/src/components/index.ts +0 -7
  138. package/templates/gen_ai/src/components/loading_results.tsx +0 -169
  139. package/templates/gen_ai/src/components/prompt_input.messages.ts +0 -14
  140. package/templates/gen_ai/src/components/prompt_input.tsx +0 -154
  141. package/templates/gen_ai/src/components/remaining_credits.tsx +0 -84
  142. package/templates/gen_ai/src/components/report_box.tsx +0 -54
  143. package/templates/gen_ai/src/components/tests/remaining_credit.tests.tsx +0 -47
  144. package/templates/gen_ai/src/config.ts +0 -21
  145. package/templates/gen_ai/src/context/app_context.tsx +0 -153
  146. package/templates/gen_ai/src/context/context.messages.ts +0 -30
  147. package/templates/gen_ai/src/context/index.ts +0 -2
  148. package/templates/gen_ai/src/context/use_app_context.ts +0 -17
  149. package/templates/gen_ai/src/index.tsx +0 -4
  150. package/templates/gen_ai/src/intents/design_editor/app.tsx +0 -19
  151. package/templates/gen_ai/src/intents/design_editor/home.tsx +0 -13
  152. package/templates/gen_ai/src/intents/design_editor/index.tsx +0 -17
  153. package/templates/gen_ai/src/pages/error.tsx +0 -41
  154. package/templates/gen_ai/src/pages/generate.tsx +0 -9
  155. package/templates/gen_ai/src/pages/index.ts +0 -3
  156. package/templates/gen_ai/src/pages/results.tsx +0 -31
  157. package/templates/gen_ai/src/routes/index.ts +0 -1
  158. package/templates/gen_ai/src/routes/paths.ts +0 -4
  159. package/templates/gen_ai/src/routes/routes.tsx +0 -24
  160. package/templates/gen_ai/src/utils/index.ts +0 -1
  161. package/templates/gen_ai/src/utils/obscenity_filter.ts +0 -33
  162. package/templates/gen_ai/styles/components.css +0 -38
  163. package/templates/gen_ai/styles/utils.css +0 -3
  164. package/templates/gen_ai/tsconfig.json +0 -56
  165. package/templates/gen_ai/utils/backend/base_backend/create.ts +0 -114
  166. package/templates/gen_ai/webpack.config.ts +0 -247
  167. package/templates/hello_world/canva-app.json +0 -21
  168. package/templates/hello_world/declarations/declarations.d.ts +0 -29
  169. package/templates/hello_world/eslint.config.mjs +0 -14
  170. package/templates/hello_world/package.json +0 -90
  171. package/templates/hello_world/scripts/copy_env.ts +0 -13
  172. package/templates/hello_world/scripts/ssl/ssl.ts +0 -131
  173. package/templates/hello_world/scripts/start/app_runner.ts +0 -223
  174. package/templates/hello_world/scripts/start/context.ts +0 -171
  175. package/templates/hello_world/scripts/start/start.ts +0 -46
  176. package/templates/hello_world/src/index.tsx +0 -4
  177. package/templates/hello_world/src/intents/design_editor/app.tsx +0 -86
  178. package/templates/hello_world/src/intents/design_editor/index.tsx +0 -25
  179. package/templates/hello_world/src/intents/design_editor/tests/__snapshots__/app.tests.tsx.snap +0 -45
  180. package/templates/hello_world/src/intents/design_editor/tests/app.tests.tsx +0 -92
  181. package/templates/hello_world/styles/components.css +0 -38
  182. package/templates/hello_world/tsconfig.json +0 -56
  183. package/templates/hello_world/webpack.config.ts +0 -247
  184. package/templates/mls/README.md +0 -81
  185. package/templates/mls/canva-app.json +0 -25
  186. package/templates/mls/declarations/declarations.d.ts +0 -29
  187. package/templates/mls/eslint.config.mjs +0 -14
  188. package/templates/mls/jest.config.mjs +0 -36
  189. package/templates/mls/jest.setup.ts +0 -39
  190. package/templates/mls/package.json +0 -117
  191. package/templates/mls/scripts/copy_env.ts +0 -13
  192. package/templates/mls/scripts/ssl/ssl.ts +0 -131
  193. package/templates/mls/scripts/start/app_runner.ts +0 -223
  194. package/templates/mls/scripts/start/context.ts +0 -171
  195. package/templates/mls/scripts/start/start.ts +0 -46
  196. package/templates/mls/src/__tests__/app.tests.tsx +0 -11
  197. package/templates/mls/src/__tests__/office_selection_page.tests.tsx +0 -72
  198. package/templates/mls/src/__tests__/utils.tsx +0 -19
  199. package/templates/mls/src/adapter.ts +0 -126
  200. package/templates/mls/src/components/agent/agent_card.tsx +0 -57
  201. package/templates/mls/src/components/agent/agent_grid.tsx +0 -37
  202. package/templates/mls/src/components/agent/agent_list.tsx +0 -17
  203. package/templates/mls/src/components/agent/agent_search_filters.tsx +0 -88
  204. package/templates/mls/src/components/breadcrumb/breadcrumb.tsx +0 -40
  205. package/templates/mls/src/components/listing/listing_card.tsx +0 -64
  206. package/templates/mls/src/components/listing/listing_grid.tsx +0 -37
  207. package/templates/mls/src/components/listing/listing_list.tsx +0 -21
  208. package/templates/mls/src/components/listing/listing_search_filters.tsx +0 -145
  209. package/templates/mls/src/components/placeholders/placeholders.tsx +0 -65
  210. package/templates/mls/src/data.ts +0 -359
  211. package/templates/mls/src/index.tsx +0 -4
  212. package/templates/mls/src/intents/design_editor/app.tsx +0 -44
  213. package/templates/mls/src/intents/design_editor/index.tsx +0 -25
  214. package/templates/mls/src/pages/agent_details_page/agent_details_page.tsx +0 -175
  215. package/templates/mls/src/pages/list_page/agent_tab_panel.tsx +0 -126
  216. package/templates/mls/src/pages/list_page/list_page.tsx +0 -67
  217. package/templates/mls/src/pages/list_page/listing_tab_panel.tsx +0 -135
  218. package/templates/mls/src/pages/listing_details_page/listing_details_page.tsx +0 -418
  219. package/templates/mls/src/pages/loading_page/loading_page.tsx +0 -152
  220. package/templates/mls/src/pages/office_selection_page/office_selection_page.tsx +0 -144
  221. package/templates/mls/src/real_estate.type.ts +0 -44
  222. package/templates/mls/src/util/use_add_element.tsx +0 -62
  223. package/templates/mls/src/util/use_drag_element.tsx +0 -68
  224. package/templates/mls/styles/components.css +0 -38
  225. package/templates/mls/tsconfig.json +0 -54
  226. package/templates/mls/webpack.config.ts +0 -248
  227. package/templates/optional/.cursor/mcp.json +0 -8
  228. package/templates/optional/.vscode/extensions.json +0 -6
  229. package/templates/optional/.vscode/mcp.json +0 -9
  230. package/templates/optional/AGENTS.md +0 -154
  231. package/templates/optional/CLAUDE.md +0 -154
@@ -1,126 +0,0 @@
1
- import { Box, Rows, Scrollable, Text } from "@canva/app-ui-kit";
2
- import { useInfiniteQuery } from "@tanstack/react-query";
3
- import { useState } from "react";
4
- import InfiniteScroll from "react-infinite-scroller";
5
- import { useIntl } from "react-intl";
6
- import { useNavigate } from "react-router-dom";
7
- import { fetchAgents } from "../../adapter";
8
- import { AgentGrid } from "../../components/agent/agent_grid";
9
- import { AgentList } from "../../components/agent/agent_list";
10
- import { AgentSearchFilters } from "../../components/agent/agent_search_filters";
11
- import {
12
- GridPlaceholder,
13
- ListPlaceholder,
14
- } from "../../components/placeholders/placeholders";
15
- import type { Agent, Office } from "../../real_estate.type";
16
-
17
- type Layout = "grid" | "list";
18
-
19
- interface AgentTabContentProps {
20
- office: Office;
21
- }
22
-
23
- export const AgentTabPanel = ({ office }: AgentTabContentProps) => {
24
- const intl = useIntl();
25
- const [layout, setLayout] = useState<Layout>("grid");
26
- const [query, setQuery] = useState<string>("");
27
- const [sort, setSort] = useState<string>("");
28
-
29
- const toggleLayout = () => {
30
- setLayout(layout === "grid" ? "list" : "grid");
31
- };
32
-
33
- const {
34
- data: agentItems,
35
- hasNextPage,
36
- isLoading,
37
- fetchNextPage,
38
- isFetchingNextPage,
39
- isError,
40
- } = useInfiniteQuery({
41
- queryKey: ["agents", query, sort, office],
42
- queryFn: async ({ pageParam }: { pageParam: string | undefined }) => {
43
- return fetchAgents(office, query, pageParam, sort);
44
- },
45
- getNextPageParam: (lastPage) => lastPage?.continuation,
46
- initialPageParam: undefined,
47
- });
48
-
49
- const agents = agentItems?.pages?.flatMap((page) => page.agents) || [];
50
- const navigate = useNavigate();
51
- const handleAgentClick = (item: Agent) => {
52
- navigate(`/details/agent`, { state: { office, agent: item } });
53
- };
54
-
55
- return (
56
- <Scrollable>
57
- <InfiniteScroll
58
- loadMore={() => fetchNextPage()}
59
- hasMore={hasNextPage}
60
- useWindow={false}
61
- >
62
- <Box height="full">
63
- <Rows spacing="2u">
64
- {((!isError && !isLoading && agents.length > 0) ||
65
- query?.length) && (
66
- <AgentSearchFilters
67
- query={query}
68
- onQueryChange={setQuery}
69
- layout={layout}
70
- onLayoutToggle={toggleLayout}
71
- sort={sort}
72
- onSortChange={setSort}
73
- />
74
- )}
75
- {isError && (
76
- <Text tone="critical">
77
- {intl.formatMessage({
78
- defaultMessage: "Error loading agents. Please try again.",
79
- description: "Error message when agents fail to load",
80
- })}
81
- </Text>
82
- )}
83
- {isLoading && (
84
- <Box width="full" paddingBottom="2u">
85
- {layout === "grid" ? <GridPlaceholder /> : <ListPlaceholder />}
86
- </Box>
87
- )}
88
- {!isError && !isLoading && agents.length === 0 && (
89
- <Box
90
- height="full"
91
- display="flex"
92
- alignItems="center"
93
- justifyContent="center"
94
- >
95
- <Text>
96
- {intl.formatMessage({
97
- defaultMessage: "No agents found in this office.",
98
- description: "Message shown when no agents are found",
99
- })}
100
- </Text>
101
- </Box>
102
- )}
103
- {!isError && !isLoading && agents.length > 0 && (
104
- <Rows spacing={layout === "grid" ? "2u" : "0"}>
105
- {layout === "grid" ? (
106
- <AgentGrid agents={agents} onAgentClick={handleAgentClick} />
107
- ) : (
108
- <AgentList agents={agents} onAgentClick={handleAgentClick} />
109
- )}
110
- {isFetchingNextPage && (
111
- <Box width="full" paddingBottom="2u">
112
- {layout === "grid" ? (
113
- <GridPlaceholder />
114
- ) : (
115
- <ListPlaceholder />
116
- )}
117
- </Box>
118
- )}
119
- </Rows>
120
- )}
121
- </Rows>
122
- </Box>
123
- </InfiniteScroll>
124
- </Scrollable>
125
- );
126
- };
@@ -1,67 +0,0 @@
1
- import {
2
- Box,
3
- Tab,
4
- TabList,
5
- TabPanel,
6
- TabPanels,
7
- Tabs,
8
- } from "@canva/app-ui-kit";
9
- import { useIntl } from "react-intl";
10
- import { useLocation, useNavigate, useParams } from "react-router-dom";
11
- import { Breadcrumb } from "../../components/breadcrumb/breadcrumb";
12
- import type { Office } from "../../real_estate.type";
13
- import { AgentTabPanel } from "./agent_tab_panel";
14
- import { ListingTabPanel } from "./listing_tab_panel";
15
-
16
- export const ListPage = () => {
17
- const navigate = useNavigate();
18
- const { tab = "listings" } = useParams<{
19
- tab?: string;
20
- }>();
21
- const { office } = useLocation().state as { office: Office };
22
- const intl = useIntl();
23
-
24
- return (
25
- <Tabs
26
- onSelect={(value) => navigate(`/list/${value}`, { state: { office } })}
27
- activeId={tab}
28
- height="fill"
29
- >
30
- <Box height="full" display="flex" flexDirection="column" paddingTop="2u">
31
- <Breadcrumb />
32
- <Box paddingBottom="1u">
33
- <TabList>
34
- <Tab
35
- id="listings"
36
- active={tab === "listings"}
37
- onClick={() => navigate(`/list/listings`, { state: { office } })}
38
- >
39
- {intl.formatMessage({
40
- defaultMessage: "Listings",
41
- description: "Tab label for property listings",
42
- })}
43
- </Tab>
44
- <Tab
45
- id="agents"
46
- active={tab === "agents"}
47
- onClick={() => navigate(`/list/agents`, { state: { office } })}
48
- >
49
- {intl.formatMessage({
50
- defaultMessage: "Agents",
51
- description: "Tab label for real estate agents",
52
- })}
53
- </Tab>
54
- </TabList>
55
- </Box>
56
- <TabPanels>
57
- <TabPanel id="listings">
58
- <ListingTabPanel office={office} />
59
- </TabPanel>
60
- <TabPanel id="agents">
61
- <AgentTabPanel office={office} />
62
- </TabPanel>
63
- </TabPanels>
64
- </Box>
65
- </Tabs>
66
- );
67
- };
@@ -1,135 +0,0 @@
1
- import { Box, Rows, Scrollable, Text } from "@canva/app-ui-kit";
2
- import { useInfiniteQuery } from "@tanstack/react-query";
3
- import { useState } from "react";
4
- import InfiniteScroll from "react-infinite-scroller";
5
- import { useIntl } from "react-intl";
6
- import { useNavigate } from "react-router-dom";
7
- import { fetchListings } from "../../adapter";
8
- import { ListingGrid } from "../../components/listing/listing_grid";
9
- import { ListingList } from "../../components/listing/listing_list";
10
- import { ListingSearchFilters } from "../../components/listing/listing_search_filters";
11
- import {
12
- GridPlaceholder,
13
- ListPlaceholder,
14
- } from "../../components/placeholders/placeholders";
15
- import type { Office, Property } from "../../real_estate.type";
16
-
17
- type Layout = "grid" | "list";
18
-
19
- interface ListingTabContentProps {
20
- office: Office;
21
- }
22
-
23
- export const ListingTabPanel = ({ office }: ListingTabContentProps) => {
24
- const intl = useIntl();
25
- const [layout, setLayout] = useState<Layout>("grid");
26
- const [query, setQuery] = useState<string>("");
27
- const [propertyType, setPropertyType] = useState<string>("");
28
- const [sort, setSort] = useState<string>("");
29
-
30
- const toggleLayout = () => {
31
- setLayout(layout === "grid" ? "list" : "grid");
32
- };
33
-
34
- const {
35
- data: listingItems,
36
- hasNextPage,
37
- isLoading,
38
- fetchNextPage,
39
- isFetchingNextPage,
40
- isError,
41
- } = useInfiniteQuery({
42
- queryKey: ["listings", query, propertyType, sort, office],
43
- queryFn: async ({ pageParam }: { pageParam: string | undefined }) => {
44
- return fetchListings(office, query, propertyType, sort, pageParam);
45
- },
46
- getNextPageParam: (lastPage) => lastPage?.continuation,
47
- initialPageParam: undefined,
48
- });
49
- const navigate = useNavigate();
50
-
51
- const listings = listingItems?.pages?.flatMap((page) => page.listings) || [];
52
- const handleListingClick = (item: Property) => {
53
- navigate(`/details/listing`, { state: { office, listing: item } });
54
- };
55
-
56
- return (
57
- <Scrollable>
58
- <InfiniteScroll
59
- loadMore={() => fetchNextPage()}
60
- hasMore={hasNextPage}
61
- useWindow={false}
62
- >
63
- <Box height="full">
64
- <Rows spacing="2u">
65
- {((!isError && !isLoading && !!listings.length) ||
66
- !!query?.length) && (
67
- <ListingSearchFilters
68
- query={query}
69
- onQueryChange={setQuery}
70
- layout={layout}
71
- onLayoutToggle={toggleLayout}
72
- propertyType={propertyType}
73
- onPropertyTypeChange={setPropertyType}
74
- sort={sort}
75
- onSortChange={setSort}
76
- />
77
- )}
78
- {isError && (
79
- <Text tone="critical">
80
- {intl.formatMessage({
81
- defaultMessage: "Error loading listings. Please try again.",
82
- description: "Error message when listings fail to load",
83
- })}
84
- </Text>
85
- )}
86
- {isLoading && (
87
- <Box width="full" paddingBottom="2u">
88
- {layout === "grid" ? <GridPlaceholder /> : <ListPlaceholder />}
89
- </Box>
90
- )}
91
- {!isError && !isLoading && !listings.length && (
92
- <Box
93
- height="full"
94
- display="flex"
95
- alignItems="center"
96
- justifyContent="center"
97
- >
98
- <Text>
99
- {intl.formatMessage({
100
- defaultMessage: "No listings found.",
101
- description: "Message shown when no listings are found",
102
- })}
103
- </Text>
104
- </Box>
105
- )}
106
- {!isError && !isLoading && !!listings.length && (
107
- <Rows spacing={layout === "grid" ? "2u" : "0"}>
108
- {layout === "grid" ? (
109
- <ListingGrid
110
- listings={listings}
111
- onListingClick={handleListingClick}
112
- />
113
- ) : (
114
- <ListingList
115
- listings={listings}
116
- onListingClick={handleListingClick}
117
- />
118
- )}
119
- {isFetchingNextPage && (
120
- <Box width="full" paddingBottom="2u">
121
- {layout === "grid" ? (
122
- <GridPlaceholder />
123
- ) : (
124
- <ListPlaceholder />
125
- )}
126
- </Box>
127
- )}
128
- </Rows>
129
- )}
130
- </Rows>
131
- </Box>
132
- </InfiniteScroll>
133
- </Scrollable>
134
- );
135
- };