@@ -19,6 +19,7 @@ export default async function Admin() {
1919 < h1 > Admin Panel</ h1 >
2020 < Dashboard />
2121 < Users />
22+ < EmailUsers />
2223 </ section >
2324 ) ;
2425}
@@ -194,3 +195,90 @@ async function deleteUser(id) {
194195 alert ( 'Success' , 'User deleted successfully' ) ;
195196 }
196197}
198+
199+ function EmailUsers ( ) {
200+ const recipientCount = Reactive ( 0 ) ;
201+ const sendBtn = Ref ( ) ;
202+ let filter = 'all' ;
203+ let subject = '' ;
204+ let message = '' ;
205+
206+ const fetchCount = async ( selectedFilter ) => {
207+ const res = await fetch ( `api/admin/email-recipients-count?filter=${ selectedFilter } ` ) ;
208+ const json = await res . json ( ) ;
209+ recipientCount . value = json . count ;
210+ } ;
211+
212+ fetchCount ( filter ) ;
213+
214+ const onFilterChange = ( e ) => {
215+ filter = e . target . value ;
216+ fetchCount ( filter ) ;
217+ } ;
218+
219+ const onSend = async ( ) => {
220+ if ( ! subject . trim ( ) || ! message . trim ( ) ) {
221+ alert ( 'ERROR' , 'Subject and message are required' ) ;
222+ return ;
223+ }
224+ const confirmation = await confirm ( 'Confirm' , `Send email to ${ recipientCount . value } recipient(s)?` ) ;
225+ if ( ! confirmation ) return ;
226+ sendBtn . disabled = true ;
227+ sendBtn . textContent = 'Sending...' ;
228+ try {
229+ const res = await fetch ( 'api/admin/send-email' , {
230+ method : 'POST' ,
231+ headers : { 'Content-Type' : 'application/json' } ,
232+ body : JSON . stringify ( { filter, subject, message } ) ,
233+ } ) ;
234+ const json = await res . json ( ) ;
235+ if ( json . error ) {
236+ alert ( 'ERROR' , json . error ) ;
237+ } else {
238+ alert ( 'Success' , `Email sent to ${ json . sent } user(s)` ) ;
239+ }
240+ } catch {
241+ alert ( 'ERROR' , 'Failed to send emails' ) ;
242+ } finally {
243+ sendBtn . disabled = false ;
244+ sendBtn . textContent = 'Send Email' ;
245+ }
246+ } ;
247+
248+ return (
249+ < div className = 'email-users' >
250+ < h2 > Email Users</ h2 >
251+ < div className = 'email-form' >
252+ < div className = 'form-group' >
253+ < label > Recipients</ label >
254+ < select onchange = { onFilterChange } >
255+ < option value = 'all' > All Users</ option >
256+ < option value = 'with_plugins' > Users with Plugins</ option >
257+ < option value = 'with_paid_plugins' > Users with Paid Plugins</ option >
258+ < option value = 'with_payment' > Users who Received Payment</ option >
259+ </ select >
260+ < small > { recipientCount } recipient(s) will receive this email</ small >
261+ </ div >
262+ < Input
263+ label = 'Subject'
264+ placeholder = 'Email subject'
265+ oninput = { ( e ) => {
266+ subject = e . target . value ;
267+ } }
268+ />
269+ < div className = 'form-group' >
270+ < label > Message</ label >
271+ < textarea
272+ placeholder = 'Email message...'
273+ oninput = { ( e ) => {
274+ message = e . target . value ;
275+ } }
276+ />
277+ </ div >
278+ < button ref = { sendBtn } type = 'button' onclick = { onSend } className = 'send-btn' >
279+ Send Email
280+ </ button >
281+ </ div >
282+ </ div >
283+ ) ;
284+ }
0 commit comments