(in-package :kira) (defclass local-constituency (group blog-mixin events-mixin geo-mixin recipient-mixin) ((founded-date :accessor founded-date :initarg :founded-date :initform nil) (coordinators :initarg :coordinators))) (defun coordinators (group) (with-caching-slot (group 'coordinators) (list (creator group)))) (defsetf coordinators (group) (coordinators) `(setf (slot-value ,group 'coordinators) ,coordinators)) (defmethod section ((group local-constituency)) group) (defmethod text ((group local-constituency) (symbol (eql 'realize))) "Register") (defmethod text ((group local-constituency) (symbol (eql 'class))) "BLC") (defhandler (:groups) (:head ((:script :src (:format "http://maps.google.com/maps?key=~a&file=api&v=2" +google-maps-key+))) ((:script :src "/map.js")) ((:script :src "/markers.js"))) (:title "Brights Local Constituencies") (:p (render-link 'create :type 'local-constituency)) ((:div :id "map"))) (defhandler ((group local-constituency)) (render-markup (body group)) (:collection (blog group))) (defmethod render-editor ((group local-constituency)) (html (:fieldset "Picture" (file-field 'image group)) (:field "Title" (text-field 'title group)) (:field "Description" (markup-field 'body group)) (:field "E-mail" (text-field 'email group :size 30)) (:field "Coordinators" (text-field "coordinators" (whereas ((coordinators (coordinators group))) (format nil "~{~a~^ ~}" coordinators)))) (:field "Date founded" (date-field 'founded-date group)) (:field "Location" (text-field 'location group)))) (defmethod render-sidebar ((group local-constituency) (view t)) (let ((people (people group)) (coordinators (coordinators group))) (html (render-avatar group) ((:panel :case-preserving t) (:uri group) (render-in-style group 'lines) (:ul (:li (render-link group :people)) (:li (render-link group :events)) (:li (render-link group 'create :type 'event)) (:li (render-link group 'create :type 'blog-entry)) (:li (:a (:uri-to group 'edit) "Edit Group Profile")) (:li (render-link group (if (and *person* (containsp people *person*)) 'leave 'join))))) (:panel (:uri group :events) (:collection (events group))) (:panel (:title "Coordinators") (:list coordinators)) (:unless (or (null people) (equal people coordinators)) (:panel (:uri group :people) (:list people)))))) (defmethod render-in-style ((group local-constituency) (style (eql 'lines))) (html ((:ul :class "lines") (:whereas ((location (location group))) (:li* "Location" (render-location location :inline t))) (:when (email group) (:li* "E-mail" (render-contact-link group))) (:whereas ((date (founded-date group))) (:li* "Founded" (render-date date))) (:when *person* (:let ((coordinator-p (containsp (coordinators group) *person*)) (member-p (containsp (people group) *person*))) (:when (or coordinator-p member-p) (:li* "Relation" (cond (coordinator-p (html "You are a coordinator of this group.")) (member-p (html "You are a member of this group.")))))))))) (defmethod initialize-instance-from-query progn ((group local-constituency)) (setf (founded-date group) *now*)) (defmethod update-instance-from-query progn ((group local-constituency)) (setf-accessors-from-query group (coordinators node-uris) (founded-date date))) (defmethod node-access-p or ((group local-constituency) (action t)) (containsp (coordinators group) *person*)) (defmethod watched-slots append ((group local-constituency)) '(title)) (define-update-methods instance ((root root) (group local-constituency)) (update-collection (groups root) group)) (macrolet ((update-membership (&body alert) `(progn (with-transaction () (update-collection (groups *person*) group) (update-collection (people group) *person*) (alert ,@alert)) (redirect *person* :groups)))) (defhandler ((group local-constituency) join) (:title "Join Group") (adding-to (update-membership "You have joined the group " (render-link group) "."))) (defhandler ((group local-constituency) leave) (:title "Leave Group") (removing-from (update-membership "You have left the group " (render-link group) ".")))) (defhandler :raw (map-groups) (with-open-file (stream (merge-pathnames "markers.js" +public-directory+) :direction :output) (format stream "function addMarkers(map) {~%") (do-collection (group (groups *root*)) (let ((location (location group)) (title (title group))) (multiple-value-bind (latitude longitude) (when (and location title) (geocode location)) (if latitude (format stream " addMarker(map, ~a, ~a, ~a, ~a);~%" latitude longitude (js-quote (uri-to nil nil nil group)) (js-quote title)) (format stream " // omitted: ~a~%" group))))) (format stream "}~%") (format t "Status: 204 No Content~%~%") (signal 'response-sent)))