@qratilabs/qrati-connect 2.24.2 → 2.25.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.
- package/README.md +86 -130
- package/element/{BP2rYgya2.js → BFCgbC5I2.js} +9 -9
- package/element/{BnZIocDu2.js → BV9JHI5n2.js} +41 -41
- package/element/{DkG0zv7_2.js → BccTn5v-2.js} +1 -1
- package/element/BxbojrJs.js +8 -0
- package/element/{Bh8kXbe92.js → C6dzWeQk2.js} +4 -4
- package/element/{C52SUIvC2.js → C7iuJ0h32.js} +8 -8
- package/element/{BM9ujORR2.js → C9T-_wQ82.js} +1 -1
- package/element/{BKDqpSN62.js → C9kBlCZx2.js} +3 -3
- package/element/{LYboLIEU.js → CJXPO3HP.js} +1 -1
- package/element/CMnzxWwG.js +9 -0
- package/element/{DN26AtHL2.js → CZbEGemi2.js} +3 -3
- package/element/{lcKuIs2T2.js → Ctl9NdWl2.js} +5 -9
- package/element/DCj_fMN5.js +5 -0
- package/element/DPg_DKOi.js +5 -0
- package/element/{CHTzn6mh2.js → DRP9vxts2.js} +3 -3
- package/element/{kiL9JENf2.js → DWjheKBP2.js} +1 -1
- package/element/{BOqkzZ92.js → EjMoIoSK.js} +1 -1
- package/element/ZYvo9BjF2.js +8 -0
- package/element/{Bow6F3212.js → iknPnbyg2.js} +14 -14
- package/element/{DdOwRfWG.js → iuooW4mt.js} +8 -9
- package/element/{mIANlVHi2.js → qQ9Xx6H32.js} +1 -1
- package/element/{CLdpUOLk2.js → rg8L51I62.js} +4 -4
- package/element/web.es.js +23 -24
- package/package.json +1 -1
- package/element/BDrHm_qM.js +0 -9
- package/element/BxErY-nv.js +0 -7
- package/element/CWhnvMey2.js +0 -8
- package/element/DWBbTgnB.js +0 -8
- /package/element/{CZ9iaxjO.js → CZ9iaxjO2.js} +0 -0
package/README.md
CHANGED
|
@@ -1,174 +1,130 @@
|
|
|
1
|
-
|
|
2
|
-
<img src="https://qrati.com/images/qrati-connect-banner.jpg" alt="Qrati Connect Banner" style="max-width:100%;height:auto;" />
|
|
3
|
-
</p>
|
|
1
|
+

|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+

|
|
12
|
+

|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# Qrati Connect — Embeddable Media & Engagement SDK
|
|
15
|
-
|
|
16
|
-
**Qrati Connect** is a compact, production-grade SDK for embedding photo galleries, media uploads, curation, and engagement into any website. It is built with [Preact](https://preactjs.com/), strict TypeScript, and Shadow-DOM style isolation, then distributed as a Web Component, React wrapper, and zero-code embed script.
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## Why Qrati Connect?
|
|
14
|
+
Qrati Connect is a drop-in, embeddable event/gallery widget. It ships as three friendly bundles:
|
|
21
15
|
|
|
22
|
-
-
|
|
23
|
-
- **
|
|
24
|
-
- **
|
|
25
|
-
- **Themeable** — organization colors, fonts, radius, and shadows are fetched from the Qrati API and applied via CSS custom properties.
|
|
26
|
-
- **TypeScript-first** — full typings for the public API.
|
|
16
|
+
- **`<qrati-connect>` Web Component** — shadow-DOM isolated, Preact-powered, ~3 KB.
|
|
17
|
+
- **React wrapper** — external React, lazy-loads the custom element.
|
|
18
|
+
- **Embed loader** — one `<script>` tag, no bundler needed.
|
|
27
19
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
## Highlights
|
|
31
|
-
|
|
32
|
-
- Interactive media gallery with lightbox, blurhash placeholders, infinite scroll, and facial search.
|
|
33
|
-
- Smart uploads: compression, chunked progress, video trimming, and HEIC → JPEG conversion on demand.
|
|
34
|
-
- Reactions, curation workflow, leaderboards, and points-based engagement.
|
|
35
|
-
- Public events page with folder navigation and optional map view (Google Maps, Mapbox, OpenStreetMap).
|
|
20
|
+
Styles self-inject at runtime, so hosts never import a stylesheet.
|
|
36
21
|
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Distribution Formats
|
|
40
22
|
|
|
41
|
-
|
|
42
|
-
|--------|--------|----------|
|
|
43
|
-
| **React wrapper** | `dist/react/index.mjs` / `index.cjs` | React / Next.js apps |
|
|
44
|
-
| **Web Component** | `dist/element/web.es.js` | Any framework or vanilla JS |
|
|
45
|
-
| **Embed loader** | `dist/embed/embed.js` | Zero-code `<script>` integration |
|
|
23
|
+
## Install
|
|
46
24
|
|
|
47
|
-
|
|
25
|
+
```bash
|
|
26
|
+
# contributors
|
|
27
|
+
pnpm install
|
|
48
28
|
|
|
49
|
-
|
|
29
|
+
# consumers
|
|
30
|
+
npm install @qratilabs/qrati-connect
|
|
31
|
+
```
|
|
50
32
|
|
|
51
|
-
|
|
33
|
+
> Requires **Node ≥24** and **pnpm ≥11**. See `.nvmrc` for the pinned Node version.
|
|
52
34
|
|
|
53
|
-
|
|
35
|
+
## Environment
|
|
54
36
|
|
|
55
37
|
```bash
|
|
56
|
-
|
|
57
|
-
# or
|
|
58
|
-
npm install @qratilabs/qrati-connect
|
|
38
|
+
cp .env.example .env.local
|
|
59
39
|
```
|
|
60
40
|
|
|
61
|
-
|
|
62
|
-
'use client';
|
|
41
|
+
Set at least:
|
|
63
42
|
|
|
64
|
-
|
|
43
|
+
- `VITE_BASE_URL` — API base, e.g. `https://api.qrati.com`
|
|
44
|
+
- `VITE_APP_ENVIRONMENT` — e.g. `alpha`, `beta`, `prod`
|
|
65
45
|
|
|
66
|
-
|
|
67
|
-
return <QratiConnect organizationId='your-org-id' router='memory' />;
|
|
68
|
-
}
|
|
69
|
-
```
|
|
46
|
+
## Develop
|
|
70
47
|
|
|
71
|
-
|
|
48
|
+
No separate dev server, but you have options:
|
|
72
49
|
|
|
73
|
-
```
|
|
74
|
-
|
|
50
|
+
```bash
|
|
51
|
+
# Component workbench
|
|
52
|
+
pnpm storybook
|
|
75
53
|
|
|
76
|
-
|
|
54
|
+
# Iterate on the standalone element
|
|
55
|
+
pnpm build:element:watch
|
|
56
|
+
pnpm serve:element # http://localhost:4599
|
|
77
57
|
```
|
|
78
58
|
|
|
79
|
-
|
|
59
|
+
## Test
|
|
80
60
|
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
data-router="hash"></script>
|
|
61
|
+
```bash
|
|
62
|
+
pnpm test:unit:run # Vitest + jsdom
|
|
63
|
+
pnpm test:production # Playwright against a live env
|
|
64
|
+
pnpm test:all # unit + production
|
|
86
65
|
```
|
|
87
66
|
|
|
88
|
-
|
|
67
|
+
## Build
|
|
89
68
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
| `organizationId` * | `string` | — | Qrati organization ID |
|
|
97
|
-
| `router` | `'memory' \| 'hash'` | `'memory'` | Routing strategy |
|
|
98
|
-
| `uid` | `string` | — | Pre-authenticated user ID |
|
|
99
|
-
| `fname` | `string` | — | Pre-authenticated first name |
|
|
100
|
-
| `lname` | `string` | — | Pre-authenticated last name |
|
|
101
|
-
| `theme` | `'light' \| 'dark'` | `'light'` | Color scheme |
|
|
102
|
-
| `onError` | `(error: Error) => void` | — | SDK error callback |
|
|
69
|
+
```bash
|
|
70
|
+
pnpm build # all three bundles + post-build validation
|
|
71
|
+
pnpm build:element # dist/element/web.es.js
|
|
72
|
+
pnpm build:react # dist/react/index.{mjs,cjs,d.ts}
|
|
73
|
+
pnpm build:embed # dist/embed/embed.js
|
|
74
|
+
```
|
|
103
75
|
|
|
104
|
-
|
|
76
|
+
`build:react` automatically builds the element first because the React wrapper loads `../element/web.es.js` at runtime.
|
|
105
77
|
|
|
106
|
-
|
|
78
|
+
## Use it
|
|
107
79
|
|
|
108
|
-
|
|
80
|
+
### React
|
|
109
81
|
|
|
110
|
-
|
|
82
|
+
```tsx
|
|
83
|
+
import { QratiConnect } from '@qratilabs/qrati-connect';
|
|
111
84
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
85
|
+
<QratiConnect
|
|
86
|
+
organizationId="your-org-id"
|
|
87
|
+
router="hash"
|
|
88
|
+
theme="light"
|
|
89
|
+
onError={(err) => console.error(err)}
|
|
90
|
+
/>
|
|
91
|
+
```
|
|
116
92
|
|
|
117
|
-
|
|
93
|
+
### Script tag
|
|
118
94
|
|
|
119
|
-
|
|
95
|
+
```html
|
|
96
|
+
<script
|
|
97
|
+
async
|
|
98
|
+
src="https://cdn.jsdelivr.net/npm/@qratilabs/qrati-connect/embed/embed.js"
|
|
99
|
+
data-organization-id="your-org-id"
|
|
100
|
+
data-router="hash"
|
|
101
|
+
data-theme="light"
|
|
102
|
+
></script>
|
|
103
|
+
```
|
|
120
104
|
|
|
121
|
-
|
|
105
|
+
Use a **classic** `<script>` tag — not `type="module"` — so the loader can read `document.currentScript`.
|
|
122
106
|
|
|
123
|
-
|
|
107
|
+
### Web Component (programmatic)
|
|
124
108
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
- Upload feature: loaded on demand.
|
|
128
|
-
- HEIC conversion (`heic2any`): loaded only when a `.heic` file is selected.
|
|
129
|
-
- Maps and heavy UI libraries are split into lazy chunks.
|
|
109
|
+
```ts
|
|
110
|
+
import { renderComponent } from '@qratilabs/qrati-connect/element';
|
|
130
111
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
112
|
+
renderComponent('#qrati-host', {
|
|
113
|
+
organizationId: 'your-org-id',
|
|
114
|
+
router: 'memory',
|
|
115
|
+
theme: 'dark'
|
|
116
|
+
});
|
|
117
|
+
```
|
|
134
118
|
|
|
135
|
-
|
|
119
|
+
## Deploy
|
|
136
120
|
|
|
137
121
|
```bash
|
|
138
|
-
pnpm
|
|
139
|
-
pnpm
|
|
140
|
-
pnpm type-check # TypeScript check (no emit)
|
|
141
|
-
pnpm lint # ESLint
|
|
142
|
-
pnpm format # Prettier
|
|
143
|
-
pnpm build # build all distribution targets
|
|
144
|
-
pnpm test:unit # Vitest unit tests (watch)
|
|
145
|
-
pnpm test:unit:run # Vitest unit tests (once)
|
|
146
|
-
pnpm test:all # unit tests + Playwright production regression
|
|
122
|
+
pnpm deploy:beta # merge main into release/beta and push
|
|
123
|
+
pnpm deploy:prod # merge main into release/prod and push
|
|
147
124
|
```
|
|
148
125
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
## Documentation
|
|
154
|
-
|
|
155
|
-
- [`docs/INDEX.md`](docs/INDEX.md) — documentation map
|
|
156
|
-
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — architecture, build system, routing, styling, i18n
|
|
157
|
-
- [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md) — environment setup, workflow, testing, Storybook
|
|
158
|
-
- [`docs/API.md`](docs/API.md) — backend API communication
|
|
159
|
-
- [`docs/REFERENCE.md`](docs/REFERENCE.md) — components, hooks, pages, utilities, router API
|
|
160
|
-
- [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md) — release process and CDN
|
|
161
|
-
- [`docs/FAQ.md`](docs/FAQ.md) — common questions
|
|
126
|
+
Both scripts require a clean git working tree. After pushing, semantic-release publishes from `dist/` when CI runs on the release branch.
|
|
162
127
|
|
|
163
128
|
---
|
|
164
129
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
- GitHub Issues: https://github.com/qrati-labs/qrati-connect-ts/issues
|
|
168
|
-
- Email: support@qrati.com
|
|
169
|
-
|
|
170
|
-
---
|
|
171
|
-
|
|
172
|
-
## License
|
|
173
|
-
|
|
174
|
-
Proprietary © Qrati Labs — https://qrati.com. All rights reserved.
|
|
130
|
+
Built with Preact, Vite, Tailwind, and a little bit of Shadow DOM magic.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import{_ as e,f as t,h as a,p as n,t as r,w as o}from"./DrrpB4Om.js";import{L as s,N as i,O as l,i as c,n as d,p as m,u}from"./CaX2xgrP.js";import{n as p,r as h,t as g}from"./C12iSy3L.js";import{n as f,r as v,t as x}from"./dT6WSX65.js";import{c as N,l as y}from"./ChJXhA9c.js";import{t as w}from"./CATr-3VW.js";import{t as b}from"./DF0LxcV7.js";import{t as T}from"./DGbyGc8b.js";import{t as
|
|
1
|
+
import{_ as e,f as t,h as a,p as n,t as r,w as o}from"./DrrpB4Om.js";import{L as s,N as i,O as l,i as c,n as d,p as m,u}from"./CaX2xgrP.js";import{n as p,r as h,t as g}from"./C12iSy3L.js";import{n as f,r as v,t as x}from"./dT6WSX65.js";import{c as N,l as y}from"./ChJXhA9c.js";import{t as w}from"./CATr-3VW.js";import{t as b}from"./DF0LxcV7.js";import{t as T}from"./DGbyGc8b.js";import{n as D,r as P,t as C}from"./EjMoIoSK.js";import{t as j}from"./DnQ6XaLR.js";import{t as I}from"./C3dOFk9A.js";import{t as E}from"./DPg_DKOi.js";import{n as S,o as z,r as A,t as U}from"./DZtaQWVG2.js";import{t as q}from"./N4HKgEC52.js";import{i as _,n as k,r as O,t as M}from"./Ctl9NdWl2.js";var $=({content:e,onDeleted:t,onClose:a})=>{const n=function(){const e=s(),{user:t,props:a}=d(),n=a?.organizationId,r=t?.token;return v({mutationKey:["delete-upload",r??null],mutationFn:async({contentId:e})=>{const t=await i.post(u.DELETE_CONTENT,{json:{contentId:e},headers:{"x-org-id":n,...r?{Authorization:`Bearer ${r}`}:{}}}).json();if(t?.error)throw new Error(t.error);return{contentId:e}},onMutate:async({contentId:t})=>{await e.cancelQueries({queryKey:[l.USER_UPLOADS],exact:!1});const a=e.getQueriesData({queryKey:[l.USER_UPLOADS],exact:!1});return e.setQueriesData({queryKey:[l.USER_UPLOADS],exact:!1},e=>e?.pages?{...e,pages:e.pages.map(e=>({...e,data:e.data.filter(e=>e._id!==t),meta:{...e.meta,totalCount:Math.max(0,(e.meta.totalCount??0)-1)}}))}:e),{previousData:a}},onError:(t,a,n)=>{n?.previousData?.forEach(([t,a])=>{e.setQueryData(t,a)})}})}(),o=e?.rateCount??0,c=o<=0,m=c?null:`This photo has ${o} rating${o>1?"s":""}. Photos with at least 1 rating cannot be deleted.`;/* @__PURE__ */
|
|
2
2
|
return r(O,{open:Boolean(e),onOpenChange:e=>{e||a()},title:"Delete content?",description:m??"Are you sure you want to delete this content? This operation is permanent and cannot be undone.",cancelText:"Cancel",confirmText:c?"Delete":"Got it",confirmColor:c?"error":"primary",onCancel:a,onConfirm:c?()=>{if(!e||!c)return;const a=e.eventId,r=e._id;t(),n.mutate({contentId:r,eventId:a})}:a})};function L({className:e}){/* @__PURE__ */
|
|
3
|
-
return r("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",className:e,"aria-hidden":"true",focusable:"false",children:/* @__PURE__ */r("path",{fill:"currentColor",d:"M7 21q-.825 0-1.412-.587T5 19V6q-.425 0-.712-.288T4 5t.288-.712T5 4h4q0-.425.288-.712T10 3h4q.425 0 .713.288T15 4h4q.425 0 .713.288T20 5t-.288.713T19 6v13q0 .825-.587 1.413T17 21zM17 6H7v13h10zm-7 11q.425 0 .713-.288T11 16V9q0-.425-.288-.712T10 8t-.712.288T9 9v7q0 .425.288.713T10 17m4 0q.425 0 .713-.288T15 16V9q0-.425-.288-.712T14 8t-.712.288T13 9v7q0 .425.288.713T14 17M7 6v13z"})})}var R={[m.APPROVED]:{color:"text-success",bgColor:"bg-success/20",icon:/* @__PURE__ */r(
|
|
3
|
+
return r("svg",{xmlns:"http://www.w3.org/2000/svg",width:"1em",height:"1em",viewBox:"0 0 24 24",className:e,"aria-hidden":"true",focusable:"false",children:/* @__PURE__ */r("path",{fill:"currentColor",d:"M7 21q-.825 0-1.412-.587T5 19V6q-.425 0-.712-.288T4 5t.288-.712T5 4h4q0-.425.288-.712T10 3h4q.425 0 .713.288T15 4h4q.425 0 .713.288T20 5t-.288.713T19 6v13q0 .825-.587 1.413T17 21zM17 6H7v13h10zm-7 11q.425 0 .713-.288T11 16V9q0-.425-.288-.712T10 8t-.712.288T9 9v7q0 .425.288.713T10 17m4 0q.425 0 .713-.288T15 16V9q0-.425-.288-.712T14 8t-.712.288T13 9v7q0 .425.288.713T14 17M7 6v13z"})})}var R={[m.APPROVED]:{color:"text-success",bgColor:"bg-success/20",icon:/* @__PURE__ */r(M,{className:"size-full"}),title:"Approved",description:"Your upload has been approved and is now visible to everyone viewing this event."},[m.IN_REVIEW]:{color:"text-warning",bgColor:"bg-warning/20",icon:/* @__PURE__ */r(_,{className:"size-full"}),title:"In Review",description:"Your upload is currently being reviewed. It will be visible once approved by the event admin."},[m.REJECTED]:{color:"text-destructive",bgColor:"bg-destructive/20",icon:/* @__PURE__ */r(q,{className:"size-full"}),title:"Rejected",description:"Your upload was not approved as it may not meet the content guidelines. Please upload appropriate content."}},F=e=>{const t=new Date(e).getTime();if(Number.isNaN(t))return"";const a=Math.max(0,Math.floor((Date.now()-t)/1e3)),n=[[60,"second"],[60,"minute"],[24,"hour"],[30,"day"],[12,"month"],[Number.POSITIVE_INFINITY,"year"]];let r=a,o="second";for(const[s,i]of n){if(r<s){o=i;break}r=Math.floor(r/s),o=i}return"second"===o&&r<30?"just now":`${r} ${o}${1===r?"":"s"} ago`},V=({content:e,onDelete:t,onStatusClick:a})=>{const n=e.status,o=R[n];/* @__PURE__ */
|
|
4
4
|
return r("div",{className:"group relative size-full overflow-hidden sm:rounded",children:/* @__PURE__ */r("div",{className:"relative size-full",children:[
|
|
5
|
-
/* @__PURE__ */r(
|
|
6
|
-
/* @__PURE__ */r("div",{className:"pointer-events-none absolute inset-x-0 bottom-0 flex items-center justify-between bg-gradient-to-t from-black/50 to-transparent pl-3",children:[/* @__PURE__ */r(w,{variant:"caption",className:"text-xs text-white opacity-90 sm:text-sm",children:F(e.createdAt)}),/* @__PURE__ */r(
|
|
7
|
-
/* @__PURE__ */r("button",{type:"button","aria-label":`Status: ${o?.title||"Unknown"}`,onClick:e=>{e.stopPropagation(),e.preventDefault(),a(n)},className:c("pointer-events-auto absolute top-1 right-1 cursor-pointer rounded-full p-1 transition-opacity hover:opacity-80",o?.bgColor||"bg-gray-500/20"),children:/* @__PURE__ */r("span",{className:c("block size-5",o?.color||"text-gray-500"),children:o?.icon||null})})]})})},B=e=>new Date(e).toLocaleDateString("en-US",{month:"short",year:"numeric"}),K=e=>{if(0===e.length)return"";if(1===e.length)return B(e[0].createdAt);const{minTime:t,maxTime:a}=e.reduce((e,t)=>{const a=new Date(t.createdAt).getTime();return{minTime:Math.min(e.minTime,a),maxTime:Math.max(e.maxTime,a)}},{minTime:1/0,maxTime:-1/0}),n=B(new Date(t).toISOString()),r=B(new Date(a).toISOString());return n===r?n:`${n} - ${r}`},Y=()=>{const s=y(),m=N(),{user:v,loadingUser:
|
|
5
|
+
/* @__PURE__ */r(P,{url:e.url||"",alt:e.caption||"",thumbnailUrl:e.thumbnailUrl||void 0,blurhash:e.blurhash||void 0,pswpData:{id:e._id,type:e.type,hash:e._id,width:e.dimension?.width,height:e.dimension?.height,thumbnailUrl:e.thumbnailUrl||void 0,caption:e.caption||""}}),
|
|
6
|
+
/* @__PURE__ */r("div",{className:"pointer-events-none absolute inset-x-0 bottom-0 flex items-center justify-between bg-gradient-to-t from-black/50 to-transparent pl-3",children:[/* @__PURE__ */r(w,{variant:"caption",className:"text-xs text-white opacity-90 sm:text-sm",children:F(e.createdAt)}),/* @__PURE__ */r(k,{icon:/* @__PURE__ */r(L,{className:"size-5"}),color:"error",size:"sm",className:"pointer-events-auto","aria-label":"Delete upload",tooltip:"Delete",onClick:e=>{e.stopPropagation(),e.preventDefault(),t()}})]}),
|
|
7
|
+
/* @__PURE__ */r("button",{type:"button","aria-label":`Status: ${o?.title||"Unknown"}`,onClick:e=>{e.stopPropagation(),e.preventDefault(),a(n)},className:c("pointer-events-auto absolute top-1 right-1 cursor-pointer rounded-full p-1 transition-opacity hover:opacity-80",o?.bgColor||"bg-gray-500/20"),children:/* @__PURE__ */r("span",{className:c("block size-5",o?.color||"text-gray-500"),children:o?.icon||null})})]})})},B=e=>new Date(e).toLocaleDateString("en-US",{month:"short",year:"numeric"}),K=e=>{if(0===e.length)return"";if(1===e.length)return B(e[0].createdAt);const{minTime:t,maxTime:a}=e.reduce((e,t)=>{const a=new Date(t.createdAt).getTime();return{minTime:Math.min(e.minTime,a),maxTime:Math.max(e.maxTime,a)}},{minTime:1/0,maxTime:-1/0}),n=B(new Date(t).toISOString()),r=B(new Date(a).toISOString());return n===r?n:`${n} - ${r}`},Y=()=>{const s=y(),m=N(),{user:v,loadingUser:P,portalContainer:q}=d(),_=t(null),k=t(null),O=t(null),[M,L]=a(null),[F,B]=a(null),{contents:Y,loading:Q,hasNextPage:G,fetchNextPage:J,isFetchingNextPage:H}=function({sort:e="-createdAt",limit:t=20}={}){const{user:a,loadingUser:r,props:o}=d(),s=o?.organizationId,c=a?.token,m=a?._id??a?.uid??null,{data:f,isLoading:v,isError:x,error:N,isFetchingNextPage:y,hasNextPage:w,fetchNextPage:b,refetch:T}=h({queryKey:[l.USER_UPLOADS,s??"",m,t,e],queryFn:async({pageParam:a=1})=>await i.get(u.MY_UPLOADS,{searchParams:{page:a,limit:t,sort:e},headers:{"x-org-id":s,...c?{Authorization:`Bearer ${c}`}:{}}}).json(),initialPageParam:1,getPreviousPageParam:p,getNextPageParam:g,staleTime:12e4,gcTime:3e5,enabled:!r&&!!a});return{contents:n(()=>f?.pages?.flatMap(e=>e?.data??[])??[],[f]),loading:v,isError:x,error:N,isFetchingNextPage:y,hasNextPage:!!w,fetchNextPage:b,refetch:T,totalCount:f?.pages?.[0]?.meta?.totalCount??0}}({sort:"-createdAt",limit:20});e(()=>{P||v||s("/auth/login",{state:{referrer:m.pathname},replace:!0})},[P,v]);const W=Y.length>0,Z=!Q&&!W,X=n(()=>{if(!Y.length)return[];const e={};return Y.forEach(t=>{const a=t.eventId||"unknown";e[a]||(e[a]={eventId:a,eventName:t.event?.name||"Event",uploads:[]}),e[a].uploads.push(t)}),Object.values(e).sort((e,t)=>{const a=new Date(e.uploads[0]?.createdAt||0).getTime();return new Date(t.uploads[0]?.createdAt||0).getTime()-a})},[Y]);e(()=>{const e=k.current;if(!e)return;const t=new D({gallery:e,children:"a",counter:!1,bgOpacity:1,wheelToZoom:!0,pinchToClose:!0,zoom:!1,pswpModule:C,appendToEl:q??document.body});return _.current=t,new x(t),new f(t),t.init(),()=>{t.destroy(),_.current=null}},[q,W]),e(()=>{const e=O.current;if(!e||!G)return;const t=new IntersectionObserver(e=>{e[0]?.isIntersecting&&G&&!H&&J()},{rootMargin:"200px"});return t.observe(e),()=>t.disconnect()},[G,H,J]);const ee=n(()=>Y.find(e=>e._id===M)??null,[M,Y]),te=F?R[F]:null;/* @__PURE__ */
|
|
8
8
|
return r("div",{className:"bg-background mx-auto min-h-screen max-w-5xl px-3 pt-16 pb-12 lg:px-0",children:[
|
|
9
|
-
/* @__PURE__ */r("div",{className:"relative mb-6 flex items-center justify-center",children:[/* @__PURE__ */r(
|
|
9
|
+
/* @__PURE__ */r("div",{className:"relative mb-6 flex items-center justify-center",children:[/* @__PURE__ */r(j,{}),/* @__PURE__ */r(w,{variant:"h4",align:"center",children:"My Uploads"})]}),
|
|
10
10
|
/* @__PURE__ */r("section",{className:"space-y-3",children:Q?/* @__PURE__ */r("div",{className:"space-y-8 py-4",children:Array.from({length:2}).map((e,t)=>/* @__PURE__ */r("div",{className:"space-y-4",children:[/* @__PURE__ */r("div",{className:"flex items-center justify-between",children:[/* @__PURE__ */r(T,{className:"h-6 w-48"}),/* @__PURE__ */r(T,{className:"h-5 w-24"})]}),/* @__PURE__ */r("div",{className:"grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-4",children:Array.from({length:4}).map((e,t)=>/* @__PURE__ */r(T,{className:"h-52 w-full lg:h-64"},t))})]},t))}):Z?/* @__PURE__ */r(b,{className:"py-12",title:"No uploads yet",description:"Photos and videos you upload to events will appear here."}):/* @__PURE__ */r(o,{children:[
|
|
11
|
-
/* @__PURE__ */r("div",{ref:
|
|
12
|
-
/* @__PURE__ */r("div",{ref:O,className:"h-px w-full"}),
|
|
11
|
+
/* @__PURE__ */r("div",{ref:k,className:"space-y-8 py-4",children:X.map(e=>/* @__PURE__ */r("div",{className:"space-y-4",children:[/* @__PURE__ */r("div",{className:"flex items-center justify-between",children:[/* @__PURE__ */r(w,{variant:"h5",color:"muted",children:e.eventName}),/* @__PURE__ */r("span",{className:"text-muted-foreground text-sm font-light uppercase sm:text-base",children:K(e.uploads)})]}),/* @__PURE__ */r("div",{className:"grid grid-cols-2 gap-1 sm:grid-cols-3 sm:gap-3 lg:grid-cols-4",children:e.uploads.map(e=>/* @__PURE__ */r("div",{className:"h-52 lg:h-64",children:/* @__PURE__ */r(V,{content:e,onDelete:()=>L(e._id),onStatusClick:e=>B(e)})},e._id))})]},e.eventId))}),
|
|
12
|
+
/* @__PURE__ */r("div",{ref:O,className:"h-px w-full"}),H&&/* @__PURE__ */r("div",{className:"my-6 w-full",children:/* @__PURE__ */r(E,{})})]})}),
|
|
13
13
|
/* @__PURE__ */r($,{content:ee,onClose:()=>L(null),onDeleted:()=>L(null)}),
|
|
14
|
-
/* @__PURE__ */r(
|
|
14
|
+
/* @__PURE__ */r(U,{open:Boolean(F),onOpenChange:e=>!e&&B(null),children:/* @__PURE__ */r(S,{className:"w-full max-w-lg",children:[/* @__PURE__ */r("div",{className:"flex flex-col gap-4 p-2 sm:flex-row sm:items-start sm:p-4",children:[/* @__PURE__ */r("div",{className:c("mx-auto flex size-12 shrink-0 items-center justify-center rounded-full sm:mx-0 sm:size-10",te?.bgColor||"bg-gray-500/20"),children:/* @__PURE__ */r("span",{className:c("size-6",te?.color||"text-gray-500"),children:te?.icon||null})}),/* @__PURE__ */r("div",{className:"flex-1 space-y-2 text-center sm:text-left",children:[/* @__PURE__ */r(z,{children:te?.title||"Unknown Status"}),/* @__PURE__ */r(A,{children:te?.description||"Status information unavailable."})]})]}),/* @__PURE__ */r("div",{className:"flex justify-end p-4",children:/* @__PURE__ */r(I,{variant:"outlined",color:"foreground",onClick:()=>B(null),children:"Got it"})})]})})]})};export{Y as default};
|