PageSourceSearch

https://www.digischolars.com/n/websiteV3/webinarlistV3.js

js digischolars.com collected 2026-10-01 15:18:42 UTC 5,262 bytes, 188 lines download raw bytes

1const isPreview = (typeof isPreviewMode === 'function') ? isPreviewMode() : false;
2const currentOrg = getCurrentOrg();
3
4document.addEventListener("alpine:init", () => {
5  Alpine.data("webinarListData", () => ({
6    webinars: [],
7    page: 0,
8    limit: 6,
9    total: 0,
10    loading: false,
11    hasMore: true,
12    observer: null,
13    activeTab: "upcoming",
14    upcomingCount: 0,
15    pastCount: 0,
16    allCount: 0,
17    orgId: "",
18
19    async init() {
20      await this.fetchTotals();
21
22      // Set up observer FIRST
23      this.observer = new IntersectionObserver(
24        (entries) => {
25          entries.forEach((entry) => {
26            if (entry.isIntersecting && this.hasMore && !this.loading) {
27              this.fetchWebinars();
28            }
29          });
30        },
31        { threshold: 0.1 }
32      );
33
34      // Then fetch initial data
35      await this.fetchWebinars();
36
37      // Observe after DOM is ready
38      this.$nextTick(() => {
39        if (this.$refs.loadMore) {
40          this.observer.observe(this.$refs.loadMore);
41        }
42      });
43
44      window.webinarListData = this;
45    },
46
47    // Fetch counts
48    async fetchTotals() {
49      try {
50        const authToken = localStorage.getItem("microserviceAuthToken");
51        const headers = {};
52        if (authToken) {
53          headers["Authorization"] = authToken;
54        }
55
56        const res = await fetch(
57          `/t/api/content/public/livesession/totals?orgId=${currentOrg._id}`,
58          { headers }
59        );
60        const json = await res.json();
61        this.upcomingCount = json?.upcoming || 0;
62        this.pastCount = json?.past || 0;
63        this.allCount = json?.all || 0;
64      } catch (e) {
65        console.error(e);
66      }
67    },
68
69    // Switch tab
70    switchTab(tab) {
71      if (this.activeTab === tab) {
72        return;
73      }
74
75      if (this.observer && this.$refs.loadMore) {
76        this.observer.unobserve(this.$refs.loadMore);
77      }
78
79      this.activeTab = tab;
80      this.page = 0;
81      this.webinars = [];
82      this.hasMore = true;
83      this.total = 0;
84      this.fetchWebinars();
85      this.$nextTick(() => {
86        if (this.$refs.loadMore && this.observer) {
87          this.observer.observe(this.$refs.loadMore);
88        }
89      });
90    },
91
92    // Fetch webinars
93    async fetchWebinars() {
94      if (this.loading || !this.hasMore) {
95        return;
96      }
97
98      this.loading = true;
99
100      try {
101        let filters = {};
102        if (this.activeTab === "upcoming") {
103          filters = { pastSessions: [{ operator: "EQUALS", value: false }] };
104        } else if (this.activeTab === "past") {
105          filters = { pastSessions: [{ operator: "EQUALS", value: true }] };
106        }
107
108        const sortOrder = this.activeTab === "upcoming" ? "ascend" : "descend";
109
110        const body = {
111          orgId: this.orgId,
112          scroll: true,
113          p: this.page,
114          s: this.limit,
115          query: "",
116          filters,
117          sort: {
118            field: "startTime",
119            order: sortOrder
120          },
121          timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone
122        };
123
124        // Add auth token if available
125        const authToken = localStorage.getItem("microserviceAuthToken");
126        const headers = {
127          "Content-Type": "application/json"
128        };
129        if (authToken) {
130          headers["Authorization"] = authToken;
131        }
132
133        const res = await fetch(
134          `/t/api/content/public/livesession/get/all?orgId=${currentOrg._id}`,
135          {
136            method: "POST",
137            headers,
138            body: JSON.stringify(body)
139          }
140        );
141
142        const json = await res.json();
143
144        const items = json?.data?.length
145          ? json.data
146          : (this.page === 0 && isPreview)
147            ? getMockProducts()?.webinars ?? []
148            : [];
149
150        this.total = json?.total || items.length;
151
152        const mapped = items.map((w, index) => {
153          const badge = getWebinarStatusBadge(w);
154          const v = createVariableResolver(isVariableMode(), 'webinar');
155          return {
156            id: w.id,
157            uniqueKey: `${w.id}-${this.activeTab}-${this.page}-${index}`,
158            title: v('title', w.title),
159            coverUrl: isPreview && w.image_url ? w.image_url : getCoverImageUrl(w.coverPath),
160            dateTime: v('dateTime', webinarUtils.getFormattedDateTime(w.startTime, w.endTime)),
161            price: v('displayPrice', formatPrice(w.isPaid, w.price, w.currency)),
162            actionText: v('actionText', getWebinarActionButtonText(w)),
163            statusBadgeText: badge.statusBadgeText,
164            statusBadgeBg: badge.statusBadgeBg,
165            isLive: badge.isLive,
166            sessionUrl: isPreview ? 'javascript:void(0)' : `/sessions/${w.sessionUrl}`, 
167            raw: w
168          };
169        });
170
171        this.webinars.push(...mapped);
172
173        // FIX: Better hasMore logic with fallback
174        this.hasMore = typeof json?.hasMore === 'boolean' 
175          ? json.hasMore 
176          : (items.length >= this.limit && this.webinars.length < (this.total || Infinity));
177
178        this.page++;
179
180      } catch (e) {
181        console.error(e);
182        this.hasMore = false;
183      } finally {
184        this.loading = false;
185      }
186    }
187  }));
188});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.