diff --git a/asteroid.asd b/asteroid.asd index e39e24f..d2542e3 100644 --- a/asteroid.asd +++ b/asteroid.asd @@ -40,6 +40,8 @@ (:file "database") (:file "template-utils") (:file "parenscript-utils") + (:module :parenscript + :components ((:file "auth-ui"))) (:file "stream-media") (:file "user-management") (:file "playlist-management") diff --git a/asteroid.lisp b/asteroid.lisp index ee2658d..c1e22d1 100644 --- a/asteroid.lisp +++ b/asteroid.lisp @@ -871,6 +871,13 @@ (format t "~%Received interrupt, stopping server...~%") (stop-server)))) +;;; ParenScript JavaScript Routes +;;; These routes serve dynamically compiled ParenScript as JavaScript + +(define-page js-auth-ui #@"/static/js/auth-ui.js" () + (:content-type "application/javascript") + (generate-auth-ui-js)) + (defun ensure-radiance-environment () "Ensure RADIANCE environment is properly configured for persistence" (unless (radiance:environment) diff --git a/parenscript/auth-ui.lisp b/parenscript/auth-ui.lisp new file mode 100644 index 0000000..f9608a5 --- /dev/null +++ b/parenscript/auth-ui.lisp @@ -0,0 +1,62 @@ +;;;; auth-ui.lisp - ParenScript version of auth-ui.js +;;;; Handle authentication UI state across all pages + +(in-package #:asteroid) + +(defun generate-auth-ui-js () + "Generate JavaScript for authentication UI handling" + (ps:ps* + '(progn + + ;; Check if user is logged in by calling the API + (defun check-auth-status () + (ps:chain + (fetch "/api/asteroid/auth-status") + (then (lambda (response) + (ps:chain response (json)))) + (then (lambda (result) + ;; api-output wraps response in {status, message, data} + (let ((data (or (ps:@ result data) result))) + data))) + (catch (lambda (error) + (ps:chain console (error "Error checking auth status:" error)) + (ps:create :logged-in false + :is-admin false))))) + + ;; Update UI based on authentication status + (defun update-auth-ui (auth-status) + ;; Show/hide elements based on login status + (ps:chain document + (query-selector-all "[data-show-if-logged-in]") + (for-each (lambda (el) + (setf (ps:@ el style display) + (if (ps:@ auth-status logged-in) + "inline-block" + "none"))))) + + (ps:chain document + (query-selector-all "[data-show-if-logged-out]") + (for-each (lambda (el) + (setf (ps:@ el style display) + (if (ps:@ auth-status logged-in) + "none" + "inline-block"))))) + + (ps:chain document + (query-selector-all "[data-show-if-admin]") + (for-each (lambda (el) + (setf (ps:@ el style display) + (if (ps:@ auth-status is-admin) + "inline-block" + "none")))))) + + ;; Initialize auth UI on page load + (ps:chain document + (add-event-listener + "DOMContentLoaded" + (async lambda () + (ps:chain console (log "Auth UI initializing...")) + (let ((auth-status (await (check-auth-status)))) + (ps:chain console (log "Auth status:" auth-status)) + (update-auth-ui auth-status) + (ps:chain console (log "Auth UI updated"))))))))))