MCPcopy
hub / github.com/koala73/worldmonitor / render

Method render

src/components/TechEventsPanel.ts:67–123  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

65 }
66
67 protected render(): void {
68 if (this.loading) {
69 replaceChildren(this.content,
70 h('div', { className: 'tech-events-loading' },
71 h('div', { className: 'loading-spinner' }),
72 h('span', null, t('components.techEvents.loading')),
73 ),
74 );
75 return;
76 }
77
78 if (this.error) {
79 replaceChildren(this.content,
80 h('div', { className: 'tech-events-error' },
81 h('span', { className: 'error-icon' }, '⚠️'),
82 h('span', { className: 'error-text' }, this.error),
83 h('button', { className: 'retry-btn', onClick: () => this.refresh() }, t('common.retry')),
84 ),
85 );
86 return;
87 }
88
89 const filteredEvents = this.getFilteredEvents();
90 const upcomingConferences = this.events.filter(e => e.type === 'conference' && new Date(e.startDate) >= new Date());
91 const mappableCount = upcomingConferences.filter(e => e.coords && !e.coords.virtual).length;
92
93 const tabEntries: [ViewMode, string][] = [
94 ['upcoming', t('components.techEvents.upcoming')],
95 ['conferences', t('components.techEvents.conferences')],
96 ['earnings', t('components.techEvents.earnings')],
97 ['all', t('components.techEvents.all')],
98 ];
99
100 replaceChildren(this.content,
101 h('div', { className: 'tech-events-panel' },
102 h('div', { className: 'tech-events-tabs' },
103 ...tabEntries.map(([view, label]) =>
104 h('button', {
105 className: `tab ${this.viewMode === view ? 'active' : ''}`,
106 dataset: { view },
107 onClick: () => { this.viewMode = view; this.render(); },
108 }, label),
109 ),
110 ),
111 h('div', { className: 'tech-events-stats' },
112 h('span', { className: 'stat' }, `📅 ${t('components.techEvents.conferencesCount', { count: String(upcomingConferences.length) })}`),
113 h('span', { className: 'stat' }, `📍 ${t('components.techEvents.onMap', { count: String(mappableCount) })}`),
114 h('a', { href: 'https://www.techmeme.com/events', target: '_blank', rel: 'noopener', className: 'source-link' }, t('components.techEvents.techmemeEvents')),
115 ),
116 h('div', { className: 'tech-events-list' },
117 ...(filteredEvents.length > 0
118 ? filteredEvents.map(e => this.buildEvent(e))
119 : [h('div', { className: 'empty-state' }, t('components.techEvents.noEvents'))]),
120 ),
121 ),
122 );
123 }
124

Callers 1

fetchEventsMethod · 0.95

Calls 6

refreshMethod · 0.95
getFilteredEventsMethod · 0.95
buildEventMethod · 0.95
replaceChildrenFunction · 0.90
hFunction · 0.90
tFunction · 0.90

Tested by

no test coverage detected