@stapel/listings-react 0.15.0 → 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 (48) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/dist/default/GateReasonPopover.d.ts +24 -0
  3. package/dist/default/GateReasonPopover.d.ts.map +1 -0
  4. package/dist/default/GateReasonPopover.js +45 -0
  5. package/dist/default/GateReasonPopover.js.map +1 -0
  6. package/dist/default/ListingCard.d.ts +26 -5
  7. package/dist/default/ListingCard.d.ts.map +1 -1
  8. package/dist/default/ListingCard.js +14 -5
  9. package/dist/default/ListingCard.js.map +1 -1
  10. package/dist/default/ListingComposerPage.d.ts.map +1 -1
  11. package/dist/default/ListingComposerPage.js +7 -1
  12. package/dist/default/ListingComposerPage.js.map +1 -1
  13. package/dist/default/ListingDetailPane.d.ts +70 -1
  14. package/dist/default/ListingDetailPane.d.ts.map +1 -1
  15. package/dist/default/ListingDetailPane.js +136 -38
  16. package/dist/default/ListingDetailPane.js.map +1 -1
  17. package/dist/default/index.d.ts +1 -1
  18. package/dist/default/index.d.ts.map +1 -1
  19. package/dist/default/index.js +4 -1
  20. package/dist/default/index.js.map +1 -1
  21. package/dist/headless/ListingDetail.d.ts +11 -0
  22. package/dist/headless/ListingDetail.d.ts.map +1 -1
  23. package/dist/headless/ListingDetail.js +7 -0
  24. package/dist/headless/ListingDetail.js.map +1 -1
  25. package/dist/i18n/es.d.ts.map +1 -1
  26. package/dist/i18n/es.js +4 -1
  27. package/dist/i18n/es.js.map +1 -1
  28. package/dist/i18n/keys.d.ts +11 -0
  29. package/dist/i18n/keys.d.ts.map +1 -1
  30. package/dist/i18n/keys.js +15 -1
  31. package/dist/i18n/keys.js.map +1 -1
  32. package/dist/i18n/ru.d.ts.map +1 -1
  33. package/dist/i18n/ru.js +4 -1
  34. package/dist/i18n/ru.js.map +1 -1
  35. package/llms.txt +1 -1
  36. package/manifest.json +4 -1
  37. package/nav-manifest.json +1 -1
  38. package/package.json +8 -8
  39. package/src/analytics/generated/events.json +1 -1
  40. package/src/default/GateReasonPopover.tsx +95 -0
  41. package/src/default/ListingCard.tsx +100 -43
  42. package/src/default/ListingComposerPage.tsx +12 -2
  43. package/src/default/ListingDetailPane.tsx +375 -103
  44. package/src/default/index.ts +9 -1
  45. package/src/headless/ListingDetail.tsx +19 -0
  46. package/src/i18n/es.ts +5 -1
  47. package/src/i18n/keys.ts +16 -1
  48. package/src/i18n/ru.ts +5 -1
@@ -74,6 +74,17 @@ export interface ListingDetailBag {
74
74
  readonly removed: boolean;
75
75
  /** The detail 404s and the probe finds nothing either. */
76
76
  readonly notFound: boolean;
77
+ /**
78
+ * The detail 404s, the probe ANSWERED, and the row is NOT soft-deleted:
79
+ * a listing taken down on purpose (archived), not deleted and not a typo.
80
+ *
81
+ * Measured on a live stand: the probe's whole body for such a row was
82
+ * `{"is_deleted": false}` — hence the `!== true` below rather than a read
83
+ * of fields the body may not carry. Without this flag the pane fell into
84
+ * the generic "could not load / retry" arm: a retry that can never help,
85
+ * on a row that is gone by its owner's choice.
86
+ */
87
+ readonly withdrawn: boolean;
77
88
  /** Both axes plus the sentence that comes out of the pair of them. */
78
89
  readonly status: ListingStatusView | undefined;
79
90
  readonly publiclyVisible: boolean;
@@ -150,6 +161,13 @@ export function useListingDetail(
150
161
  detail.status === "error" && errorStatus(detail.error) === 404;
151
162
  const removed = detailIs404 && probe.data?.is_deleted === true;
152
163
  const notFound = detailIs404 && !removed && probe.status === "error";
164
+ // The probe ANSWERED and did not say "deleted": the row exists and its
165
+ // owner took it off the shelf. `!== true` and not `=== false`, because the
166
+ // live probe body can carry `is_deleted` alone — a body missing the field
167
+ // must still read as "not deleted", not fall through to the generic arm.
168
+ const withdrawn =
169
+ detailIs404 && !removed && probe.data !== undefined &&
170
+ probe.data.is_deleted !== true;
153
171
 
154
172
  const status: ListingStatusView | undefined = useMemo(() => {
155
173
  if (detail.data !== undefined) {
@@ -220,6 +238,7 @@ export function useListingDetail(
220
238
  statusState,
221
239
  removed,
222
240
  notFound,
241
+ withdrawn,
223
242
  status,
224
243
  publiclyVisible: status?.lifecycle.publiclyVisible ?? false,
225
244
  viewerIsOwner,
package/src/i18n/es.ts CHANGED
@@ -86,6 +86,7 @@ export const listingsI18nBundleEs: I18nDictionary = {
86
86
  "listings.detail.retry": "Reintentar",
87
87
  "listings.detail.not_found": "No hay ningún anuncio en esta dirección",
88
88
  "listings.detail.removed": "Este anuncio fue eliminado",
89
+ "listings.detail.withdrawn": "Este anuncio ya no está publicado",
89
90
  "listings.detail.not_published":
90
91
  "Este anuncio no está a la venta ahora, así que lo que ves puede estar desactualizado",
91
92
  "listings.detail.owner_only_view":
@@ -139,10 +140,13 @@ export const listingsI18nBundleEs: I18nDictionary = {
139
140
  "listings.compose.stock": "Cuántas unidades",
140
141
  "listings.compose.auto_republish": "Volver a publicar cuando caduque",
141
142
  "listings.compose.save": "Guardar borrador",
143
+ "listings.compose.save_live": "Apartar como borrador",
144
+ "listings.compose.saved_live":
145
+ "Cambios apartados como borrador — el anuncio publicado no cambió",
142
146
  "listings.compose.saving": "Guardando…",
143
147
  "listings.compose.saved": "Borrador guardado",
144
148
  "listings.compose.publish": "Publicar",
145
- "listings.compose.republish": "Enviar los cambios",
149
+ "listings.compose.republish": "Guardar los cambios",
146
150
  "listings.compose.publishing": "Enviando…",
147
151
  "listings.compose.published_first":
148
152
  "Enviado a revisión. Saldrá a la venta cuando un moderador lo apruebe.",
package/src/i18n/keys.ts CHANGED
@@ -94,6 +94,11 @@ export const LISTINGS_I18N_KEYS = {
94
94
  detailNotFound: "listings.detail.not_found",
95
95
  /** Soft-deleted: the status probe answers where the detail 404s. */
96
96
  detailRemoved: "listings.detail.removed",
97
+ /** Taken down on purpose (archived, not deleted): the detail 404s while
98
+ * the probe still answers and does NOT say "deleted". A different sentence
99
+ * from `detailRemoved`, and above all not the generic retry arm — a retry
100
+ * cannot help a row whose owner took it off the shelf. */
101
+ detailWithdrawn: "listings.detail.withdrawn",
97
102
  /** Readable by id, but not on the shelf — and the reader is not the owner. */
98
103
  detailNotPublished: "listings.detail.not_published",
99
104
  detailOwnerOnlyView: "listings.detail.owner_only_view",
@@ -143,6 +148,12 @@ export const LISTINGS_I18N_KEYS = {
143
148
  composeStock: "listings.compose.stock",
144
149
  composeAutoRepublish: "listings.compose.auto_republish",
145
150
  composeSave: "listings.compose.save",
151
+ /** The quiet exit ON A LIVE EDIT: parks the changes in the draft twin and
152
+ * leaves the published listing untouched (D33 — «Save draft» on a
153
+ * published listing read as the safe choice and silently shelved the
154
+ * seller's first round of edits). */
155
+ composeSaveLive: "listings.compose.save_live",
156
+ composeSavedLive: "listings.compose.saved_live",
146
157
  composeSaving: "listings.compose.saving",
147
158
  composeSaved: "listings.compose.saved",
148
159
  composePublish: "listings.compose.publish",
@@ -291,6 +302,7 @@ export const listingsI18nBundleEn: Record<string, string> = {
291
302
  "listings.detail.retry": "Try again",
292
303
  "listings.detail.not_found": "There is no listing at this address",
293
304
  "listings.detail.removed": "This listing was removed",
305
+ "listings.detail.withdrawn": "This listing is no longer published",
294
306
  "listings.detail.not_published":
295
307
  "This listing is not on sale right now, so what you see may be out of date",
296
308
  "listings.detail.owner_only_view":
@@ -344,10 +356,13 @@ export const listingsI18nBundleEn: Record<string, string> = {
344
356
  "listings.compose.stock": "How many",
345
357
  "listings.compose.auto_republish": "Re-publish automatically when it expires",
346
358
  "listings.compose.save": "Save draft",
359
+ "listings.compose.save_live": "Stash as draft",
360
+ "listings.compose.saved_live":
361
+ "Changes stashed as a draft — the published listing is unchanged",
347
362
  "listings.compose.saving": "Saving…",
348
363
  "listings.compose.saved": "Draft saved",
349
364
  "listings.compose.publish": "Publish",
350
- "listings.compose.republish": "Send changes",
365
+ "listings.compose.republish": "Save changes",
351
366
  "listings.compose.publishing": "Sending…",
352
367
  "listings.compose.published_first":
353
368
  "Sent for review. It goes on sale once a moderator approves it.",
package/src/i18n/ru.ts CHANGED
@@ -102,6 +102,7 @@ export const listingsI18nBundleRu: I18nDictionary = {
102
102
  "listings.detail.retry": "Повторить",
103
103
  "listings.detail.not_found": "По этому адресу объявления нет",
104
104
  "listings.detail.removed": "Это объявление удалено",
105
+ "listings.detail.withdrawn": "Объявление снято с публикации",
105
106
  "listings.detail.not_published":
106
107
  "Объявление сейчас не в продаже, и то, что вы видите, может быть неактуальным",
107
108
  "listings.detail.owner_only_view":
@@ -156,10 +157,13 @@ export const listingsI18nBundleRu: I18nDictionary = {
156
157
  "listings.compose.stock": "Сколько штук",
157
158
  "listings.compose.auto_republish": "Публиковать заново, когда истечёт срок",
158
159
  "listings.compose.save": "Сохранить черновик",
160
+ "listings.compose.save_live": "Отложить правки в черновик",
161
+ "listings.compose.saved_live":
162
+ "Правки отложены в черновик — опубликованное объявление не изменилось",
159
163
  "listings.compose.saving": "Сохраняем…",
160
164
  "listings.compose.saved": "Черновик сохранён",
161
165
  "listings.compose.publish": "Опубликовать",
162
- "listings.compose.republish": "Отправить правки",
166
+ "listings.compose.republish": "Сохранить изменения",
163
167
  "listings.compose.publishing": "Отправляем…",
164
168
  "listings.compose.published_first":
165
169
  "Отправлено на проверку. Объявление появится в продаже после одобрения модератора.",