├── increments ├── complete │ ├── .firebaserc │ ├── src │ │ └── giggin │ │ │ ├── helpers.cljs │ │ │ ├── components │ │ │ ├── footer.cljs │ │ │ ├── admin_panel.cljs │ │ │ ├── header.cljs │ │ │ ├── checkout_modal.cljs │ │ │ ├── gig_editor.cljs │ │ │ └── orders.cljs │ │ │ ├── state.cljs │ │ │ ├── fb │ │ │ ├── init.cljs │ │ │ ├── db.cljs │ │ │ └── auth.cljs │ │ │ ├── core.cljs │ │ │ └── api.cljs │ ├── .gitignore │ ├── public │ │ ├── img │ │ │ ├── giggin-icon.png │ │ │ ├── stripe.svg │ │ │ └── giggin-logo.svg │ │ ├── index.html │ │ └── 404.html │ ├── firebase.json │ ├── shadow-cljs.edn │ └── package.json ├── 28-performance-url │ ├── .firebaserc │ ├── src │ │ ├── helpers.cljs │ │ ├── components │ │ │ ├── footer.cljs │ │ │ ├── admin_panel.cljs │ │ │ ├── header.cljs │ │ │ ├── checkout_modal.cljs │ │ │ ├── gig_editor.cljs │ │ │ └── orders.cljs │ │ ├── state.cljs │ │ ├── fb │ │ │ ├── init.cljs │ │ │ ├── db.cljs │ │ │ └── auth.cljs │ │ ├── core.cljs │ │ └── api.cljs │ └── firebase.json ├── 02-app-setup │ ├── .gitignore │ ├── public │ │ ├── img │ │ │ ├── giggin-icon.png │ │ │ ├── stripe.svg │ │ │ └── giggin-logo.svg │ │ └── index.html │ ├── src │ │ └── giggin │ │ │ └── core.cljs │ ├── shadow-cljs.edn │ └── package.json ├── 05-displaying-gigs │ └── src │ │ └── giggin │ │ ├── components │ │ ├── gigs.cljs │ │ ├── orders.cljs │ │ ├── footer.cljs │ │ └── header.cljs │ │ └── core.cljs ├── 14-gig-editor │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── gigs.cljs │ │ ├── checkout_modal.cljs │ │ └── orders.cljs │ │ └── core.cljs ├── 15-save-gig │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── checkout_modal.cljs │ │ ├── gigs.cljs │ │ ├── gig_editor.cljs │ │ └── orders.cljs │ │ └── core.cljs ├── 16-update-gig │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── checkout_modal.cljs │ │ ├── gig_editor.cljs │ │ ├── orders.cljs │ │ └── gigs.cljs │ │ └── core.cljs ├── 22-subscribe │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── state.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── admin_panel.cljs │ │ ├── checkout_modal.cljs │ │ ├── gig_editor.cljs │ │ ├── orders.cljs │ │ └── gigs.cljs │ │ ├── fb │ │ ├── db.cljs │ │ └── init.cljs │ │ ├── core.cljs │ │ └── api.cljs ├── 23-sold-out │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── state.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── admin_panel.cljs │ │ ├── checkout_modal.cljs │ │ ├── gig_editor.cljs │ │ ├── orders.cljs │ │ └── gigs.cljs │ │ ├── fb │ │ ├── init.cljs │ │ └── db.cljs │ │ ├── core.cljs │ │ └── api.cljs ├── 07-add-to-order │ └── src │ │ └── giggin │ │ ├── components │ │ ├── orders.cljs │ │ ├── footer.cljs │ │ ├── header.cljs │ │ └── gigs.cljs │ │ └── core.cljs ├── 13-checkout-modal │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── gigs.cljs │ │ └── orders.cljs │ │ └── core.cljs ├── 17-refactor-gigs │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── checkout_modal.cljs │ │ ├── gig_editor.cljs │ │ ├── orders.cljs │ │ └── gigs.cljs │ │ └── core.cljs ├── 18-ajax-requests │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── checkout_modal.cljs │ │ ├── orders.cljs │ │ ├── gig_editor.cljs │ │ └── gigs.cljs │ │ └── core.cljs ├── 20-firebase-setup │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── state.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── checkout_modal.cljs │ │ ├── orders.cljs │ │ ├── gig_editor.cljs │ │ └── gigs.cljs │ │ ├── core.cljs │ │ └── api.cljs ├── 21-firebase-database │ ├── src │ │ └── giggin │ │ │ ├── helpers.cljs │ │ │ ├── state.cljs │ │ │ ├── components │ │ │ ├── footer.cljs │ │ │ ├── header.cljs │ │ │ ├── checkout_modal.cljs │ │ │ ├── orders.cljs │ │ │ ├── gig_editor.cljs │ │ │ └── gigs.cljs │ │ │ ├── fb │ │ │ └── init.cljs │ │ │ ├── core.cljs │ │ │ └── api.cljs │ └── package.json ├── 24-firebase-auth │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── state.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── admin_panel.cljs │ │ ├── checkout_modal.cljs │ │ ├── gig_editor.cljs │ │ └── orders.cljs │ │ ├── fb │ │ ├── init.cljs │ │ └── db.cljs │ │ ├── core.cljs │ │ └── api.cljs ├── 25-sign-in-sign-out │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── state.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── admin_panel.cljs │ │ ├── checkout_modal.cljs │ │ ├── gig_editor.cljs │ │ └── orders.cljs │ │ ├── fb │ │ ├── init.cljs │ │ ├── db.cljs │ │ └── auth.cljs │ │ ├── core.cljs │ │ └── api.cljs ├── 26-security-rules │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── admin_panel.cljs │ │ ├── header.cljs │ │ ├── checkout_modal.cljs │ │ ├── gig_editor.cljs │ │ └── orders.cljs │ │ ├── state.cljs │ │ ├── fb │ │ ├── init.cljs │ │ ├── db.cljs │ │ └── auth.cljs │ │ ├── core.cljs │ │ └── api.cljs ├── 29-tips-and-tricks │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── admin_panel.cljs │ │ ├── header.cljs │ │ ├── checkout_modal.cljs │ │ ├── gig_editor.cljs │ │ └── orders.cljs │ │ ├── state.cljs │ │ ├── fb │ │ ├── init.cljs │ │ ├── db.cljs │ │ └── auth.cljs │ │ ├── core.cljs │ │ └── api.cljs ├── 06-list-comprehension │ └── src │ │ └── giggin │ │ ├── components │ │ ├── orders.cljs │ │ ├── footer.cljs │ │ ├── header.cljs │ │ └── gigs.cljs │ │ └── core.cljs ├── 08-for-over-orders │ └── src │ │ └── giggin │ │ ├── components │ │ ├── orders.cljs │ │ ├── footer.cljs │ │ ├── header.cljs │ │ └── gigs.cljs │ │ └── core.cljs ├── 12-refactor-functions │ └── src │ │ └── giggin │ │ ├── helpers.cljs │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── gigs.cljs │ │ └── orders.cljs │ │ └── core.cljs ├── 19-ajax-transformations │ ├── src │ │ └── giggin │ │ │ ├── helpers.cljs │ │ │ ├── components │ │ │ ├── footer.cljs │ │ │ ├── header.cljs │ │ │ ├── checkout_modal.cljs │ │ │ ├── orders.cljs │ │ │ ├── gig_editor.cljs │ │ │ └── gigs.cljs │ │ │ ├── core.cljs │ │ │ └── api.cljs │ └── shadow-cljs.edn ├── 10-order-total │ └── src │ │ └── giggin │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── gigs.cljs │ │ └── orders.cljs │ │ └── core.cljs ├── 11-format-price │ └── src │ │ └── giggin │ │ ├── components │ │ ├── footer.cljs │ │ ├── header.cljs │ │ ├── gigs.cljs │ │ └── orders.cljs │ │ └── core.cljs └── 09-remove-from-order │ └── src │ └── giggin │ ├── components │ ├── footer.cljs │ ├── header.cljs │ ├── orders.cljs │ └── gigs.cljs │ └── core.cljs ├── giggin ├── public │ ├── img │ │ ├── giggin-icon.png │ │ ├── stripe.svg │ │ └── giggin-logo.svg │ └── index.html ├── .gitignore ├── src │ └── giggin │ │ └── core.cljs ├── shadow-cljs.edn └── package.json └── README.md /increments/complete/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "giggin-7c2d7" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /increments/28-performance-url/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "your-project-id" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /giggin/public/img/giggin-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/learn-reagent-course-files/master/giggin/public/img/giggin-icon.png -------------------------------------------------------------------------------- /increments/complete/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /giggin/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /target 3 | /public/js 4 | .shadow-cljs 5 | .nrepl-port 6 | yarn.lock 7 | package-lock.json 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /increments/02-app-setup/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /target 3 | /public/js 4 | .shadow-cljs 5 | .nrepl-port 6 | yarn.lock 7 | package-lock.json 8 | -------------------------------------------------------------------------------- /increments/05-displaying-gigs/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs) 2 | 3 | (defn gigs 4 | [] 5 | [:gigs "gigs"]) 6 | -------------------------------------------------------------------------------- /increments/14-gig-editor/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/15-save-gig/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/16-update-gig/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/22-subscribe/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/23-sold-out/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/28-performance-url/src/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/complete/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /target 3 | /public/js 4 | .shadow-cljs 5 | .nrepl-port 6 | yarn.lock 7 | package-lock.json 8 | -------------------------------------------------------------------------------- /increments/07-add-to-order/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders) 2 | 3 | (defn orders 4 | [] 5 | [:orders "orders"]) 6 | -------------------------------------------------------------------------------- /increments/13-checkout-modal/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/17-refactor-gigs/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/18-ajax-requests/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/20-firebase-setup/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/21-firebase-database/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/24-firebase-auth/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/25-sign-in-sign-out/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/26-security-rules/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/29-tips-and-tricks/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/05-displaying-gigs/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders) 2 | 3 | (defn orders 4 | [] 5 | [:orders "orders"]) 6 | -------------------------------------------------------------------------------- /increments/06-list-comprehension/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders) 2 | 3 | (defn orders 4 | [] 5 | [:orders "orders"]) 6 | -------------------------------------------------------------------------------- /increments/08-for-over-orders/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders) 2 | 3 | (defn orders 4 | [] 5 | [:orders "orders"]) 6 | -------------------------------------------------------------------------------- /increments/12-refactor-functions/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/19-ajax-transformations/src/giggin/helpers.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.helpers) 2 | 3 | (defn format-price 4 | [cents] 5 | (str " €" (/ cents 100))) 6 | -------------------------------------------------------------------------------- /increments/complete/public/img/giggin-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/learn-reagent-course-files/master/increments/complete/public/img/giggin-icon.png -------------------------------------------------------------------------------- /increments/02-app-setup/public/img/giggin-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gs/learn-reagent-course-files/master/increments/02-app-setup/public/img/giggin-icon.png -------------------------------------------------------------------------------- /increments/22-subscribe/src/giggin/state.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.state 2 | (:require [reagent.core :as r])) 3 | 4 | (def orders (r/atom {})) 5 | 6 | (def gigs (r/atom {})) 7 | -------------------------------------------------------------------------------- /increments/23-sold-out/src/giggin/state.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.state 2 | (:require [reagent.core :as r])) 3 | 4 | (def orders (r/atom {})) 5 | 6 | (def gigs (r/atom {})) 7 | -------------------------------------------------------------------------------- /increments/20-firebase-setup/src/giggin/state.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.state 2 | (:require [reagent.core :as r])) 3 | 4 | (def orders (r/atom {})) 5 | 6 | (def gigs (r/atom {})) 7 | -------------------------------------------------------------------------------- /increments/24-firebase-auth/src/giggin/state.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.state 2 | (:require [reagent.core :as r])) 3 | 4 | (def orders (r/atom {})) 5 | 6 | (def gigs (r/atom {})) 7 | -------------------------------------------------------------------------------- /increments/25-sign-in-sign-out/src/giggin/state.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.state 2 | (:require [reagent.core :as r])) 3 | 4 | (def orders (r/atom {})) 5 | 6 | (def gigs (r/atom {})) 7 | -------------------------------------------------------------------------------- /increments/21-firebase-database/src/giggin/state.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.state 2 | (:require [reagent.core :as r])) 3 | 4 | (def orders (r/atom {})) 5 | 6 | (def gigs (r/atom {})) 7 | -------------------------------------------------------------------------------- /increments/complete/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/10-order-total/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/14-gig-editor/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/15-save-gig/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/16-update-gig/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/22-subscribe/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/23-sold-out/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/28-performance-url/src/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/28-performance-url/src/state.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.state 2 | (:require [reagent.core :as r])) 3 | 4 | (def orders (r/atom {})) 5 | 6 | (def gigs (r/atom {})) 7 | 8 | (def user (r/atom nil)) 9 | -------------------------------------------------------------------------------- /increments/complete/src/giggin/state.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.state 2 | (:require [reagent.core :as r])) 3 | 4 | (def orders (r/atom {})) 5 | 6 | (def gigs (r/atom {})) 7 | 8 | (def user (r/atom nil)) 9 | -------------------------------------------------------------------------------- /increments/05-displaying-gigs/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/07-add-to-order/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/08-for-over-orders/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/10-order-total/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/11-format-price/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/13-checkout-modal/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/14-gig-editor/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/15-save-gig/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/16-update-gig/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/17-refactor-gigs/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/18-ajax-requests/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/20-firebase-setup/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/22-subscribe/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/23-sold-out/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/24-firebase-auth/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/25-sign-in-sign-out/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/26-security-rules/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/26-security-rules/src/giggin/state.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.state 2 | (:require [reagent.core :as r])) 3 | 4 | (def orders (r/atom {})) 5 | 6 | (def gigs (r/atom {})) 7 | 8 | (def user (r/atom nil)) -------------------------------------------------------------------------------- /increments/29-tips-and-tricks/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/05-displaying-gigs/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/06-list-comprehension/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/07-add-to-order/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/08-for-over-orders/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/09-remove-from-order/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/11-format-price/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/12-refactor-functions/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/13-checkout-modal/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/17-refactor-gigs/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/18-ajax-requests/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/19-ajax-transformations/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/20-firebase-setup/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/21-firebase-database/src/giggin/components/footer.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.footer) 2 | 3 | (defn footer 4 | [] 5 | [:footer 6 | [:img {:src "img/giggin-icon.png" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/24-firebase-auth/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/29-tips-and-tricks/src/giggin/state.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.state 2 | (:require [reagent.core :as r])) 3 | 4 | (def orders (r/atom {})) 5 | 6 | (def gigs (r/atom {})) 7 | 8 | (def user (r/atom nil)) 9 | -------------------------------------------------------------------------------- /increments/06-list-comprehension/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/09-remove-from-order/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/12-refactor-functions/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/19-ajax-transformations/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/21-firebase-database/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header) 2 | 3 | (defn header 4 | [] 5 | [:header 6 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}]]) 7 | -------------------------------------------------------------------------------- /increments/complete/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "public", 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /increments/28-performance-url/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "public", 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /giggin/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r])) 3 | 4 | (defn app 5 | [] 6 | [:div.container]) 7 | 8 | (defn ^:export main 9 | [] 10 | (r/render 11 | [app] 12 | (.getElementById js/document "app"))) 13 | -------------------------------------------------------------------------------- /increments/02-app-setup/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r])) 3 | 4 | (defn app 5 | [] 6 | [:div.container]) 7 | 8 | (defn ^:export main 9 | [] 10 | (r/render 11 | [app] 12 | (.getElementById js/document "app"))) 13 | -------------------------------------------------------------------------------- /increments/22-subscribe/src/giggin/fb/db.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.db 2 | (:require ["firebase/app" :refer [database]] 3 | [clojure.string :as str])) 4 | 5 | (defn db-ref 6 | [path] 7 | (.ref (database) (str/join "/" path))) 8 | 9 | (defn db-save! 10 | [path value] 11 | (.set (db-ref path) value)) 12 | -------------------------------------------------------------------------------- /increments/25-sign-in-sign-out/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header 2 | (:require [giggin.fb.auth :refer [sign-in-with-google]])) 3 | 4 | (defn header 5 | [] 6 | [:header 7 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}] 8 | [:button.btn.btn--link.float--right 9 | {:on-click #(sign-in-with-google)} 10 | "Login"]]) -------------------------------------------------------------------------------- /increments/23-sold-out/src/giggin/components/admin_panel.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.admin-panel 2 | (:require [giggin.state :as state] 3 | [giggin.fb.db :refer [db-save!]])) 4 | 5 | (defn admin-panel 6 | [] 7 | [:div.admin-panel 8 | [:button.btn.btn--primary 9 | {:styles {:width "100%"} 10 | :on-click #(db-save! ["gigs"] (clj->js @state/gigs))} 11 | "Publish"]]) 12 | -------------------------------------------------------------------------------- /increments/28-performance-url/src/components/admin_panel.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.admin-panel 2 | (:require [giggin.state :as state] 3 | [giggin.fb.db :refer [db-save!]])) 4 | 5 | (defn admin-panel 6 | [] 7 | [:div.admin-panel 8 | [:button.btn.btn--primary 9 | {:styles {:width "100%"} 10 | :on-click #(db-save! ["gigs"] (clj->js @state/gigs))} 11 | "Publish"]]) 12 | -------------------------------------------------------------------------------- /increments/complete/src/giggin/components/admin_panel.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.admin-panel 2 | (:require [giggin.state :as state] 3 | [giggin.fb.db :refer [db-save!]])) 4 | 5 | (defn admin-panel 6 | [] 7 | [:div.admin-panel 8 | [:button.btn.btn--primary 9 | {:styles {:width "100%"} 10 | :on-click #(db-save! ["gigs"] (clj->js @state/gigs))} 11 | "Publish"]]) 12 | -------------------------------------------------------------------------------- /increments/22-subscribe/src/giggin/components/admin_panel.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.admin-panel 2 | (:require [giggin.state :as state] 3 | [giggin.fb.db :refer [db-save!]])) 4 | 5 | (defn admin-panel 6 | [] 7 | [:div.admin-panel 8 | [:button.btn.btn--primary 9 | {:styles {:width "100%"} 10 | :on-click #(db-save! ["gigs"] (clj->js @state/gigs))} 11 | "Publish"]]) 12 | -------------------------------------------------------------------------------- /increments/24-firebase-auth/src/giggin/components/admin_panel.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.admin-panel 2 | (:require [giggin.state :as state] 3 | [giggin.fb.db :refer [db-save!]])) 4 | 5 | (defn admin-panel 6 | [] 7 | [:div.admin-panel 8 | [:button.btn.btn--primary 9 | {:styles {:width "100%"} 10 | :on-click #(db-save! ["gigs"] (clj->js @state/gigs))} 11 | "Publish"]]) 12 | -------------------------------------------------------------------------------- /increments/25-sign-in-sign-out/src/giggin/components/admin_panel.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.admin-panel 2 | (:require [giggin.state :as state] 3 | [giggin.fb.db :refer [db-save!]])) 4 | 5 | (defn admin-panel 6 | [] 7 | [:div.admin-panel 8 | [:button.btn.btn--primary 9 | {:styles {:width "100%"} 10 | :on-click #(db-save! ["gigs"] (clj->js @state/gigs))} 11 | "Publish"]]) 12 | -------------------------------------------------------------------------------- /increments/26-security-rules/src/giggin/components/admin_panel.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.admin-panel 2 | (:require [giggin.state :as state] 3 | [giggin.fb.db :refer [db-save!]])) 4 | 5 | (defn admin-panel 6 | [] 7 | [:div.admin-panel 8 | [:button.btn.btn--primary 9 | {:styles {:width "100%"} 10 | :on-click #(db-save! ["gigs"] (clj->js @state/gigs))} 11 | "Publish"]]) 12 | -------------------------------------------------------------------------------- /increments/29-tips-and-tricks/src/giggin/components/admin_panel.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.admin-panel 2 | (:require [giggin.state :as state] 3 | [giggin.fb.db :refer [db-save!]])) 4 | 5 | (defn admin-panel 6 | [] 7 | [:div.admin-panel 8 | [:button.btn.btn--primary 9 | {:styles {:width "100%"} 10 | :on-click #(db-save! ["gigs"] (clj->js @state/gigs))} 11 | "Publish"]]) 12 | -------------------------------------------------------------------------------- /increments/21-firebase-database/src/giggin/fb/init.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.init 2 | (:require ["firebase/app" :as firebase] 3 | ["firebase/database"] 4 | ["firebase/auth"])) 5 | 6 | (defn firebase-init 7 | [] 8 | (firebase/initializeApp 9 | {:apiKey "your-api-key" 10 | :authDomain "your-auth-domain" 11 | :databaseURL "your-databse-url" 12 | :projectId "your-project-id"})) 13 | -------------------------------------------------------------------------------- /increments/22-subscribe/src/giggin/fb/init.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.init 2 | (:require ["firebase/app" :as firebase] 3 | ["firebase/database"] 4 | ["firebase/auth"])) 5 | 6 | (defn firebase-init 7 | [] 8 | (if (zero? (alength firebase/apps)) 9 | (firebase/initializeApp 10 | #js {:apiKey "your-api-key" 11 | :authDomain "your-auth-domain" 12 | :databaseURL "your-databse-url" 13 | :projectId "your-project-id"}) 14 | (firebase/app))) -------------------------------------------------------------------------------- /increments/23-sold-out/src/giggin/fb/init.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.init 2 | (:require ["firebase/app" :as firebase] 3 | ["firebase/database"] 4 | ["firebase/auth"])) 5 | 6 | (defn firebase-init 7 | [] 8 | (if (zero? (alength firebase/apps)) 9 | (firebase/initializeApp 10 | #js {:apiKey "your-api-key" 11 | :authDomain "your-auth-domain" 12 | :databaseURL "your-databse-url" 13 | :projectId "your-project-id"}) 14 | (firebase/app))) -------------------------------------------------------------------------------- /increments/24-firebase-auth/src/giggin/fb/init.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.init 2 | (:require ["firebase/app" :as firebase] 3 | ["firebase/database"] 4 | ["firebase/auth"])) 5 | 6 | (defn firebase-init 7 | [] 8 | (if (zero? (alength firebase/apps)) 9 | (firebase/initializeApp 10 | #js {:apiKey "your-api-key" 11 | :authDomain "your-auth-domain" 12 | :databaseURL "your-databse-url" 13 | :projectId "your-project-id"}) 14 | (firebase/app))) -------------------------------------------------------------------------------- /increments/complete/src/giggin/fb/init.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.init 2 | (:require ["firebase/app" :as firebase] 3 | ["firebase/database"] 4 | ["firebase/auth"] 5 | [giggin.fb.auth :refer [on-auth-state-changed]])) 6 | 7 | (defn firebase-init 8 | [] 9 | (firebase/initializeApp 10 | #js {:apiKey "your-api-key" 11 | :authDomain "your-auth-domain" 12 | :databaseURL "your-database-url" 13 | :projectId "your-project-id"}) 14 | (on-auth-state-changed)) 15 | -------------------------------------------------------------------------------- /increments/29-tips-and-tricks/src/giggin/fb/init.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.init 2 | (:require ["firebase/app" :as firebase] 3 | ["firebase/database"] 4 | ["firebase/auth"] 5 | [giggin.fb.auth :refer [on-auth-state-changed]])) 6 | 7 | (defn firebase-init 8 | [] 9 | (firebase/initializeApp 10 | #js {:apiKey "your-api-key" 11 | :authDomain "your-auth-domain" 12 | :databaseURL "your-database-url" 13 | :projectId "your-project-id"}) 14 | (on-auth-state-changed)) 15 | -------------------------------------------------------------------------------- /giggin/shadow-cljs.edn: -------------------------------------------------------------------------------- 1 | {:source-paths ["src"] 2 | 3 | :dependencies [[binaryage/devtools "0.9.10"] 4 | [proto-repl "0.3.1"] 5 | [reagent "0.8.0"]] 6 | 7 | :nrepl {:port 3333} 8 | 9 | :builds 10 | {:app {:target :browser 11 | :output-dir "public/js" 12 | :asset-path "/js" 13 | 14 | :modules 15 | {:main 16 | {:entries [giggin.core]}} 17 | 18 | :devtools 19 | {:after-load giggin.core/main 20 | :http-root "public" 21 | :http-port 3000}}}} 22 | -------------------------------------------------------------------------------- /increments/15-save-gig/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/07-add-to-order/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/10-order-total/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/11-format-price/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/14-gig-editor/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/16-update-gig/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/17-refactor-gigs/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/18-ajax-requests/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/05-displaying-gigs/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/06-list-comprehension/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/08-for-over-orders/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/09-remove-from-order/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/12-refactor-functions/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/13-checkout-modal/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]])) 7 | 8 | (defn app 9 | [] 10 | [:div.container 11 | [header] 12 | [gigs] 13 | [orders] 14 | [footer]]) 15 | 16 | (defn ^:export main 17 | [] 18 | (r/render 19 | [app] 20 | (.getElementById js/document "app"))) 21 | -------------------------------------------------------------------------------- /increments/complete/shadow-cljs.edn: -------------------------------------------------------------------------------- 1 | {:source-paths ["src"] 2 | 3 | :dependencies [[binaryage/devtools "0.9.10"] 4 | [proto-repl "0.3.1"] 5 | [reagent "0.8.0"] 6 | [cljs-ajax "0.7.3"]] 7 | 8 | :nrepl {:port 3333} 9 | 10 | :builds 11 | {:app {:target :browser 12 | :output-dir "public/js" 13 | :asset-path "/js" 14 | 15 | :modules 16 | {:main 17 | {:entries [giggin.core]}} 18 | 19 | :devtools 20 | {:http-root "public" 21 | :http-port 3000}}}} 22 | -------------------------------------------------------------------------------- /increments/02-app-setup/shadow-cljs.edn: -------------------------------------------------------------------------------- 1 | {:source-paths ["src"] 2 | 3 | :dependencies [[binaryage/devtools "0.9.10"] 4 | [proto-repl "0.3.1"] 5 | [reagent "0.8.0"]] 6 | 7 | :nrepl {:port 3333} 8 | 9 | :builds 10 | {:app {:target :browser 11 | :output-dir "public/js" 12 | :asset-path "/js" 13 | 14 | :modules 15 | {:main 16 | {:entries [giggin.core]}} 17 | 18 | :devtools 19 | {:after-load giggin.core/main 20 | :http-root "public" 21 | :http-port 3000}}}} 22 | -------------------------------------------------------------------------------- /increments/28-performance-url/src/fb/init.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.init 2 | (:require ["firebase/app" :as firebase] 3 | ["firebase/database"] 4 | ["firebase/auth"] 5 | [giggin.fb.auth :refer [on-auth-state-changed]])) 6 | 7 | (defn firebase-init 8 | [] 9 | (if (zero? (alength firebase/apps)) 10 | (firebase/initializeApp 11 | #js {:apiKey "your-api-key" 12 | :authDomain "your-auth-domain" 13 | :databaseURL "your-database-url" 14 | :projectId "your-project-id"}) 15 | (firebase/app)) 16 | (on-auth-state-changed)) 17 | -------------------------------------------------------------------------------- /increments/07-add-to-order/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state])) 3 | 4 | (defn gigs 5 | [] 6 | [:main 7 | [:div.gigs 8 | (for [{:keys [id img title price desc]} (vals @state/gigs)] 9 | [:div.gig {:key id} 10 | [:img.gig__artwork {:src img :alt title}] 11 | [:div.gig__body 12 | [:div.gig__title 13 | [:div.btn.btn--primary.float--right.tooltip {:data-tooltip "Add to order"} 14 | [:i.icon.icon--plus]] title] 15 | [:p.gig__price price] 16 | [:p.gig__desc desc]]])]]) 17 | -------------------------------------------------------------------------------- /increments/26-security-rules/src/giggin/fb/init.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.init 2 | (:require ["firebase/app" :as firebase] 3 | ["firebase/database"] 4 | ["firebase/auth"] 5 | [giggin.fb.auth :refer [on-auth-state-changed]])) 6 | 7 | (defn firebase-init 8 | [] 9 | (if (zero? (alength firebase/apps)) 10 | (firebase/initializeApp 11 | #js {:apiKey "your-api-key" 12 | :authDomain "your-auth-domain" 13 | :databaseURL "your-databse-url" 14 | :projectId "your-project-id"}) 15 | (firebase/app)) 16 | (on-auth-state-changed)) -------------------------------------------------------------------------------- /increments/25-sign-in-sign-out/src/giggin/fb/init.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.init 2 | (:require ["firebase/app" :as firebase] 3 | ["firebase/database"] 4 | ["firebase/auth"] 5 | [giggin.fb.auth :refer [on-auth-state-changed]])) 6 | 7 | (defn firebase-init 8 | [] 9 | (if (zero? (alength firebase/apps)) 10 | (firebase/initializeApp 11 | #js {:apiKey "your-api-key" 12 | :authDomain "your-auth-domain" 13 | :databaseURL "your-databse-url" 14 | :projectId "your-project-id"}) 15 | (firebase/app)) 16 | (on-auth-state-changed)) -------------------------------------------------------------------------------- /increments/complete/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header 2 | (:require [giggin.fb.auth :as auth] 3 | [giggin.state :as state])) 4 | 5 | (defn header 6 | [] 7 | [:header 8 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}] 9 | (if @state/user 10 | [:button.btn.btn--link.float--right.tooltip 11 | {:data-tooltip "Sing out" 12 | :on-click #(auth/sign-out)} 13 | [:figure.avatar 14 | [:img {:src (:photo-url @state/user)}]]] 15 | [:button.btn.btn--link.float--right 16 | {:on-click #(auth/sign-in-with-google)} 17 | "Login"])]) 18 | -------------------------------------------------------------------------------- /increments/19-ajax-transformations/shadow-cljs.edn: -------------------------------------------------------------------------------- 1 | {:source-paths ["src"] 2 | 3 | :dependencies [[binaryage/devtools "0.9.10"] 4 | [proto-repl "0.3.1"] 5 | [reagent "0.8.0"] 6 | [cljs-ajax "0.7.3"]] 7 | 8 | :nrepl {:port 3333} 9 | 10 | :builds 11 | {:app {:target :browser 12 | :output-dir "public/js" 13 | :asset-path "/js" 14 | 15 | :modules 16 | {:main 17 | {:entries [giggin.core]}} 18 | 19 | :devtools 20 | {:after-load giggin.core/main 21 | :http-root "public" 22 | :http-port 3000}}}} 23 | -------------------------------------------------------------------------------- /increments/20-firebase-setup/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]] 7 | [giggin.api :as api])) 8 | 9 | (defn app 10 | [] 11 | [:div.container 12 | [header] 13 | [gigs] 14 | [orders] 15 | [footer]]) 16 | 17 | (defn ^:export main 18 | [] 19 | (api/fetch-gigs) 20 | (r/render 21 | [app] 22 | (.getElementById js/document "app"))) 23 | -------------------------------------------------------------------------------- /increments/28-performance-url/src/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header 2 | (:require [giggin.fb.auth :as auth] 3 | [giggin.state :as state])) 4 | 5 | (defn header 6 | [] 7 | [:header 8 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}] 9 | (if @state/user 10 | [:button.btn.btn--link.float--right.tooltip 11 | {:data-tooltip "Sing out" 12 | :on-click #(auth/sign-out)} 13 | [:figure.avatar 14 | [:img {:src (:photo-url @state/user)}]]] 15 | [:button.btn.btn--link.float--right 16 | {:on-click #(auth/sign-in-with-google)} 17 | "Login"])]) 18 | -------------------------------------------------------------------------------- /increments/19-ajax-transformations/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]] 7 | [giggin.api :as api])) 8 | 9 | (defn app 10 | [] 11 | [:div.container 12 | [header] 13 | [gigs] 14 | [orders] 15 | [footer]]) 16 | 17 | (defn ^:export main 18 | [] 19 | (api/fetch-gigs) 20 | (r/render 21 | [app] 22 | (.getElementById js/document "app"))) 23 | -------------------------------------------------------------------------------- /increments/26-security-rules/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header 2 | (:require [giggin.fb.auth :as auth] 3 | [giggin.state :as state])) 4 | 5 | (defn header 6 | [] 7 | [:header 8 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}] 9 | (if @state/user 10 | [:button.btn.btn--link.float--right.tooltip 11 | {:data-tooltip "Sing out" 12 | :on-click #(auth/sign-out)} 13 | [:figure.avatar 14 | [:img {:src (:photo-url @state/user)}]]] 15 | [:button.btn.btn--link.float--right 16 | {:on-click #(auth/sign-in-with-google)} 17 | "Login"])]) 18 | -------------------------------------------------------------------------------- /increments/29-tips-and-tricks/src/giggin/components/header.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.header 2 | (:require [giggin.fb.auth :as auth] 3 | [giggin.state :as state])) 4 | 5 | (defn header 6 | [] 7 | [:header 8 | [:img.logo {:src "img/giggin-logo.svg" :alt "Giggin logo"}] 9 | (if @state/user 10 | [:button.btn.btn--link.float--right.tooltip 11 | {:data-tooltip "Sing out" 12 | :on-click #(auth/sign-out)} 13 | [:figure.avatar 14 | [:img {:src (:photo-url @state/user)}]]] 15 | [:button.btn.btn--link.float--right 16 | {:on-click #(auth/sign-in-with-google)} 17 | "Login"])]) 18 | -------------------------------------------------------------------------------- /increments/09-remove-from-order/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state])) 3 | 4 | (defn orders 5 | [] 6 | [:aside 7 | [:div.order 8 | [:div.body 9 | (for [[id quant] @state/orders] 10 | [:div.item {:key id} 11 | [:div.img 12 | [:img {:src (get-in @state/gigs [id :img]) 13 | :alt (get-in @state/gigs [id :title])}]] 14 | [:div.content 15 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 16 | [:div.action 17 | [:div.price (* (get-in @state/gigs [id :price]) quant)]]])]]]) 18 | -------------------------------------------------------------------------------- /increments/19-ajax-transformations/src/giggin/api.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.api 2 | (:require [ajax.core :refer [GET]])) 3 | 4 | (defn handler [response] 5 | (.log js/console response)) 6 | 7 | (defn error-handler [{:keys [status status-text]}] 8 | (.log js/console (str "something bad happened: " status " " status-text))) 9 | 10 | (defn fetch-gigs 11 | [] 12 | (GET "https://gist.githubusercontent.com/jacekschae/8c10aa58a6163905fffcec33dd6f5a01/raw/20874f73b2c1d0ad08d828131d6ea8392950780a/gigs.json" 13 | {:handler handler 14 | :error-handler error-handler 15 | :response-format :json 16 | :keywords? true})) 17 | -------------------------------------------------------------------------------- /giggin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Giggin", 3 | "version": "0.0.1", 4 | "description": "Giggin - find a gig!", 5 | "repository": "https://github.com/jacekschae/learn-reagent-course-files.git", 6 | "private": true, 7 | "scripts": { 8 | "dev": "shadow-cljs watch app", 9 | "release": "shadow-cljs release app", 10 | "clean": "rm -rf target && rm -rf public/js", 11 | "clean-win": "rmdir /s /q public/js & rmdir /s /q target" 12 | }, 13 | "devDependencies": { 14 | "shadow-cljs": "2.8.52" 15 | }, 16 | "dependencies": { 17 | "create-react-class": "15.6.3", 18 | "react": "16.3.2", 19 | "react-dom": "16.3.2" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /increments/02-app-setup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Giggin", 3 | "version": "0.0.1", 4 | "description": "Giggin - find a gig!", 5 | "repository": "https://github.com/jacekschae/learn-reagent-course-files.git", 6 | "private": true, 7 | "scripts": { 8 | "dev": "shadow-cljs watch app", 9 | "release": "shadow-cljs release app", 10 | "clean": "rm -rf target && rm -rf public/js", 11 | "clean-win": "rmdir /s /q public/js & rmdir /s /q target" 12 | }, 13 | "devDependencies": { 14 | "shadow-cljs": "2.3.30" 15 | }, 16 | "dependencies": { 17 | "create-react-class": "15.6.3", 18 | "react": "16.3.2", 19 | "react-dom": "16.3.2" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /increments/10-order-total/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state])) 3 | 4 | (defn gigs 5 | [] 6 | [:main 7 | [:div.gigs 8 | (for [{:keys [id img title price desc]} (vals @state/gigs)] 9 | [:div.gig {:key id} 10 | [:img.gig__artwork {:src img :alt title}] 11 | [:div.gig__body 12 | [:div.gig__title 13 | [:div.btn.btn--primary.float--right.tooltip 14 | {:data-tooltip "Add to order" 15 | :on-click (fn [] (swap! state/orders update id inc))} 16 | [:i.icon.icon--plus]] title] 17 | [:p.gig__price price] 18 | [:p.gig__desc desc]]])]]) 19 | -------------------------------------------------------------------------------- /increments/11-format-price/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state])) 3 | 4 | (defn gigs 5 | [] 6 | [:main 7 | [:div.gigs 8 | (for [{:keys [id img title price desc]} (vals @state/gigs)] 9 | [:div.gig {:key id} 10 | [:img.gig__artwork {:src img :alt title}] 11 | [:div.gig__body 12 | [:div.gig__title 13 | [:div.btn.btn--primary.float--right.tooltip 14 | {:data-tooltip "Add to order" 15 | :on-click (fn [] (swap! state/orders update id inc))} 16 | [:i.icon.icon--plus]] title] 17 | [:p.gig__price price] 18 | [:p.gig__desc desc]]])]]) 19 | -------------------------------------------------------------------------------- /increments/08-for-over-orders/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state])) 3 | 4 | (defn gigs 5 | [] 6 | [:main 7 | [:div.gigs 8 | (for [{:keys [id img title price desc]} (vals @state/gigs)] 9 | [:div.gig {:key id} 10 | [:img.gig__artwork {:src img :alt title}] 11 | [:div.gig__body 12 | [:div.gig__title 13 | [:div.btn.btn--primary.float--right.tooltip 14 | {:data-tooltip "Add to order" 15 | :on-click (fn [] (swap! state/orders update id inc))} 16 | [:i.icon.icon--plus]] title] 17 | [:p.gig__price price] 18 | [:p.gig__desc desc]]])]]) 19 | -------------------------------------------------------------------------------- /increments/09-remove-from-order/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state])) 3 | 4 | (defn gigs 5 | [] 6 | [:main 7 | [:div.gigs 8 | (for [{:keys [id img title price desc]} (vals @state/gigs)] 9 | [:div.gig {:key id} 10 | [:img.gig__artwork {:src img :alt title}] 11 | [:div.gig__body 12 | [:div.gig__title 13 | [:div.btn.btn--primary.float--right.tooltip 14 | {:data-tooltip "Add to order" 15 | :on-click (fn [] (swap! state/orders update id inc))} 16 | [:i.icon.icon--plus]] title] 17 | [:p.gig__price price] 18 | [:p.gig__desc desc]]])]]) 19 | -------------------------------------------------------------------------------- /increments/22-subscribe/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]] 7 | [giggin.api :as api] 8 | [giggin.fb.init :refer [firebase-init]])) 9 | 10 | (defn app 11 | [] 12 | [:div.container 13 | [header] 14 | [gigs] 15 | [orders] 16 | [footer]]) 17 | 18 | (defn ^:export main 19 | [] 20 | (api/fetch-gigs) 21 | (r/render 22 | [app] 23 | (.getElementById js/document "app")) 24 | (firebase-init)) 25 | -------------------------------------------------------------------------------- /increments/complete/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Giggin", 3 | "version": "0.0.1", 4 | "private": true, 5 | "description": "Giggin - find a gig!", 6 | "repository": "https://github.com/jacekschae/learn-reagent-course-files.git", 7 | "scripts": { 8 | "dev": "shadow-cljs watch app", 9 | "release": "shadow-cljs release app", 10 | "clean": "rm -rf target && rm -rf public/js", 11 | "clean-win": "rmdir /s /q public/js & rmdir /s /q target" 12 | }, 13 | "devDependencies": { 14 | "shadow-cljs": "2.3.30" 15 | }, 16 | "dependencies": { 17 | "create-react-class": "15.6.3", 18 | "firebase": "^4.13.1", 19 | "react": "16.3.2", 20 | "react-dom": "16.3.2" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /increments/21-firebase-database/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]] 7 | [giggin.api :as api] 8 | [giggin.fb.init :refer [firebase-init]])) 9 | 10 | (defn app 11 | [] 12 | [:div.container 13 | [header] 14 | [gigs] 15 | [orders] 16 | [footer]]) 17 | 18 | (defn ^:export main 19 | [] 20 | (api/fetch-gigs) 21 | (r/render 22 | [app] 23 | (.getElementById js/document "app")) 24 | (firebase-init)) 25 | -------------------------------------------------------------------------------- /increments/21-firebase-database/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Giggin", 3 | "version": "0.0.1", 4 | "description": "Giggin - find a gig!", 5 | "repository": "https://github.com/jacekschae/learn-reagent-course-files.git", 6 | "private": true, 7 | "scripts": { 8 | "dev": "shadow-cljs watch app", 9 | "release": "shadow-cljs release app", 10 | "clean": "rm -rf target && rm -rf public/js", 11 | "clean-win": "rmdir /s /q public/js & rmdir /s /q target" 12 | }, 13 | "devDependencies": { 14 | "shadow-cljs": "2.3.30" 15 | }, 16 | "dependencies": { 17 | "create-react-class": "15.6.3", 18 | "firebase": "^4.13.1", 19 | "react": "16.3.2", 20 | "react-dom": "16.3.2" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /increments/06-list-comprehension/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state])) 3 | 4 | (defn gigs 5 | [] 6 | [:main 7 | [:div.gigs (map (fn [gig] 8 | [:div.gig {:key (:id gig)} 9 | [:img.gig__artwork {:src (:img gig) :alt (:title gig)}] 10 | [:div.gig__body 11 | [:div.gig__title 12 | [:div.btn.btn--primary.float--right.tooltip {:data-tooltip "Add to order"} 13 | [:i.icon.icon--plus]] (:title gig)] 14 | [:p.gig__price (:price gig)] 15 | [:p.gig__desc (:desc gig)]]]) (vals @state/gigs))]]) -------------------------------------------------------------------------------- /increments/23-sold-out/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]] 7 | [giggin.fb.init :refer [firebase-init]] 8 | [giggin.fb.db :refer [db-subscribe]])) 9 | 10 | (defn app 11 | [] 12 | [:div.container 13 | [header] 14 | [gigs] 15 | [orders] 16 | [footer]]) 17 | 18 | (defn ^:export main 19 | [] 20 | (r/render 21 | [app] 22 | (.getElementById js/document "app")) 23 | (firebase-init) 24 | (db-subscribe ["gigs"])) 25 | -------------------------------------------------------------------------------- /increments/24-firebase-auth/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]] 7 | [giggin.fb.init :refer [firebase-init]] 8 | [giggin.fb.db :refer [db-subscribe]])) 9 | 10 | (defn app 11 | [] 12 | [:div.container 13 | [header] 14 | [gigs] 15 | [orders] 16 | [footer]]) 17 | 18 | (defn ^:export main 19 | [] 20 | (r/render 21 | [app] 22 | (.getElementById js/document "app")) 23 | (firebase-init) 24 | (db-subscribe ["gigs"])) 25 | -------------------------------------------------------------------------------- /increments/25-sign-in-sign-out/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]] 7 | [giggin.fb.init :refer [firebase-init]] 8 | [giggin.fb.db :refer [db-subscribe]])) 9 | 10 | (defn app 11 | [] 12 | [:div.container 13 | [header] 14 | [gigs] 15 | [orders] 16 | [footer]]) 17 | 18 | (defn ^:export main 19 | [] 20 | (r/render 21 | [app] 22 | (.getElementById js/document "app")) 23 | (firebase-init) 24 | (db-subscribe ["gigs"])) 25 | -------------------------------------------------------------------------------- /increments/26-security-rules/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]] 7 | [giggin.fb.init :refer [firebase-init]] 8 | [giggin.fb.db :refer [db-subscribe]])) 9 | 10 | (defn app 11 | [] 12 | [:div.container 13 | [header] 14 | [gigs] 15 | [orders] 16 | [footer]]) 17 | 18 | (defn ^:export main 19 | [] 20 | (r/render 21 | [app] 22 | (.getElementById js/document "app")) 23 | (firebase-init) 24 | (db-subscribe ["gigs"])) 25 | -------------------------------------------------------------------------------- /giggin/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Giggin 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /increments/complete/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Giggin 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /increments/complete/src/giggin/fb/db.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.db 2 | (:require ["firebase/app" :refer [database]] 3 | [clojure.string :as str] 4 | [giggin.state :as state])) 5 | 6 | (defn db-ref 7 | [path] 8 | (.ref (database) (str/join "/" path))) 9 | 10 | (defn db-save! 11 | [path value] 12 | (.set (db-ref path) value)) 13 | 14 | ; var starCountRef = firebase.database().ref('posts/' + postId + '/starCount'); 15 | ; starCountRef.on('value', function(snapshot) { 16 | ; updateStarCount(postElement, snapshot.val()); 17 | ; }); 18 | (defn db-subscribe 19 | [path] 20 | (.on (db-ref path) 21 | "value" 22 | (fn [snapshot] 23 | (reset! state/gigs (js->clj (.val snapshot) :keywordize-keys true))))) 24 | -------------------------------------------------------------------------------- /increments/02-app-setup/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Giggin 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /increments/23-sold-out/src/giggin/fb/db.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.db 2 | (:require ["firebase/app" :refer [database]] 3 | [clojure.string :as str] 4 | [giggin.state :as state])) 5 | 6 | (defn db-ref 7 | [path] 8 | (.ref (database) (str/join "/" path))) 9 | 10 | (defn db-save! 11 | [path value] 12 | (.set (db-ref path) value)) 13 | 14 | ; var starCountRef = firebase.database().ref('posts/' + postId + '/starCount'); 15 | ; starCountRef.on('value', function(snapshot) { 16 | ; updateStarCount(postElement, snapshot.val()); 17 | ; }); 18 | (defn db-subscribe 19 | [path] 20 | (.on (db-ref path) 21 | "value" 22 | (fn [snapshot] 23 | (reset! state/gigs (js->clj (.val snapshot) :keywordize-keys true))))) 24 | -------------------------------------------------------------------------------- /increments/28-performance-url/src/fb/db.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.db 2 | (:require ["firebase/app" :refer [database]] 3 | [clojure.string :as str] 4 | [giggin.state :as state])) 5 | 6 | (defn db-ref 7 | [path] 8 | (.ref (database) (str/join "/" path))) 9 | 10 | (defn db-save! 11 | [path value] 12 | (.set (db-ref path) value)) 13 | 14 | ; var starCountRef = firebase.database().ref('posts/' + postId + '/starCount'); 15 | ; starCountRef.on('value', function(snapshot) { 16 | ; updateStarCount(postElement, snapshot.val()); 17 | ; }); 18 | (defn db-subscribe 19 | [path] 20 | (.on (db-ref path) 21 | "value" 22 | (fn [snapshot] 23 | (reset! state/gigs (js->clj (.val snapshot) :keywordize-keys true))))) 24 | -------------------------------------------------------------------------------- /increments/12-refactor-functions/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]])) 4 | 5 | (defn gigs 6 | [] 7 | [:main 8 | [:div.gigs 9 | (for [{:keys [id img title price desc]} (vals @state/gigs)] 10 | [:div.gig {:key id} 11 | [:img.gig__artwork {:src img :alt title}] 12 | [:div.gig__body 13 | [:div.gig__title 14 | [:div.btn.btn--primary.float--right.tooltip 15 | {:data-tooltip "Add to order" 16 | :on-click (fn [] (swap! state/orders update id inc))} 17 | [:i.icon.icon--plus]] title] 18 | [:p.gig__price (format-price price)] 19 | [:p.gig__desc desc]]])]]) 20 | -------------------------------------------------------------------------------- /increments/24-firebase-auth/src/giggin/fb/db.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.db 2 | (:require ["firebase/app" :refer [database]] 3 | [clojure.string :as str] 4 | [giggin.state :as state])) 5 | 6 | (defn db-ref 7 | [path] 8 | (.ref (database) (str/join "/" path))) 9 | 10 | (defn db-save! 11 | [path value] 12 | (.set (db-ref path) value)) 13 | 14 | ; var starCountRef = firebase.database().ref('posts/' + postId + '/starCount'); 15 | ; starCountRef.on('value', function(snapshot) { 16 | ; updateStarCount(postElement, snapshot.val()); 17 | ; }); 18 | (defn db-subscribe 19 | [path] 20 | (.on (db-ref path) 21 | "value" 22 | (fn [snapshot] 23 | (reset! state/gigs (js->clj (.val snapshot) :keywordize-keys true))))) 24 | -------------------------------------------------------------------------------- /increments/26-security-rules/src/giggin/fb/db.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.db 2 | (:require ["firebase/app" :refer [database]] 3 | [clojure.string :as str] 4 | [giggin.state :as state])) 5 | 6 | (defn db-ref 7 | [path] 8 | (.ref (database) (str/join "/" path))) 9 | 10 | (defn db-save! 11 | [path value] 12 | (.set (db-ref path) value)) 13 | 14 | ; var starCountRef = firebase.database().ref('posts/' + postId + '/starCount'); 15 | ; starCountRef.on('value', function(snapshot) { 16 | ; updateStarCount(postElement, snapshot.val()); 17 | ; }); 18 | (defn db-subscribe 19 | [path] 20 | (.on (db-ref path) 21 | "value" 22 | (fn [snapshot] 23 | (reset! state/gigs (js->clj (.val snapshot) :keywordize-keys true))))) 24 | -------------------------------------------------------------------------------- /increments/29-tips-and-tricks/src/giggin/fb/db.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.db 2 | (:require ["firebase/app" :refer [database]] 3 | [clojure.string :as str] 4 | [giggin.state :as state])) 5 | 6 | (defn db-ref 7 | [path] 8 | (.ref (database) (str/join "/" path))) 9 | 10 | (defn db-save! 11 | [path value] 12 | (.set (db-ref path) value)) 13 | 14 | ; var starCountRef = firebase.database().ref('posts/' + postId + '/starCount'); 15 | ; starCountRef.on('value', function(snapshot) { 16 | ; updateStarCount(postElement, snapshot.val()); 17 | ; }); 18 | (defn db-subscribe 19 | [path] 20 | (.on (db-ref path) 21 | "value" 22 | (fn [snapshot] 23 | (reset! state/gigs (js->clj (.val snapshot) :keywordize-keys true))))) 24 | -------------------------------------------------------------------------------- /increments/25-sign-in-sign-out/src/giggin/fb/db.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.db 2 | (:require ["firebase/app" :refer [database]] 3 | [clojure.string :as str] 4 | [giggin.state :as state])) 5 | 6 | (defn db-ref 7 | [path] 8 | (.ref (database) (str/join "/" path))) 9 | 10 | (defn db-save! 11 | [path value] 12 | (.set (db-ref path) value)) 13 | 14 | ; var starCountRef = firebase.database().ref('posts/' + postId + '/starCount'); 15 | ; starCountRef.on('value', function(snapshot) { 16 | ; updateStarCount(postElement, snapshot.val()); 17 | ; }); 18 | (defn db-subscribe 19 | [path] 20 | (.on (db-ref path) 21 | "value" 22 | (fn [snapshot] 23 | (reset! state/gigs (js->clj (.val snapshot) :keywordize-keys true))))) 24 | -------------------------------------------------------------------------------- /increments/28-performance-url/src/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]] 7 | [giggin.api :as api] 8 | [giggin.fb.init :refer [firebase-init]] 9 | [giggin.fb.db :refer [db-subscribe]])) 10 | 11 | (defn app 12 | [] 13 | [:div.container 14 | [header] 15 | [gigs] 16 | [orders] 17 | [footer]]) 18 | 19 | (defn ^:export main 20 | [] 21 | (r/render 22 | [app] 23 | (.getElementById js/document "app")) 24 | (firebase-init) 25 | (db-subscribe ["gigs"])) 26 | -------------------------------------------------------------------------------- /increments/complete/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]] 7 | [giggin.fb.init :refer [firebase-init]] 8 | [giggin.fb.db :refer [db-subscribe]])) 9 | 10 | (defn app 11 | [] 12 | [:div.container 13 | [header] 14 | [gigs] 15 | [orders] 16 | [footer]]) 17 | 18 | (defn ^:dev/after-load start 19 | [] 20 | (r/render 21 | [app] 22 | (.getElementById js/document "app"))) 23 | 24 | (defn ^:export main 25 | [] 26 | (start) 27 | (firebase-init) 28 | (db-subscribe ["gigs"])) 29 | -------------------------------------------------------------------------------- /increments/29-tips-and-tricks/src/giggin/core.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.core 2 | (:require [reagent.core :as r] 3 | [giggin.components.header :refer [header]] 4 | [giggin.components.gigs :refer [gigs]] 5 | [giggin.components.orders :refer [orders]] 6 | [giggin.components.footer :refer [footer]] 7 | [giggin.fb.init :refer [firebase-init]] 8 | [giggin.fb.db :refer [db-subscribe]])) 9 | 10 | (defn app 11 | [] 12 | [:div.container 13 | [header] 14 | [gigs] 15 | [orders] 16 | [footer]]) 17 | 18 | (defn ^:dev/after-load start 19 | [] 20 | (r/render 21 | [app] 22 | (.getElementById js/document "app"))) 23 | 24 | (defn ^:export main 25 | [] 26 | (start) 27 | (firebase-init) 28 | (db-subscribe ["gigs"])) 29 | -------------------------------------------------------------------------------- /increments/14-gig-editor/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]])) 4 | 5 | (defn gigs 6 | [] 7 | (let [add-to-order #(swap! state/orders update % inc)] 8 | [:main 9 | [:div.gigs 10 | (for [{:keys [id img title price desc]} (vals @state/gigs)] 11 | [:div.gig {:key id} 12 | [:img.gig__artwork {:src img :alt title}] 13 | [:div.gig__body 14 | [:div.gig__title 15 | [:div.btn.btn--primary.float--right.tooltip 16 | {:data-tooltip "Add to order" 17 | :on-click #(add-to-order id)} 18 | [:i.icon.icon--plus]] title] 19 | [:p.gig__price (format-price price)] 20 | [:p.gig__desc desc]]])]])) 21 | -------------------------------------------------------------------------------- /increments/13-checkout-modal/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]])) 4 | 5 | (defn gigs 6 | [] 7 | (let [add-to-order #(swap! state/orders update % inc)] 8 | [:main 9 | [:div.gigs 10 | (for [{:keys [id img title price desc]} (vals @state/gigs)] 11 | [:div.gig {:key id} 12 | [:img.gig__artwork {:src img :alt title}] 13 | [:div.gig__body 14 | [:div.gig__title 15 | [:div.btn.btn--primary.float--right.tooltip 16 | {:data-tooltip "Add to order" 17 | :on-click #(add-to-order id)} 18 | [:i.icon.icon--plus]] title] 19 | [:p.gig__price (format-price price)] 20 | [:p.gig__desc desc]]])]])) 21 | -------------------------------------------------------------------------------- /increments/10-order-total/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state])) 3 | 4 | (defn orders 5 | [] 6 | [:aside 7 | [:div.order 8 | [:div.body 9 | (for [[id quant] @state/orders] 10 | [:div.item {:key id} 11 | [:div.img 12 | [:img {:src (get-in @state/gigs [id :img]) 13 | :alt (get-in @state/gigs [id :title])}]] 14 | [:div.content 15 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 16 | [:div.action 17 | [:div.price (* (get-in @state/gigs [id :price]) quant)] 18 | [:button.btn.btn--link.tooltip 19 | {:data-tooltip "Remove" 20 | :on-click (fn [] (swap! state/orders dissoc id))} 21 | [:i.icon.icon--cross]]]])]]]) 22 | -------------------------------------------------------------------------------- /increments/complete/src/giggin/api.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.api 2 | (:require [ajax.core :refer [GET]] 3 | [giggin.state :as state])) 4 | 5 | (defn index-by 6 | [key coll] 7 | "Transfomr a coll to a map with a given key as a lookup value" 8 | (->> coll 9 | (map (juxt key identity)) 10 | (into {}))) 11 | 12 | (defn handler [response] 13 | (reset! state/gigs (index-by :id response))) 14 | 15 | (defn error-handler [{:keys [status status-text]}] 16 | (.log js/console (str "something bad happened: " status " " status-text))) 17 | 18 | (defn fetch-gigs 19 | [] 20 | (GET "https://gist.githubusercontent.com/jacekschae/8c10aa58a6163905fffcec33dd6f5a01/raw/20874f73b2c1d0ad08d828131d6ea8392950780a/gigs.json" 21 | {:handler handler 22 | :error-handler error-handler 23 | :response-format :json 24 | :keywords? true})) 25 | -------------------------------------------------------------------------------- /increments/22-subscribe/src/giggin/api.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.api 2 | (:require [ajax.core :refer [GET]] 3 | [giggin.state :as state])) 4 | 5 | (defn index-by 6 | [key coll] 7 | "Transfomr a coll to a map with a given key as a lookup value" 8 | (->> coll 9 | (map (juxt key identity)) 10 | (into {}))) 11 | 12 | (defn handler [response] 13 | (reset! state/gigs (index-by :id response))) 14 | 15 | (defn error-handler [{:keys [status status-text]}] 16 | (.log js/console (str "something bad happened: " status " " status-text))) 17 | 18 | (defn fetch-gigs 19 | [] 20 | (GET "https://gist.githubusercontent.com/jacekschae/8c10aa58a6163905fffcec33dd6f5a01/raw/20874f73b2c1d0ad08d828131d6ea8392950780a/gigs.json" 21 | {:handler handler 22 | :error-handler error-handler 23 | :response-format :json 24 | :keywords? true})) 25 | -------------------------------------------------------------------------------- /increments/23-sold-out/src/giggin/api.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.api 2 | (:require [ajax.core :refer [GET]] 3 | [giggin.state :as state])) 4 | 5 | (defn index-by 6 | [key coll] 7 | "Transfomr a coll to a map with a given key as a lookup value" 8 | (->> coll 9 | (map (juxt key identity)) 10 | (into {}))) 11 | 12 | (defn handler [response] 13 | (reset! state/gigs (index-by :id response))) 14 | 15 | (defn error-handler [{:keys [status status-text]}] 16 | (.log js/console (str "something bad happened: " status " " status-text))) 17 | 18 | (defn fetch-gigs 19 | [] 20 | (GET "https://gist.githubusercontent.com/jacekschae/8c10aa58a6163905fffcec33dd6f5a01/raw/20874f73b2c1d0ad08d828131d6ea8392950780a/gigs.json" 21 | {:handler handler 22 | :error-handler error-handler 23 | :response-format :json 24 | :keywords? true})) 25 | -------------------------------------------------------------------------------- /increments/28-performance-url/src/api.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.api 2 | (:require [ajax.core :refer [GET]] 3 | [giggin.state :as state])) 4 | 5 | (defn index-by 6 | [key coll] 7 | "Transfomr a coll to a map with a given key as a lookup value" 8 | (->> coll 9 | (map (juxt key identity)) 10 | (into {}))) 11 | 12 | (defn handler [response] 13 | (reset! state/gigs (index-by :id response))) 14 | 15 | (defn error-handler [{:keys [status status-text]}] 16 | (.log js/console (str "something bad happened: " status " " status-text))) 17 | 18 | (defn fetch-gigs 19 | [] 20 | (GET "https://gist.githubusercontent.com/jacekschae/8c10aa58a6163905fffcec33dd6f5a01/raw/20874f73b2c1d0ad08d828131d6ea8392950780a/gigs.json" 21 | {:handler handler 22 | :error-handler error-handler 23 | :response-format :json 24 | :keywords? true})) 25 | -------------------------------------------------------------------------------- /increments/20-firebase-setup/src/giggin/api.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.api 2 | (:require [ajax.core :refer [GET]] 3 | [giggin.state :as state])) 4 | 5 | (defn index-by 6 | [key coll] 7 | "Transfomr a coll to a map with a given key as a lookup value" 8 | (->> coll 9 | (map (juxt key identity)) 10 | (into {}))) 11 | 12 | (defn handler [response] 13 | (reset! state/gigs (index-by :id response))) 14 | 15 | (defn error-handler [{:keys [status status-text]}] 16 | (.log js/console (str "something bad happened: " status " " status-text))) 17 | 18 | (defn fetch-gigs 19 | [] 20 | (GET "https://gist.githubusercontent.com/jacekschae/8c10aa58a6163905fffcec33dd6f5a01/raw/20874f73b2c1d0ad08d828131d6ea8392950780a/gigs.json" 21 | {:handler handler 22 | :error-handler error-handler 23 | :response-format :json 24 | :keywords? true})) 25 | -------------------------------------------------------------------------------- /increments/24-firebase-auth/src/giggin/api.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.api 2 | (:require [ajax.core :refer [GET]] 3 | [giggin.state :as state])) 4 | 5 | (defn index-by 6 | [key coll] 7 | "Transfomr a coll to a map with a given key as a lookup value" 8 | (->> coll 9 | (map (juxt key identity)) 10 | (into {}))) 11 | 12 | (defn handler [response] 13 | (reset! state/gigs (index-by :id response))) 14 | 15 | (defn error-handler [{:keys [status status-text]}] 16 | (.log js/console (str "something bad happened: " status " " status-text))) 17 | 18 | (defn fetch-gigs 19 | [] 20 | (GET "https://gist.githubusercontent.com/jacekschae/8c10aa58a6163905fffcec33dd6f5a01/raw/20874f73b2c1d0ad08d828131d6ea8392950780a/gigs.json" 21 | {:handler handler 22 | :error-handler error-handler 23 | :response-format :json 24 | :keywords? true})) 25 | -------------------------------------------------------------------------------- /increments/25-sign-in-sign-out/src/giggin/api.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.api 2 | (:require [ajax.core :refer [GET]] 3 | [giggin.state :as state])) 4 | 5 | (defn index-by 6 | [key coll] 7 | "Transfomr a coll to a map with a given key as a lookup value" 8 | (->> coll 9 | (map (juxt key identity)) 10 | (into {}))) 11 | 12 | (defn handler [response] 13 | (reset! state/gigs (index-by :id response))) 14 | 15 | (defn error-handler [{:keys [status status-text]}] 16 | (.log js/console (str "something bad happened: " status " " status-text))) 17 | 18 | (defn fetch-gigs 19 | [] 20 | (GET "https://gist.githubusercontent.com/jacekschae/8c10aa58a6163905fffcec33dd6f5a01/raw/20874f73b2c1d0ad08d828131d6ea8392950780a/gigs.json" 21 | {:handler handler 22 | :error-handler error-handler 23 | :response-format :json 24 | :keywords? true})) 25 | -------------------------------------------------------------------------------- /increments/26-security-rules/src/giggin/api.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.api 2 | (:require [ajax.core :refer [GET]] 3 | [giggin.state :as state])) 4 | 5 | (defn index-by 6 | [key coll] 7 | "Transfomr a coll to a map with a given key as a lookup value" 8 | (->> coll 9 | (map (juxt key identity)) 10 | (into {}))) 11 | 12 | (defn handler [response] 13 | (reset! state/gigs (index-by :id response))) 14 | 15 | (defn error-handler [{:keys [status status-text]}] 16 | (.log js/console (str "something bad happened: " status " " status-text))) 17 | 18 | (defn fetch-gigs 19 | [] 20 | (GET "https://gist.githubusercontent.com/jacekschae/8c10aa58a6163905fffcec33dd6f5a01/raw/20874f73b2c1d0ad08d828131d6ea8392950780a/gigs.json" 21 | {:handler handler 22 | :error-handler error-handler 23 | :response-format :json 24 | :keywords? true})) 25 | -------------------------------------------------------------------------------- /increments/29-tips-and-tricks/src/giggin/api.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.api 2 | (:require [ajax.core :refer [GET]] 3 | [giggin.state :as state])) 4 | 5 | (defn index-by 6 | [key coll] 7 | "Transfomr a coll to a map with a given key as a lookup value" 8 | (->> coll 9 | (map (juxt key identity)) 10 | (into {}))) 11 | 12 | (defn handler [response] 13 | (reset! state/gigs (index-by :id response))) 14 | 15 | (defn error-handler [{:keys [status status-text]}] 16 | (.log js/console (str "something bad happened: " status " " status-text))) 17 | 18 | (defn fetch-gigs 19 | [] 20 | (GET "https://gist.githubusercontent.com/jacekschae/8c10aa58a6163905fffcec33dd6f5a01/raw/20874f73b2c1d0ad08d828131d6ea8392950780a/gigs.json" 21 | {:handler handler 22 | :error-handler error-handler 23 | :response-format :json 24 | :keywords? true})) 25 | -------------------------------------------------------------------------------- /increments/21-firebase-database/src/giggin/api.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.api 2 | (:require [ajax.core :refer [GET]] 3 | [giggin.state :as state])) 4 | 5 | (defn index-by 6 | [key coll] 7 | "Transfomr a coll to a map with a given key as a lookup value" 8 | (->> coll 9 | (map (juxt key identity)) 10 | (into {}))) 11 | 12 | (defn handler [response] 13 | (reset! state/gigs (index-by :id response))) 14 | 15 | (defn error-handler [{:keys [status status-text]}] 16 | (.log js/console (str "something bad happened: " status " " status-text))) 17 | 18 | (defn fetch-gigs 19 | [] 20 | (GET "https://gist.githubusercontent.com/jacekschae/8c10aa58a6163905fffcec33dd6f5a01/raw/20874f73b2c1d0ad08d828131d6ea8392950780a/gigs.json" 21 | {:handler handler 22 | :error-handler error-handler 23 | :response-format :json 24 | :keywords? true})) 25 | -------------------------------------------------------------------------------- /increments/26-security-rules/src/giggin/fb/auth.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.auth 2 | (:require ["firebase/app" :as firebase] 3 | [giggin.fb.db :refer [db-save!]])) 4 | 5 | (defn sign-in-with-google 6 | [] 7 | (let [provider (firebase/auth.GoogleAuthProvider.)] 8 | (.signInWithPopup (firebase/auth) provider))) 9 | 10 | (defn sign-out 11 | [] 12 | (.signOut (firebase/auth))) 13 | 14 | (defn on-auth-state-changed 15 | [] 16 | (.onAuthStateChanged 17 | (firebase/auth) 18 | (fn 19 | [user] 20 | (when user 21 | (let [uid (.-uid user) 22 | display-name (.-displayName user) 23 | photo-url (.-photoURL user) 24 | email (.-email user)] 25 | (db-save! 26 | ["users" uid "profile"] 27 | #js {:photo-url photo-url 28 | :display-name display-name 29 | :email email})))))) 30 | -------------------------------------------------------------------------------- /increments/15-save-gig/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/22-subscribe/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/23-sold-out/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/28-performance-url/src/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/complete/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/14-gig-editor/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/16-update-gig/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/17-refactor-gigs/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/18-ajax-requests/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/20-firebase-setup/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/24-firebase-auth/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/26-security-rules/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/21-firebase-database/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/25-sign-in-sign-out/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/29-tips-and-tricks/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/19-ajax-transformations/src/giggin/components/checkout_modal.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.checkout-modal 2 | (:require [reagent.core :as r])) 3 | 4 | (defn checkout-modal 5 | [] 6 | (let [modal (r/atom false) 7 | toggle-modal #(reset! modal %)] 8 | (fn 9 | [] 10 | [:div.checkout-modal 11 | [:button.btn.btn--secondary 12 | {:on-click #(toggle-modal true) 13 | :style {:width "100%"}} 14 | "Checkout"] 15 | [:div.modal (when @modal {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [:div.payment 20 | [:img.payment-logo {:src "/img/paypal.svg" :alt "Paypal logo"}] 21 | [:img.payment-logo {:src "/img/stripe.svg" :alt "Stripe logo"}]]] 22 | [:div.modal__footer 23 | [:button.btn.btn--link.float--left 24 | {:on-click #(toggle-modal false)} 25 | "Cancel"]]]]]))) 26 | -------------------------------------------------------------------------------- /increments/28-performance-url/src/fb/auth.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.auth 2 | (:require ["firebase/app" :as firebase] 3 | [giggin.fb.db :refer [db-save!]] 4 | [giggin.state :as state])) 5 | 6 | (defn sign-in-with-google 7 | [] 8 | (let [provider (firebase/auth.GoogleAuthProvider.)] 9 | (.signInWithPopup (firebase/auth) provider))) 10 | 11 | (defn sign-out 12 | [] 13 | (.signOut (firebase/auth))) 14 | 15 | (defn on-auth-state-changed 16 | [] 17 | (.onAuthStateChanged 18 | (firebase/auth) 19 | (fn 20 | [user] 21 | (if user 22 | (let [uid (.-uid user) 23 | display-name (.-displayName user) 24 | photo-url (.-photoURL user) 25 | email (.-email user)] 26 | (do 27 | (reset! state/user {:photo-url photo-url 28 | :display-name display-name 29 | :email email}) 30 | (db-save! 31 | ["users" uid "profile"] 32 | #js {:photo-url photo-url 33 | :display-name display-name 34 | :email email}))) 35 | (reset! state/user nil))))) 36 | -------------------------------------------------------------------------------- /increments/complete/src/giggin/fb/auth.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.auth 2 | (:require ["firebase/app" :as firebase] 3 | [giggin.fb.db :refer [db-save!]] 4 | [giggin.state :as state])) 5 | 6 | (defn sign-in-with-google 7 | [] 8 | (let [provider (firebase/auth.GoogleAuthProvider.)] 9 | (.signInWithPopup (firebase/auth) provider))) 10 | 11 | (defn sign-out 12 | [] 13 | (.signOut (firebase/auth))) 14 | 15 | (defn on-auth-state-changed 16 | [] 17 | (.onAuthStateChanged 18 | (firebase/auth) 19 | (fn 20 | [user] 21 | (if user 22 | (let [uid (.-uid user) 23 | display-name (.-displayName user) 24 | photo-url (.-photoURL user) 25 | email (.-email user)] 26 | (do 27 | (reset! state/user {:photo-url photo-url 28 | :display-name display-name 29 | :email email}) 30 | (db-save! 31 | ["users" uid "profile"] 32 | #js {:photo-url photo-url 33 | :display-name display-name 34 | :email email}))) 35 | (reset! state/user nil))))) 36 | -------------------------------------------------------------------------------- /increments/25-sign-in-sign-out/src/giggin/fb/auth.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.auth 2 | (:require ["firebase/app" :as firebase] 3 | [giggin.fb.db :refer [db-save!]] 4 | [giggin.state :as state])) 5 | 6 | (defn sign-in-with-google 7 | [] 8 | (let [provider (firebase/auth.GoogleAuthProvider.)] 9 | (.signInWithPopup (firebase/auth) provider))) 10 | 11 | (defn sign-out 12 | [] 13 | (.signOut (firebase/auth))) 14 | 15 | (defn on-auth-state-changed 16 | [] 17 | (.onAuthStateChanged 18 | (firebase/auth) 19 | (fn 20 | [user] 21 | (if user 22 | (let [uid (.-uid user) 23 | display-name (.-displayName user) 24 | photo-url (.-photoURL user) 25 | email (.-email user)] 26 | (do 27 | (reset! state/user {:photo-url photo-url 28 | :display-name display-name 29 | :email email}) 30 | (db-save! 31 | ["users" uid "profile"] 32 | #js {:photo-url photo-url 33 | :display-name display-name 34 | :email email}))) 35 | (reset! state/user nil))))) 36 | -------------------------------------------------------------------------------- /increments/29-tips-and-tricks/src/giggin/fb/auth.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.fb.auth 2 | (:require ["firebase/app" :as firebase] 3 | [giggin.fb.db :refer [db-save!]] 4 | [giggin.state :as state])) 5 | 6 | (defn sign-in-with-google 7 | [] 8 | (let [provider (firebase/auth.GoogleAuthProvider.)] 9 | (.signInWithPopup (firebase/auth) provider))) 10 | 11 | (defn sign-out 12 | [] 13 | (.signOut (firebase/auth))) 14 | 15 | (defn on-auth-state-changed 16 | [] 17 | (.onAuthStateChanged 18 | (firebase/auth) 19 | (fn 20 | [user] 21 | (if user 22 | (let [uid (.-uid user) 23 | display-name (.-displayName user) 24 | photo-url (.-photoURL user) 25 | email (.-email user)] 26 | (do 27 | (reset! state/user {:photo-url photo-url 28 | :display-name display-name 29 | :email email}) 30 | (db-save! 31 | ["users" uid "profile"] 32 | #js {:photo-url photo-url 33 | :display-name display-name 34 | :email email}))) 35 | (reset! state/user nil))))) 36 | -------------------------------------------------------------------------------- /increments/11-format-price/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state])) 3 | 4 | (defn total 5 | [] 6 | (->> @state/orders 7 | (map (fn [[id quant]] (* quant (get-in @state/gigs [id :price])))) 8 | (reduce +))) 9 | 10 | (defn orders 11 | [] 12 | [:aside 13 | [:div.order 14 | [:div.body 15 | (for [[id quant] @state/orders] 16 | [:div.item {:key id} 17 | [:div.img 18 | [:img {:src (get-in @state/gigs [id :img]) 19 | :alt (get-in @state/gigs [id :title])}]] 20 | [:div.content 21 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 22 | [:div.action 23 | [:div.price (* (get-in @state/gigs [id :price]) quant)] 24 | [:button.btn.btn--link.tooltip 25 | {:data-tooltip "Remove" 26 | :on-click (fn [] (swap! state/orders dissoc id))} 27 | [:i.icon.icon--cross]]]])] 28 | [:div.total 29 | [:hr] 30 | [:div.item 31 | [:div.content "Total"] 32 | [:div.action 33 | [:div.price (total)]] 34 | [:button.btn.btn--link.tooltip 35 | {:data-tooltip "Remove all" 36 | :on-click (fn [] (reset! state/orders {}))} 37 | [:i.icon.icon--delete]]]]]]) 38 | -------------------------------------------------------------------------------- /increments/15-save-gig/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.gig-editor :refer [gig-editor]] 5 | [reagent.core :as r])) 6 | 7 | (defn gigs 8 | [] 9 | (let [modal (r/atom false) 10 | values (r/atom {:id nil :title "" :desc "" :price 0 :img "" :sold-out false}) 11 | add-to-order #(swap! state/orders update % inc)] 12 | (fn 13 | [] 14 | [:main 15 | [:div.gigs 16 | [:button.add-gig 17 | {:on-click #(reset! modal true)} 18 | [:div.add__title 19 | [:i.icon.icon--plus] 20 | [:p "Add gig"]]] 21 | [gig-editor modal values] 22 | (for [{:keys [id img title price desc]} (vals @state/gigs)] 23 | [:div.gig {:key id} 24 | [:img.gig__artwork {:src img :alt title}] 25 | [:div.gig__body 26 | [:div.gig__title 27 | [:div.btn.btn--primary.float--right.tooltip 28 | {:data-tooltip "Add to order" 29 | :on-click #(add-to-order id)} 30 | [:i.icon.icon--plus]] title] 31 | [:p.gig__price (format-price price)] 32 | [:p.gig__desc desc]]])]]))) 33 | -------------------------------------------------------------------------------- /increments/12-refactor-functions/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]])) 4 | 5 | (defn total 6 | [] 7 | (->> @state/orders 8 | (map (fn [[id quant]] (* quant (get-in @state/gigs [id :price])))) 9 | (reduce +))) 10 | 11 | (defn orders 12 | [] 13 | [:aside 14 | (if (empty? @state/orders) 15 | [:div.empty 16 | [:div.title "You don't have any orders"] 17 | [:div.subtitle "Click on a + to add an order"]] 18 | [:div.order 19 | [:div.body 20 | (for [[id quant] @state/orders] 21 | [:div.item {:key id} 22 | [:div.img 23 | [:img {:src (get-in @state/gigs [id :img]) 24 | :alt (get-in @state/gigs [id :title])}]] 25 | [:div.content 26 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 27 | [:div.action 28 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))] 29 | [:button.btn.btn--link.tooltip 30 | {:data-tooltip "Remove" 31 | :on-click (fn [] (swap! state/orders dissoc id))} 32 | [:i.icon.icon--cross]]]])] 33 | [:div.total 34 | [:hr] 35 | [:div.item 36 | [:div.content "Total"] 37 | [:div.action 38 | [:div.price (format-price (total))]] 39 | [:button.btn.btn--link.tooltip 40 | {:data-tooltip "Remove all" 41 | :on-click (fn [] (reset! state/orders {}))} 42 | [:i.icon.icon--delete]]]]])]) 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![alt learn-reagent-logo](https://res.cloudinary.com/schae/image/upload/f_auto,q_auto/v1523483980/giggin/learn-cljs-reagent.png) 2 | 3 | # [LearnReagent.com](https://www.learnreagent.com) 4 | 5 | Learn simple, clean, and robust way to build SPA (Single-Page Applications) with ClojureScript & Reagent. Build GIGGIN an app that shows local gigs. Step-by-step, component-by-component we'll learn how to build SPAs with ClojureScript. We'll work with remote API. Learn how easy it is to interop with JS and npm and much more … . This video course will take you from zero to deployment in a few afternoons. 6 | 7 | ## Course files 8 | 9 | The code in this repo is split into two folders - `giggin` - starting point of the videos (this is what you should open when you start to code along with the vidoes) and - `increments` - code for the start of each video (if you get lost somewhere along the way just copy the content of the video you are starting and continue). 10 | 11 | ### Clone 12 | 13 | ```shell 14 | $ git clone git@github.com:jacekschae/learn-reagent-course-files.git 15 | 16 | $ cd learn-reagent-course-files/giggin/ 17 | ``` 18 | 19 | ### Install 20 | 21 | ```shell 22 | learn-reagent-course-files/giggin/ $ npm install 23 | ``` 24 | 25 | or with yarn 26 | 27 | ```shell 28 | learn-reagent-course-files/giggin/ $ yarn install 29 | ``` 30 | 31 | ### Run development server 32 | 33 | ```shell 34 | learn-reagent-course-files/giggin/ $ npm run dev 35 | ``` 36 | 37 | or with yarn 38 | 39 | ```shell 40 | learn-reagent-course-files/giggin/ $ yarn dev 41 | ``` 42 | 43 | ## License 44 | 45 | Copyright © 2018 Jacek Schae 46 | -------------------------------------------------------------------------------- /increments/13-checkout-modal/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]])) 4 | 5 | (defn total 6 | [] 7 | (->> @state/orders 8 | (map (fn [[id quant]] (* quant (get-in @state/gigs [id :price])))) 9 | (reduce +))) 10 | 11 | (defn orders 12 | [] 13 | (let [remove-from-order #(swap! state/orders dissoc %) 14 | remove-all-orders #(reset! state/orders {})] 15 | [:aside 16 | (if (empty? @state/orders) 17 | [:div.empty 18 | [:div.title "You don't have any orders"] 19 | [:div.subtitle "Click on a + to add an order"]] 20 | [:div.order 21 | [:div.body 22 | (for [[id quant] @state/orders] 23 | [:div.item {:key id} 24 | [:div.img 25 | [:img {:src (get-in @state/gigs [id :img]) 26 | :alt (get-in @state/gigs [id :title])}]] 27 | [:div.content 28 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 29 | [:div.action 30 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))] 31 | [:button.btn.btn--link.tooltip 32 | {:data-tooltip "Remove" 33 | :on-click #(remove-from-order id)} 34 | [:i.icon.icon--cross]]]])] 35 | [:div.total 36 | [:hr] 37 | [:div.item 38 | [:div.content "Total"] 39 | [:div.action 40 | [:div.price (format-price (total))]] 41 | [:button.btn.btn--link.tooltip 42 | {:data-tooltip "Remove all" 43 | :on-click #(remove-all-orders)} 44 | [:i.icon.icon--delete]]]]])])) 45 | -------------------------------------------------------------------------------- /increments/15-save-gig/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [modal values] 14 | [:div.modal (when @modal {:class "active"}) 15 | [:div.modal__overlay] 16 | [:div.modal__container 17 | [:div.modal__body 18 | [form-group {:id "title" 19 | :type "text" 20 | :value (:title @values) 21 | :values values}] 22 | [form-group {:id "desc" 23 | :type "text" 24 | :value (:desc @values) 25 | :values values}] 26 | [form-group {:id "img" 27 | :type "text" 28 | :value (:img @values) 29 | :values values}] 30 | [form-group {:id "price" 31 | :type "number" 32 | :value (:price @values) 33 | :values values}] 34 | [:div.form__group 35 | [:label.form__label {:for "sold-out"} "sold-out"] 36 | [:label.form__switch 37 | [:input {:type :checkbox 38 | :checked (:sold-out @values) 39 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 40 | [:i.form__icon]]]] 41 | [:div.modal__footer 42 | [:button.btn.btn--link.float--left 43 | {:on-click #(reset! modal false)} 44 | "Cancel"] 45 | [:button.btn.btn--secondary 46 | "Save"]]]]) 47 | -------------------------------------------------------------------------------- /increments/16-update-gig/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [modal values insert-gig] 14 | [:div.modal (when @modal {:class "active"}) 15 | [:div.modal__overlay] 16 | [:div.modal__container 17 | [:div.modal__body 18 | [form-group {:id "title" 19 | :type "text" 20 | :value (:title @values) 21 | :values values}] 22 | [form-group {:id "desc" 23 | :type "text" 24 | :value (:desc @values) 25 | :values values}] 26 | [form-group {:id "img" 27 | :type "text" 28 | :value (:img @values) 29 | :values values}] 30 | [form-group {:id "price" 31 | :type "number" 32 | :value (:price @values) 33 | :values values}] 34 | [:div.form__group 35 | [:label.form__label {:for "sold-out"} "sold-out"] 36 | [:label.form__switch 37 | [:input {:type :checkbox 38 | :checked (:sold-out @values) 39 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 40 | [:i.form__icon]]]] 41 | [:div.modal__footer 42 | [:button.btn.btn--link.float--left 43 | {:on-click #(reset! modal false)} 44 | "Cancel"] 45 | [:button.btn.btn--secondary 46 | {:on-click #(insert-gig @values)} 47 | "Save"]]]]) 48 | -------------------------------------------------------------------------------- /increments/15-save-gig/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]])) 5 | 6 | (defn total 7 | [] 8 | (->> @state/orders 9 | (map (fn [[id quant]] (* quant (get-in @state/gigs [id :price])))) 10 | (reduce +))) 11 | 12 | (defn orders 13 | [] 14 | (let [remove-from-order #(swap! state/orders dissoc %) 15 | remove-all-orders #(reset! state/orders {})] 16 | [:aside 17 | (if (empty? @state/orders) 18 | [:div.empty 19 | [:div.title "You don't have any orders"] 20 | [:div.subtitle "Click on a + to add an order"]] 21 | [:div.order 22 | [:div.body 23 | (for [[id quant] @state/orders] 24 | [:div.item {:key id} 25 | [:div.img 26 | [:img {:src (get-in @state/gigs [id :img]) 27 | :alt (get-in @state/gigs [id :title])}]] 28 | [:div.content 29 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 30 | [:div.action 31 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))] 32 | [:button.btn.btn--link.tooltip 33 | {:data-tooltip "Remove" 34 | :on-click #(remove-from-order id)} 35 | [:i.icon.icon--cross]]]])] 36 | [:div.total 37 | [:hr] 38 | [:div.item 39 | [:div.content "Total"] 40 | [:div.action 41 | [:div.price (format-price (total))]] 42 | [:button.btn.btn--link.tooltip 43 | {:data-tooltip "Remove all" 44 | :on-click #(remove-all-orders)} 45 | [:i.icon.icon--delete]]] 46 | [checkout-modal]]])])) 47 | -------------------------------------------------------------------------------- /increments/14-gig-editor/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]])) 5 | 6 | (defn total 7 | [] 8 | (->> @state/orders 9 | (map (fn [[id quant]] (* quant (get-in @state/gigs [id :price])))) 10 | (reduce +))) 11 | 12 | (defn orders 13 | [] 14 | (let [remove-from-order #(swap! state/orders dissoc %) 15 | remove-all-orders #(reset! state/orders {})] 16 | [:aside 17 | (if (empty? @state/orders) 18 | [:div.empty 19 | [:div.title "You don't have any orders"] 20 | [:div.subtitle "Click on a + to add an order"]] 21 | [:div.order 22 | [:div.body 23 | (for [[id quant] @state/orders] 24 | [:div.item {:key id} 25 | [:div.img 26 | [:img {:src (get-in @state/gigs [id :img]) 27 | :alt (get-in @state/gigs [id :title])}]] 28 | [:div.content 29 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 30 | [:div.action 31 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))] 32 | [:button.btn.btn--link.tooltip 33 | {:data-tooltip "Remove" 34 | :on-click #(remove-from-order id)} 35 | [:i.icon.icon--cross]]]])] 36 | [:div.total 37 | [:hr] 38 | [:div.item 39 | [:div.content "Total"] 40 | [:div.action 41 | [:div.price (format-price (total))]] 42 | [:button.btn.btn--link.tooltip 43 | {:data-tooltip "Remove all" 44 | :on-click #(remove-all-orders)} 45 | [:i.icon.icon--delete]]] 46 | [checkout-modal]]])])) 47 | -------------------------------------------------------------------------------- /increments/16-update-gig/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]])) 5 | 6 | (defn total 7 | [] 8 | (->> @state/orders 9 | (map (fn [[id quant]] (* quant (get-in @state/gigs [id :price])))) 10 | (reduce +))) 11 | 12 | (defn orders 13 | [] 14 | (let [remove-from-order #(swap! state/orders dissoc %) 15 | remove-all-orders #(reset! state/orders {})] 16 | [:aside 17 | (if (empty? @state/orders) 18 | [:div.empty 19 | [:div.title "You don't have any orders"] 20 | [:div.subtitle "Click on a + to add an order"]] 21 | [:div.order 22 | [:div.body 23 | (for [[id quant] @state/orders] 24 | [:div.item {:key id} 25 | [:div.img 26 | [:img {:src (get-in @state/gigs [id :img]) 27 | :alt (get-in @state/gigs [id :title])}]] 28 | [:div.content 29 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 30 | [:div.action 31 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))] 32 | [:button.btn.btn--link.tooltip 33 | {:data-tooltip "Remove" 34 | :on-click #(remove-from-order id)} 35 | [:i.icon.icon--cross]]]])] 36 | [:div.total 37 | [:hr] 38 | [:div.item 39 | [:div.content "Total"] 40 | [:div.action 41 | [:div.price (format-price (total))]] 42 | [:button.btn.btn--link.tooltip 43 | {:data-tooltip "Remove all" 44 | :on-click #(remove-all-orders)} 45 | [:i.icon.icon--delete]]] 46 | [checkout-modal]]])])) 47 | -------------------------------------------------------------------------------- /increments/17-refactor-gigs/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [modal values upsert-gig toggle-modal] 14 | [:div.modal (when (:active @modal) {:class "active"}) 15 | [:div.modal__overlay] 16 | [:div.modal__container 17 | [:div.modal__body 18 | [form-group {:id "title" 19 | :type "text" 20 | :value (:title @values) 21 | :values values}] 22 | [form-group {:id "desc" 23 | :type "text" 24 | :value (:desc @values) 25 | :values values}] 26 | [form-group {:id "img" 27 | :type "text" 28 | :value (:img @values) 29 | :values values}] 30 | [form-group {:id "price" 31 | :type "number" 32 | :value (:price @values) 33 | :values values}] 34 | [:div.form__group 35 | [:label.form__label {:for "sold-out"} "sold-out"] 36 | [:label.form__switch 37 | [:input {:type :checkbox 38 | :checked (:sold-out @values) 39 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 40 | [:i.form__icon]]]] 41 | [:div.modal__footer 42 | [:button.btn.btn--link.float--left 43 | {:on-click #(toggle-modal {:active false :gig {}})} 44 | "Cancel"] 45 | [:button.btn.btn--secondary 46 | {:on-click #(upsert-gig @values)} 47 | "Save"]]]]) 48 | -------------------------------------------------------------------------------- /increments/17-refactor-gigs/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]])) 5 | 6 | (defn total 7 | [] 8 | (->> @state/orders 9 | (map (fn [[id quant]] (* quant (get-in @state/gigs [id :price])))) 10 | (reduce +))) 11 | 12 | (defn orders 13 | [] 14 | (let [remove-from-order #(swap! state/orders dissoc %) 15 | remove-all-orders #(reset! state/orders {})] 16 | [:aside 17 | (if (empty? @state/orders) 18 | [:div.empty 19 | [:div.title "You don't have any orders"] 20 | [:div.subtitle "Click on a + to add an order"]] 21 | [:div.order 22 | [:div.body 23 | (for [[id quant] @state/orders] 24 | [:div.item {:key id} 25 | [:div.img 26 | [:img {:src (get-in @state/gigs [id :img]) 27 | :alt (get-in @state/gigs [id :title])}]] 28 | [:div.content 29 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 30 | [:div.action 31 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))] 32 | [:button.btn.btn--link.tooltip 33 | {:data-tooltip "Remove" 34 | :on-click #(remove-from-order id)} 35 | [:i.icon.icon--cross]]]])] 36 | [:div.total 37 | [:hr] 38 | [:div.item 39 | [:div.content "Total"] 40 | [:div.action 41 | [:div.price (format-price (total))]] 42 | [:button.btn.btn--link.tooltip 43 | {:data-tooltip "Remove all" 44 | :on-click #(remove-all-orders)} 45 | [:i.icon.icon--delete]]] 46 | [checkout-modal]]])])) 47 | -------------------------------------------------------------------------------- /increments/18-ajax-requests/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]])) 5 | 6 | (defn total 7 | [] 8 | (->> @state/orders 9 | (map (fn [[id quant]] (* quant (get-in @state/gigs [id :price])))) 10 | (reduce +))) 11 | 12 | (defn orders 13 | [] 14 | (let [remove-from-order #(swap! state/orders dissoc %) 15 | remove-all-orders #(reset! state/orders {})] 16 | [:aside 17 | (if (empty? @state/orders) 18 | [:div.empty 19 | [:div.title "You don't have any orders"] 20 | [:div.subtitle "Click on a + to add an order"]] 21 | [:div.order 22 | [:div.body 23 | (for [[id quant] @state/orders] 24 | [:div.item {:key id} 25 | [:div.img 26 | [:img {:src (get-in @state/gigs [id :img]) 27 | :alt (get-in @state/gigs [id :title])}]] 28 | [:div.content 29 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 30 | [:div.action 31 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))] 32 | [:button.btn.btn--link.tooltip 33 | {:data-tooltip "Remove" 34 | :on-click #(remove-from-order id)} 35 | [:i.icon.icon--cross]]]])] 36 | [:div.total 37 | [:hr] 38 | [:div.item 39 | [:div.content "Total"] 40 | [:div.action 41 | [:div.price (format-price (total))]] 42 | [:button.btn.btn--link.tooltip 43 | {:data-tooltip "Remove all" 44 | :on-click #(remove-all-orders)} 45 | [:i.icon.icon--delete]]] 46 | [checkout-modal]]])])) 47 | -------------------------------------------------------------------------------- /increments/20-firebase-setup/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]])) 5 | 6 | (defn total 7 | [] 8 | (->> @state/orders 9 | (map (fn [[id quant]] (* quant (get-in @state/gigs [id :price])))) 10 | (reduce +))) 11 | 12 | (defn orders 13 | [] 14 | (let [remove-from-order #(swap! state/orders dissoc %) 15 | remove-all-orders #(reset! state/orders {})] 16 | [:aside 17 | (if (empty? @state/orders) 18 | [:div.empty 19 | [:div.title "You don't have any orders"] 20 | [:div.subtitle "Click on a + to add an order"]] 21 | [:div.order 22 | [:div.body 23 | (for [[id quant] @state/orders] 24 | [:div.item {:key id} 25 | [:div.img 26 | [:img {:src (get-in @state/gigs [id :img]) 27 | :alt (get-in @state/gigs [id :title])}]] 28 | [:div.content 29 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 30 | [:div.action 31 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))] 32 | [:button.btn.btn--link.tooltip 33 | {:data-tooltip "Remove" 34 | :on-click #(remove-from-order id)} 35 | [:i.icon.icon--cross]]]])] 36 | [:div.total 37 | [:hr] 38 | [:div.item 39 | [:div.content "Total"] 40 | [:div.action 41 | [:div.price (format-price (total))]] 42 | [:button.btn.btn--link.tooltip 43 | {:data-tooltip "Remove all" 44 | :on-click #(remove-all-orders)} 45 | [:i.icon.icon--delete]]] 46 | [checkout-modal]]])])) 47 | -------------------------------------------------------------------------------- /increments/21-firebase-database/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]])) 5 | 6 | (defn total 7 | [] 8 | (->> @state/orders 9 | (map (fn [[id quant]] (* quant (get-in @state/gigs [id :price])))) 10 | (reduce +))) 11 | 12 | (defn orders 13 | [] 14 | (let [remove-from-order #(swap! state/orders dissoc %) 15 | remove-all-orders #(reset! state/orders {})] 16 | [:aside 17 | (if (empty? @state/orders) 18 | [:div.empty 19 | [:div.title "You don't have any orders"] 20 | [:div.subtitle "Click on a + to add an order"]] 21 | [:div.order 22 | [:div.body 23 | (for [[id quant] @state/orders] 24 | [:div.item {:key id} 25 | [:div.img 26 | [:img {:src (get-in @state/gigs [id :img]) 27 | :alt (get-in @state/gigs [id :title])}]] 28 | [:div.content 29 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 30 | [:div.action 31 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))] 32 | [:button.btn.btn--link.tooltip 33 | {:data-tooltip "Remove" 34 | :on-click #(remove-from-order id)} 35 | [:i.icon.icon--cross]]]])] 36 | [:div.total 37 | [:hr] 38 | [:div.item 39 | [:div.content "Total"] 40 | [:div.action 41 | [:div.price (format-price (total))]] 42 | [:button.btn.btn--link.tooltip 43 | {:data-tooltip "Remove all" 44 | :on-click #(remove-all-orders)} 45 | [:i.icon.icon--delete]]] 46 | [checkout-modal]]])])) 47 | -------------------------------------------------------------------------------- /increments/19-ajax-transformations/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]])) 5 | 6 | (defn total 7 | [] 8 | (->> @state/orders 9 | (map (fn [[id quant]] (* quant (get-in @state/gigs [id :price])))) 10 | (reduce +))) 11 | 12 | (defn orders 13 | [] 14 | (let [remove-from-order #(swap! state/orders dissoc %) 15 | remove-all-orders #(reset! state/orders {})] 16 | [:aside 17 | (if (empty? @state/orders) 18 | [:div.empty 19 | [:div.title "You don't have any orders"] 20 | [:div.subtitle "Click on a + to add an order"]] 21 | [:div.order 22 | [:div.body 23 | (for [[id quant] @state/orders] 24 | [:div.item {:key id} 25 | [:div.img 26 | [:img {:src (get-in @state/gigs [id :img]) 27 | :alt (get-in @state/gigs [id :title])}]] 28 | [:div.content 29 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 30 | [:div.action 31 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))] 32 | [:button.btn.btn--link.tooltip 33 | {:data-tooltip "Remove" 34 | :on-click #(remove-from-order id)} 35 | [:i.icon.icon--cross]]]])] 36 | [:div.total 37 | [:hr] 38 | [:div.item 39 | [:div.content "Total"] 40 | [:div.action 41 | [:div.price (format-price (total))]] 42 | [:button.btn.btn--link.tooltip 43 | {:data-tooltip "Remove all" 44 | :on-click #(remove-all-orders)} 45 | [:i.icon.icon--delete]]] 46 | [checkout-modal]]])])) 47 | -------------------------------------------------------------------------------- /increments/16-update-gig/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.gig-editor :refer [gig-editor]] 5 | [reagent.core :as r] 6 | [clojure.string :as str])) 7 | 8 | (defn gigs 9 | [] 10 | (let [modal (r/atom false) 11 | values (r/atom {:id (str "gig-" (random-uuid)) :title "" :desc "" :price 0 :img "" :sold-out false}) 12 | add-to-order #(swap! state/orders update % inc) 13 | insert-gig (fn [{:keys [id title desc price img sold-out]}] 14 | (swap! state/gigs assoc id {:id id 15 | :title (str/trim title) 16 | :desc (str/trim desc) 17 | :img (str/trim img) 18 | :price (js/parseInt price) 19 | :sold-out sold-out}) 20 | (reset! modal false))] 21 | (fn 22 | [] 23 | [:main 24 | [:div.gigs 25 | [:button.add-gig 26 | {:on-click #(reset! modal true)} 27 | [:div.add__title 28 | [:i.icon.icon--plus] 29 | [:p "Add gig"]]] 30 | [gig-editor modal values insert-gig] 31 | (for [{:keys [id img title price desc]} (vals @state/gigs)] 32 | [:div.gig {:key id} 33 | [:img.gig__artwork {:src img :alt title}] 34 | [:div.gig__body 35 | [:div.gig__title 36 | [:div.btn.btn--primary.float--right.tooltip 37 | {:data-tooltip "Add to order" 38 | :on-click #(add-to-order id)} 39 | [:i.icon.icon--plus]] title] 40 | [:p.gig__price (format-price price)] 41 | [:p.gig__desc desc]]])]]))) 42 | -------------------------------------------------------------------------------- /giggin/public/img/stripe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 12 | 15 | 16 | 17 | 18 | 20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /increments/02-app-setup/public/img/stripe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 12 | 15 | 16 | 17 | 18 | 20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /increments/complete/public/img/stripe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 12 | 15 | 16 | 17 | 18 | 20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /increments/complete/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [{:keys [modal values upsert-gig toggle-modal initial-values]}] 14 | (let [{:keys [title desc img price sold-out]} @values] 15 | [:div.modal (when (:active @modal) {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [form-group {:id "title" 20 | :type "text" 21 | :value title 22 | :values values}] 23 | [form-group {:id "desc" 24 | :type "text" 25 | :value desc 26 | :values values}] 27 | [form-group {:id "img" 28 | :type "text" 29 | :value img 30 | :values values}] 31 | [form-group {:id "price" 32 | :type "number" 33 | :value price 34 | :values values}] 35 | [:div.form__group 36 | [:label.form__label {:for "sold-out"} "sold-out"] 37 | [:label.form__switch 38 | [:input {:type :checkbox 39 | :checked sold-out 40 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 41 | [:i.form__icon]]]] 42 | [:div.modal__footer 43 | [:button.btn.btn--link.float--left 44 | {:on-click #(toggle-modal {:active false :gig initial-values})} 45 | "Cancel"] 46 | [:button.btn.btn--secondary 47 | {:on-click #(upsert-gig @values)} 48 | "Save"]]]])) 49 | -------------------------------------------------------------------------------- /increments/22-subscribe/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [{:keys [modal values upsert-gig toggle-modal initial-values]}] 14 | (let [{:keys [title desc img price sold-out]} @values] 15 | [:div.modal (when (:active @modal) {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [form-group {:id "title" 20 | :type "text" 21 | :value title 22 | :values values}] 23 | [form-group {:id "desc" 24 | :type "text" 25 | :value desc 26 | :values values}] 27 | [form-group {:id "img" 28 | :type "text" 29 | :value img 30 | :values values}] 31 | [form-group {:id "price" 32 | :type "number" 33 | :value price 34 | :values values}] 35 | [:div.form__group 36 | [:label.form__label {:for "sold-out"} "sold-out"] 37 | [:label.form__switch 38 | [:input {:type :checkbox 39 | :checked sold-out 40 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 41 | [:i.form__icon]]]] 42 | [:div.modal__footer 43 | [:button.btn.btn--link.float--left 44 | {:on-click #(toggle-modal {:active false :gig initial-values})} 45 | "Cancel"] 46 | [:button.btn.btn--secondary 47 | {:on-click #(upsert-gig @values)} 48 | "Save"]]]])) 49 | -------------------------------------------------------------------------------- /increments/23-sold-out/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [{:keys [modal values upsert-gig toggle-modal initial-values]}] 14 | (let [{:keys [title desc img price sold-out]} @values] 15 | [:div.modal (when (:active @modal) {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [form-group {:id "title" 20 | :type "text" 21 | :value title 22 | :values values}] 23 | [form-group {:id "desc" 24 | :type "text" 25 | :value desc 26 | :values values}] 27 | [form-group {:id "img" 28 | :type "text" 29 | :value img 30 | :values values}] 31 | [form-group {:id "price" 32 | :type "number" 33 | :value price 34 | :values values}] 35 | [:div.form__group 36 | [:label.form__label {:for "sold-out"} "sold-out"] 37 | [:label.form__switch 38 | [:input {:type :checkbox 39 | :checked sold-out 40 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 41 | [:i.form__icon]]]] 42 | [:div.modal__footer 43 | [:button.btn.btn--link.float--left 44 | {:on-click #(toggle-modal {:active false :gig initial-values})} 45 | "Cancel"] 46 | [:button.btn.btn--secondary 47 | {:on-click #(upsert-gig @values)} 48 | "Save"]]]])) 49 | -------------------------------------------------------------------------------- /increments/28-performance-url/src/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [{:keys [modal values upsert-gig toggle-modal initial-values]}] 14 | (let [{:keys [title desc img price sold-out]} @values] 15 | [:div.modal (when (:active @modal) {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [form-group {:id "title" 20 | :type "text" 21 | :value title 22 | :values values}] 23 | [form-group {:id "desc" 24 | :type "text" 25 | :value desc 26 | :values values}] 27 | [form-group {:id "img" 28 | :type "text" 29 | :value img 30 | :values values}] 31 | [form-group {:id "price" 32 | :type "number" 33 | :value price 34 | :values values}] 35 | [:div.form__group 36 | [:label.form__label {:for "sold-out"} "sold-out"] 37 | [:label.form__switch 38 | [:input {:type :checkbox 39 | :checked sold-out 40 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 41 | [:i.form__icon]]]] 42 | [:div.modal__footer 43 | [:button.btn.btn--link.float--left 44 | {:on-click #(toggle-modal {:active false :gig initial-values})} 45 | "Cancel"] 46 | [:button.btn.btn--secondary 47 | {:on-click #(upsert-gig @values)} 48 | "Save"]]]])) 49 | -------------------------------------------------------------------------------- /increments/complete/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Page Not Found 7 | 8 | 23 | 24 | 25 |
26 |

404

27 |

Page Not Found

28 |

The specified file was not found on this website. Please check the URL for mistakes and try again.

29 |

Why am I seeing this?

30 |

This page was generated by the Firebase Command-Line Interface. To modify it, edit the 404.html file in your project's configured public directory.

31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /increments/18-ajax-requests/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [{:keys [modal values upsert-gig toggle-modal initial-values]}] 14 | (let [{:keys [title desc img price sold-out]} @values] 15 | [:div.modal (when (:active @modal) {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [form-group {:id "title" 20 | :type "text" 21 | :value title 22 | :values values}] 23 | [form-group {:id "desc" 24 | :type "text" 25 | :value desc 26 | :values values}] 27 | [form-group {:id "img" 28 | :type "text" 29 | :value img 30 | :values values}] 31 | [form-group {:id "price" 32 | :type "number" 33 | :value price 34 | :values values}] 35 | [:div.form__group 36 | [:label.form__label {:for "sold-out"} "sold-out"] 37 | [:label.form__switch 38 | [:input {:type :checkbox 39 | :checked sold-out 40 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 41 | [:i.form__icon]]]] 42 | [:div.modal__footer 43 | [:button.btn.btn--link.float--left 44 | {:on-click #(toggle-modal {:active false :gig initial-values})} 45 | "Cancel"] 46 | [:button.btn.btn--secondary 47 | {:on-click #(upsert-gig @values)} 48 | "Save"]]]])) 49 | -------------------------------------------------------------------------------- /increments/20-firebase-setup/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [{:keys [modal values upsert-gig toggle-modal initial-values]}] 14 | (let [{:keys [title desc img price sold-out]} @values] 15 | [:div.modal (when (:active @modal) {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [form-group {:id "title" 20 | :type "text" 21 | :value title 22 | :values values}] 23 | [form-group {:id "desc" 24 | :type "text" 25 | :value desc 26 | :values values}] 27 | [form-group {:id "img" 28 | :type "text" 29 | :value img 30 | :values values}] 31 | [form-group {:id "price" 32 | :type "number" 33 | :value price 34 | :values values}] 35 | [:div.form__group 36 | [:label.form__label {:for "sold-out"} "sold-out"] 37 | [:label.form__switch 38 | [:input {:type :checkbox 39 | :checked sold-out 40 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 41 | [:i.form__icon]]]] 42 | [:div.modal__footer 43 | [:button.btn.btn--link.float--left 44 | {:on-click #(toggle-modal {:active false :gig initial-values})} 45 | "Cancel"] 46 | [:button.btn.btn--secondary 47 | {:on-click #(upsert-gig @values)} 48 | "Save"]]]])) 49 | -------------------------------------------------------------------------------- /increments/24-firebase-auth/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [{:keys [modal values upsert-gig toggle-modal initial-values]}] 14 | (let [{:keys [title desc img price sold-out]} @values] 15 | [:div.modal (when (:active @modal) {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [form-group {:id "title" 20 | :type "text" 21 | :value title 22 | :values values}] 23 | [form-group {:id "desc" 24 | :type "text" 25 | :value desc 26 | :values values}] 27 | [form-group {:id "img" 28 | :type "text" 29 | :value img 30 | :values values}] 31 | [form-group {:id "price" 32 | :type "number" 33 | :value price 34 | :values values}] 35 | [:div.form__group 36 | [:label.form__label {:for "sold-out"} "sold-out"] 37 | [:label.form__switch 38 | [:input {:type :checkbox 39 | :checked sold-out 40 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 41 | [:i.form__icon]]]] 42 | [:div.modal__footer 43 | [:button.btn.btn--link.float--left 44 | {:on-click #(toggle-modal {:active false :gig initial-values})} 45 | "Cancel"] 46 | [:button.btn.btn--secondary 47 | {:on-click #(upsert-gig @values)} 48 | "Save"]]]])) 49 | -------------------------------------------------------------------------------- /increments/26-security-rules/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [{:keys [modal values upsert-gig toggle-modal initial-values]}] 14 | (let [{:keys [title desc img price sold-out]} @values] 15 | [:div.modal (when (:active @modal) {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [form-group {:id "title" 20 | :type "text" 21 | :value title 22 | :values values}] 23 | [form-group {:id "desc" 24 | :type "text" 25 | :value desc 26 | :values values}] 27 | [form-group {:id "img" 28 | :type "text" 29 | :value img 30 | :values values}] 31 | [form-group {:id "price" 32 | :type "number" 33 | :value price 34 | :values values}] 35 | [:div.form__group 36 | [:label.form__label {:for "sold-out"} "sold-out"] 37 | [:label.form__switch 38 | [:input {:type :checkbox 39 | :checked sold-out 40 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 41 | [:i.form__icon]]]] 42 | [:div.modal__footer 43 | [:button.btn.btn--link.float--left 44 | {:on-click #(toggle-modal {:active false :gig initial-values})} 45 | "Cancel"] 46 | [:button.btn.btn--secondary 47 | {:on-click #(upsert-gig @values)} 48 | "Save"]]]])) 49 | -------------------------------------------------------------------------------- /increments/29-tips-and-tricks/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [{:keys [modal values upsert-gig toggle-modal initial-values]}] 14 | (let [{:keys [title desc img price sold-out]} @values] 15 | [:div.modal (when (:active @modal) {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [form-group {:id "title" 20 | :type "text" 21 | :value title 22 | :values values}] 23 | [form-group {:id "desc" 24 | :type "text" 25 | :value desc 26 | :values values}] 27 | [form-group {:id "img" 28 | :type "text" 29 | :value img 30 | :values values}] 31 | [form-group {:id "price" 32 | :type "number" 33 | :value price 34 | :values values}] 35 | [:div.form__group 36 | [:label.form__label {:for "sold-out"} "sold-out"] 37 | [:label.form__switch 38 | [:input {:type :checkbox 39 | :checked sold-out 40 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 41 | [:i.form__icon]]]] 42 | [:div.modal__footer 43 | [:button.btn.btn--link.float--left 44 | {:on-click #(toggle-modal {:active false :gig initial-values})} 45 | "Cancel"] 46 | [:button.btn.btn--secondary 47 | {:on-click #(upsert-gig @values)} 48 | "Save"]]]])) 49 | -------------------------------------------------------------------------------- /increments/19-ajax-transformations/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [{:keys [modal values upsert-gig toggle-modal initial-values]}] 14 | (let [{:keys [title desc img price sold-out]} @values] 15 | [:div.modal (when (:active @modal) {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [form-group {:id "title" 20 | :type "text" 21 | :value title 22 | :values values}] 23 | [form-group {:id "desc" 24 | :type "text" 25 | :value desc 26 | :values values}] 27 | [form-group {:id "img" 28 | :type "text" 29 | :value img 30 | :values values}] 31 | [form-group {:id "price" 32 | :type "number" 33 | :value price 34 | :values values}] 35 | [:div.form__group 36 | [:label.form__label {:for "sold-out"} "sold-out"] 37 | [:label.form__switch 38 | [:input {:type :checkbox 39 | :checked sold-out 40 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 41 | [:i.form__icon]]]] 42 | [:div.modal__footer 43 | [:button.btn.btn--link.float--left 44 | {:on-click #(toggle-modal {:active false :gig initial-values})} 45 | "Cancel"] 46 | [:button.btn.btn--secondary 47 | {:on-click #(upsert-gig @values)} 48 | "Save"]]]])) 49 | -------------------------------------------------------------------------------- /increments/21-firebase-database/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [{:keys [modal values upsert-gig toggle-modal initial-values]}] 14 | (let [{:keys [title desc img price sold-out]} @values] 15 | [:div.modal (when (:active @modal) {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [form-group {:id "title" 20 | :type "text" 21 | :value title 22 | :values values}] 23 | [form-group {:id "desc" 24 | :type "text" 25 | :value desc 26 | :values values}] 27 | [form-group {:id "img" 28 | :type "text" 29 | :value img 30 | :values values}] 31 | [form-group {:id "price" 32 | :type "number" 33 | :value price 34 | :values values}] 35 | [:div.form__group 36 | [:label.form__label {:for "sold-out"} "sold-out"] 37 | [:label.form__switch 38 | [:input {:type :checkbox 39 | :checked sold-out 40 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 41 | [:i.form__icon]]]] 42 | [:div.modal__footer 43 | [:button.btn.btn--link.float--left 44 | {:on-click #(toggle-modal {:active false :gig initial-values})} 45 | "Cancel"] 46 | [:button.btn.btn--secondary 47 | {:on-click #(upsert-gig @values)} 48 | "Save"]]]])) 49 | -------------------------------------------------------------------------------- /increments/25-sign-in-sign-out/src/giggin/components/gig_editor.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gig-editor) 2 | 3 | (defn form-group 4 | [{:keys [id type value values]}] 5 | [:div.form__group 6 | [:label.form__label {:for id} id] 7 | [:input.form__input {:type type 8 | :id id 9 | :value value 10 | :on-change #(swap! values assoc (keyword id) (.. % -target -value))}]]) 11 | 12 | (defn gig-editor 13 | [{:keys [modal values upsert-gig toggle-modal initial-values]}] 14 | (let [{:keys [title desc img price sold-out]} @values] 15 | [:div.modal (when (:active @modal) {:class "active"}) 16 | [:div.modal__overlay] 17 | [:div.modal__container 18 | [:div.modal__body 19 | [form-group {:id "title" 20 | :type "text" 21 | :value title 22 | :values values}] 23 | [form-group {:id "desc" 24 | :type "text" 25 | :value desc 26 | :values values}] 27 | [form-group {:id "img" 28 | :type "text" 29 | :value img 30 | :values values}] 31 | [form-group {:id "price" 32 | :type "number" 33 | :value price 34 | :values values}] 35 | [:div.form__group 36 | [:label.form__label {:for "sold-out"} "sold-out"] 37 | [:label.form__switch 38 | [:input {:type :checkbox 39 | :checked sold-out 40 | :on-change #(swap! values assoc :sold-out (.. % -target -checked))}] 41 | [:i.form__icon]]]] 42 | [:div.modal__footer 43 | [:button.btn.btn--link.float--left 44 | {:on-click #(toggle-modal {:active false :gig initial-values})} 45 | "Cancel"] 46 | [:button.btn.btn--secondary 47 | {:on-click #(upsert-gig @values)} 48 | "Save"]]]])) 49 | -------------------------------------------------------------------------------- /increments/23-sold-out/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]] 5 | [giggin.components.admin-panel :refer [admin-panel]])) 6 | 7 | (defn total 8 | [] 9 | (->> @state/orders 10 | (map (fn [[id quant]] (* quant (get-in @state/gigs [id :price])))) 11 | (reduce +))) 12 | 13 | (defn orders 14 | [] 15 | (let [remove-from-order #(swap! state/orders dissoc %) 16 | remove-all-orders #(reset! state/orders {})] 17 | [:aside 18 | [admin-panel] 19 | (if (empty? @state/orders) 20 | [:div.empty 21 | [:div.title "You don't have any orders"] 22 | [:div.subtitle "Click on a + to add an order"]] 23 | [:div.order 24 | [:div.body 25 | (doall (for [[id quant] @state/orders] 26 | [:div.item {:key id} 27 | [:div.img 28 | [:img {:src (get-in @state/gigs [id :img]) 29 | :alt (get-in @state/gigs [id :title])}]] 30 | [:div.content 31 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 32 | [:div.action 33 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))] 34 | [:button.btn.btn--link.tooltip 35 | {:data-tooltip "Remove" 36 | :on-click #(remove-from-order id)} 37 | [:i.icon.icon--cross]]]]))] 38 | [:div.total 39 | [:hr] 40 | [:div.item 41 | [:div.content "Total"] 42 | [:div.action 43 | [:div.price (format-price (total))]] 44 | [:button.btn.btn--link.tooltip 45 | {:data-tooltip "Remove all" 46 | :on-click #(remove-all-orders)} 47 | [:i.icon.icon--delete]]] 48 | [checkout-modal]]])])) 49 | -------------------------------------------------------------------------------- /increments/22-subscribe/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]] 5 | [giggin.components.admin-panel :refer [admin-panel]])) 6 | 7 | (defn total 8 | [] 9 | (->> @state/orders 10 | (map (fn [[id quant]] (* quant (get-in @state/gigs [id :price])))) 11 | (reduce +))) 12 | 13 | (defn orders 14 | [] 15 | (let [remove-from-order #(swap! state/orders dissoc %) 16 | remove-all-orders #(reset! state/orders {})] 17 | [:aside 18 | [admin-panel] 19 | (if (empty? @state/orders) 20 | [:div.empty 21 | [:div.title "You don't have any orders"] 22 | [:div.subtitle "Click on a + to add an order"]] 23 | [:div.order 24 | [:div.body 25 | (doall (for [[id quant] @state/orders] 26 | [:div.item {:key id} 27 | [:div.img 28 | [:img {:src (get-in @state/gigs [id :img]) 29 | :alt (get-in @state/gigs [id :title])}]] 30 | [:div.content 31 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)]] 32 | [:div.action 33 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))] 34 | [:button.btn.btn--link.tooltip 35 | {:data-tooltip "Remove" 36 | :on-click #(remove-from-order id)} 37 | [:i.icon.icon--cross]]]]))] 38 | [:div.total 39 | [:hr] 40 | [:div.item 41 | [:div.content "Total"] 42 | [:div.action 43 | [:div.price (format-price (total))]] 44 | [:button.btn.btn--link.tooltip 45 | {:data-tooltip "Remove all" 46 | :on-click #(remove-all-orders)} 47 | [:i.icon.icon--delete]]] 48 | [checkout-modal]]])])) 49 | -------------------------------------------------------------------------------- /increments/complete/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]])) 5 | 6 | (defn total 7 | [] 8 | (->> @state/orders 9 | (map (fn [[id quant]] 10 | (if (get-in @state/gigs [id :sold-out]) 11 | 0 12 | (* quant (get-in @state/gigs [id :price]))))) 13 | (reduce +))) 14 | 15 | (defn orders 16 | [] 17 | (let [remove-from-order #(swap! state/orders dissoc %) 18 | remove-all-orders #(reset! state/orders {})] 19 | [:aside 20 | (if (empty? @state/orders) 21 | [:div.empty 22 | [:div.title "You don't have any orders"] 23 | [:div.subtitle "Click on a + to add an order"]] 24 | [:div.order 25 | [:div.body 26 | (doall (for [[id quant] @state/orders] 27 | (let [gig (id @state/gigs)] 28 | [:div.item {:key id} 29 | [:div.img 30 | [:img {:src (:img gig) 31 | :alt (:title gig)}]] 32 | [:div.content 33 | (if (:sold-out gig) 34 | [:p.sold-out "Sold out"] 35 | [:p.title (:title gig) " \u00D7 " quant])] 36 | [:div.action 37 | (if (:sold-out gig) 38 | [:div.price (format-price 0)] 39 | [:div.price (format-price (* (:price gig) quant))]) 40 | [:button.btn.btn--link.tooltip 41 | {:data-tooltip "Remove" 42 | :on-click #(remove-from-order id)} 43 | [:i.icon.icon--cross]]]])))] 44 | [:div.total 45 | [:hr] 46 | [:div.item 47 | [:div.content "Total"] 48 | [:div.action 49 | [:div.price (format-price (total))]] 50 | [:button.btn.btn--link.tooltip 51 | {:data-tooltip "Remove all" 52 | :on-click #(remove-all-orders)} 53 | [:i.icon.icon--delete]]] 54 | [checkout-modal]]])])) 55 | -------------------------------------------------------------------------------- /increments/29-tips-and-tricks/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]])) 5 | 6 | (defn total 7 | [] 8 | (->> @state/orders 9 | (map (fn [[id quant]] 10 | (if (get-in @state/gigs [id :sold-out]) 11 | 0 12 | (* quant (get-in @state/gigs [id :price]))))) 13 | (reduce +))) 14 | 15 | (defn orders 16 | [] 17 | (let [remove-from-order #(swap! state/orders dissoc %) 18 | remove-all-orders #(reset! state/orders {})] 19 | [:aside 20 | (if (empty? @state/orders) 21 | [:div.empty 22 | [:div.title "You don't have any orders"] 23 | [:div.subtitle "Click on a + to add an order"]] 24 | [:div.order 25 | [:div.body 26 | (doall (for [[id quant] @state/orders] 27 | (let [gig (id @state/gigs)] 28 | [:div.item {:key id} 29 | [:div.img 30 | [:img {:src (:img gig) 31 | :alt (:title gig)}]] 32 | [:div.content 33 | (if (:sold-out gig) 34 | [:p.sold-out "Sold out"] 35 | [:p.title (:title gig) " \u00D7 " quant])] 36 | [:div.action 37 | (if (:sold-out gig) 38 | [:div.price (format-price 0)] 39 | [:div.price (format-price (* (:price gig) quant))]) 40 | [:button.btn.btn--link.tooltip 41 | {:data-tooltip "Remove" 42 | :on-click #(remove-from-order id)} 43 | [:i.icon.icon--cross]]]])))] 44 | [:div.total 45 | [:hr] 46 | [:div.item 47 | [:div.content "Total"] 48 | [:div.action 49 | [:div.price (format-price (total))]] 50 | [:button.btn.btn--link.tooltip 51 | {:data-tooltip "Remove all" 52 | :on-click #(remove-all-orders)} 53 | [:i.icon.icon--delete]]] 54 | [checkout-modal]]])])) 55 | -------------------------------------------------------------------------------- /increments/28-performance-url/src/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]])) 5 | 6 | (defn total 7 | [] 8 | (->> @state/orders 9 | (map (fn [[id quant]] 10 | (if (get-in @state/gigs [id :sold-out]) 11 | 0 12 | (* quant (get-in @state/gigs [id :price]))))) 13 | (reduce +))) 14 | 15 | (defn orders 16 | [] 17 | (let [remove-from-order #(swap! state/orders dissoc %) 18 | remove-all-orders #(reset! state/orders {})] 19 | [:aside 20 | (if (empty? @state/orders) 21 | [:div.empty 22 | [:div.title "You don't have any orders"] 23 | [:div.subtitle "Click on a + to add an order"]] 24 | [:div.order 25 | [:div.body 26 | (doall (for [[id quant] @state/orders] 27 | [:div.item {:key id} 28 | [:div.img 29 | [:img {:src (get-in @state/gigs [id :img]) 30 | :alt (get-in @state/gigs [id :title])}]] 31 | [:div.content 32 | (if (get-in @state/gigs [id :sold-out]) 33 | [:p.sold-out "Sold out"] 34 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)])] 35 | [:div.action 36 | (if (get-in @state/gigs [id :sold-out]) 37 | [:div.price (format-price 0)] 38 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))]) 39 | [:button.btn.btn--link.tooltip 40 | {:data-tooltip "Remove" 41 | :on-click #(remove-from-order id)} 42 | [:i.icon.icon--cross]]]]))] 43 | [:div.total 44 | [:hr] 45 | [:div.item 46 | [:div.content "Total"] 47 | [:div.action 48 | [:div.price (format-price (total))]] 49 | [:button.btn.btn--link.tooltip 50 | {:data-tooltip "Remove all" 51 | :on-click #(remove-all-orders)} 52 | [:i.icon.icon--delete]]] 53 | [checkout-modal]]])])) 54 | -------------------------------------------------------------------------------- /increments/26-security-rules/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]])) 5 | 6 | (defn total 7 | [] 8 | (->> @state/orders 9 | (map (fn [[id quant]] 10 | (if (get-in @state/gigs [id :sold-out]) 11 | 0 12 | (* quant (get-in @state/gigs [id :price]))))) 13 | (reduce +))) 14 | 15 | (defn orders 16 | [] 17 | (let [remove-from-order #(swap! state/orders dissoc %) 18 | remove-all-orders #(reset! state/orders {})] 19 | [:aside 20 | (if (empty? @state/orders) 21 | [:div.empty 22 | [:div.title "You don't have any orders"] 23 | [:div.subtitle "Click on a + to add an order"]] 24 | [:div.order 25 | [:div.body 26 | (doall (for [[id quant] @state/orders] 27 | [:div.item {:key id} 28 | [:div.img 29 | [:img {:src (get-in @state/gigs [id :img]) 30 | :alt (get-in @state/gigs [id :title])}]] 31 | [:div.content 32 | (if (get-in @state/gigs [id :sold-out]) 33 | [:p.sold-out "Sold out"] 34 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)])] 35 | [:div.action 36 | (if (get-in @state/gigs [id :sold-out]) 37 | [:div.price (format-price 0)] 38 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))]) 39 | [:button.btn.btn--link.tooltip 40 | {:data-tooltip "Remove" 41 | :on-click #(remove-from-order id)} 42 | [:i.icon.icon--cross]]]]))] 43 | [:div.total 44 | [:hr] 45 | [:div.item 46 | [:div.content "Total"] 47 | [:div.action 48 | [:div.price (format-price (total))]] 49 | [:button.btn.btn--link.tooltip 50 | {:data-tooltip "Remove all" 51 | :on-click #(remove-all-orders)} 52 | [:i.icon.icon--delete]]] 53 | [checkout-modal]]])])) 54 | -------------------------------------------------------------------------------- /giggin/public/img/giggin-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 9 | 11 | 14 | 17 | 20 | 22 | 24 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /increments/complete/public/img/giggin-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 9 | 11 | 14 | 17 | 20 | 22 | 24 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /increments/02-app-setup/public/img/giggin-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 9 | 11 | 14 | 17 | 20 | 22 | 24 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /increments/24-firebase-auth/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]] 5 | [giggin.components.admin-panel :refer [admin-panel]])) 6 | 7 | (defn total 8 | [] 9 | (->> @state/orders 10 | (map (fn [[id quant]] 11 | (if (get-in @state/gigs [id :sold-out]) 12 | 0 13 | (* quant (get-in @state/gigs [id :price]))))) 14 | (reduce +))) 15 | 16 | (defn orders 17 | [] 18 | (let [remove-from-order #(swap! state/orders dissoc %) 19 | remove-all-orders #(reset! state/orders {})] 20 | [:aside 21 | [admin-panel] 22 | (if (empty? @state/orders) 23 | [:div.empty 24 | [:div.title "You don't have any orders"] 25 | [:div.subtitle "Click on a + to add an order"]] 26 | [:div.order 27 | [:div.body 28 | (doall (for [[id quant] @state/orders] 29 | [:div.item {:key id} 30 | [:div.img 31 | [:img {:src (get-in @state/gigs [id :img]) 32 | :alt (get-in @state/gigs [id :title])}]] 33 | [:div.content 34 | (if (get-in @state/gigs [id :sold-out]) 35 | [:p.sold-out "Sold out"] 36 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)])] 37 | [:div.action 38 | (if (get-in @state/gigs [id :sold-out]) 39 | [:div.price (format-price 0)] 40 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))]) 41 | [:button.btn.btn--link.tooltip 42 | {:data-tooltip "Remove" 43 | :on-click #(remove-from-order id)} 44 | [:i.icon.icon--cross]]]]))] 45 | [:div.total 46 | [:hr] 47 | [:div.item 48 | [:div.content "Total"] 49 | [:div.action 50 | [:div.price (format-price (total))]] 51 | [:button.btn.btn--link.tooltip 52 | {:data-tooltip "Remove all" 53 | :on-click #(remove-all-orders)} 54 | [:i.icon.icon--delete]]] 55 | [checkout-modal]]])])) 56 | -------------------------------------------------------------------------------- /increments/25-sign-in-sign-out/src/giggin/components/orders.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.orders 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.checkout-modal :refer [checkout-modal]] 5 | [giggin.components.admin-panel :refer [admin-panel]])) 6 | 7 | (defn total 8 | [] 9 | (->> @state/orders 10 | (map (fn [[id quant]] 11 | (if (get-in @state/gigs [id :sold-out]) 12 | 0 13 | (* quant (get-in @state/gigs [id :price]))))) 14 | (reduce +))) 15 | 16 | (defn orders 17 | [] 18 | (let [remove-from-order #(swap! state/orders dissoc %) 19 | remove-all-orders #(reset! state/orders {})] 20 | [:aside 21 | [admin-panel] 22 | (if (empty? @state/orders) 23 | [:div.empty 24 | [:div.title "You don't have any orders"] 25 | [:div.subtitle "Click on a + to add an order"]] 26 | [:div.order 27 | [:div.body 28 | (doall (for [[id quant] @state/orders] 29 | [:div.item {:key id} 30 | [:div.img 31 | [:img {:src (get-in @state/gigs [id :img]) 32 | :alt (get-in @state/gigs [id :title])}]] 33 | [:div.content 34 | (if (get-in @state/gigs [id :sold-out]) 35 | [:p.sold-out "Sold out"] 36 | [:p.title (str (get-in @state/gigs [id :title]) " \u00D7 " quant)])] 37 | [:div.action 38 | (if (get-in @state/gigs [id :sold-out]) 39 | [:div.price (format-price 0)] 40 | [:div.price (format-price (* (get-in @state/gigs [id :price]) quant))]) 41 | [:button.btn.btn--link.tooltip 42 | {:data-tooltip "Remove" 43 | :on-click #(remove-from-order id)} 44 | [:i.icon.icon--cross]]]]))] 45 | [:div.total 46 | [:hr] 47 | [:div.item 48 | [:div.content "Total"] 49 | [:div.action 50 | [:div.price (format-price (total))]] 51 | [:button.btn.btn--link.tooltip 52 | {:data-tooltip "Remove all" 53 | :on-click #(remove-all-orders)} 54 | [:i.icon.icon--delete]]] 55 | [checkout-modal]]])])) 56 | -------------------------------------------------------------------------------- /increments/17-refactor-gigs/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.gig-editor :refer [gig-editor]] 5 | [reagent.core :as r] 6 | [clojure.string :as str])) 7 | 8 | (defn gigs 9 | [] 10 | (let [modal (r/atom {:active false}) 11 | values (r/atom {:id nil :title "" :desc "" :price 0 :img "" :sold-out false}) 12 | add-to-order #(swap! state/orders update % inc) 13 | toggle-modal (fn 14 | [{:keys [active gig]}] 15 | (swap! modal assoc :active active) 16 | (reset! values gig)) 17 | upsert-gig (fn [{:keys [id title desc price img sold-out]}] 18 | (swap! state/gigs assoc id {:id (or id (str "gig-" (random-uuid))) 19 | :title (str/trim title) 20 | :desc (str/trim desc) 21 | :img (str/trim img) 22 | :price (js/parseInt price) 23 | :sold-out sold-out}) 24 | (toggle-modal {:active false :gig {}}))] 25 | (fn 26 | [] 27 | [:main 28 | [:div.gigs 29 | [:button.add-gig 30 | {:on-click #(toggle-modal {:active true :gig {}})} 31 | [:div.add__title 32 | [:i.icon.icon--plus] 33 | [:p "Add gig"]]] 34 | [gig-editor modal values upsert-gig toggle-modal] 35 | (for [{:keys [id img title price desc] :as gig} (vals @state/gigs)] 36 | [:div.gig {:key id} 37 | [:img.gig__artwork.gig__edit {:src img 38 | :alt title 39 | :on-click #(toggle-modal {:active true 40 | :gig gig})}] 41 | [:div.gig__body 42 | [:div.gig__title 43 | [:div.btn.btn--primary.float--right.tooltip 44 | {:data-tooltip "Add to order" 45 | :on-click #(add-to-order id)} 46 | [:i.icon.icon--plus]] title] 47 | [:p.gig__price (format-price price)] 48 | [:p.gig__desc desc]]])]]))) 49 | -------------------------------------------------------------------------------- /increments/22-subscribe/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.gig-editor :refer [gig-editor]] 5 | [reagent.core :as r] 6 | [clojure.string :as str])) 7 | 8 | (defn gigs 9 | [] 10 | (let [modal (r/atom {:active false}) 11 | initial-values {:id nil :title "" :desc "" :price 0 :img "" :sold-out false} 12 | values (r/atom initial-values) 13 | add-to-order #(swap! state/orders update % inc) 14 | toggle-modal (fn 15 | [{:keys [active gig]}] 16 | (swap! modal assoc :active active) 17 | (reset! values gig)) 18 | upsert-gig (fn [{:keys [id title desc price img sold-out]}] 19 | (swap! state/gigs assoc id {:id (or id (str "gig-" (random-uuid))) 20 | :title (str/trim title) 21 | :desc (str/trim desc) 22 | :img (str/trim img) 23 | :price (js/parseInt price) 24 | :sold-out sold-out}) 25 | (toggle-modal {:active false :gig initial-values}))] 26 | (fn 27 | [] 28 | [:main 29 | [:div.gigs 30 | [:button.add-gig 31 | {:on-click #(toggle-modal {:active true :gig initial-values})} 32 | [:div.add__title 33 | [:i.icon.icon--plus] 34 | [:p "Add gig"]]] 35 | [gig-editor {:modal modal 36 | :values values 37 | :upsert-gig upsert-gig 38 | :toggle-modal toggle-modal 39 | :initial-values initial-values}] 40 | (for [{:keys [id img title price desc] :as gig} (vals @state/gigs)] 41 | [:div.gig {:key id} 42 | [:img.gig__artwork.gig__edit {:src img 43 | :alt title 44 | :on-click #(toggle-modal {:active true 45 | :gig gig})}] 46 | [:div.gig__body 47 | [:div.gig__title 48 | [:div.btn.btn--primary.float--right.tooltip 49 | {:data-tooltip "Add to order" 50 | :on-click #(add-to-order id)} 51 | [:i.icon.icon--plus]] title] 52 | [:p.gig__price (format-price price)] 53 | [:p.gig__desc desc]]])]]))) 54 | -------------------------------------------------------------------------------- /increments/18-ajax-requests/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.gig-editor :refer [gig-editor]] 5 | [reagent.core :as r] 6 | [clojure.string :as str])) 7 | 8 | (defn gigs 9 | [] 10 | (let [modal (r/atom {:active false}) 11 | initial-values {:id nil :title "" :desc "" :price 0 :img "" :sold-out false} 12 | values (r/atom initial-values) 13 | add-to-order #(swap! state/orders update % inc) 14 | toggle-modal (fn 15 | [{:keys [active gig]}] 16 | (swap! modal assoc :active active) 17 | (reset! values gig)) 18 | upsert-gig (fn [{:keys [id title desc price img sold-out]}] 19 | (swap! state/gigs assoc id {:id (or id (str "gig-" (random-uuid))) 20 | :title (str/trim title) 21 | :desc (str/trim desc) 22 | :img (str/trim img) 23 | :price (js/parseInt price) 24 | :sold-out sold-out}) 25 | (toggle-modal {:active false :gig initial-values}))] 26 | (fn 27 | [] 28 | [:main 29 | [:div.gigs 30 | [:button.add-gig 31 | {:on-click #(toggle-modal {:active true :gig initial-values})} 32 | [:div.add__title 33 | [:i.icon.icon--plus] 34 | [:p "Add gig"]]] 35 | [gig-editor {:modal modal 36 | :values values 37 | :upsert-gig upsert-gig 38 | :toggle-modal toggle-modal 39 | :initial-values initial-values}] 40 | (for [{:keys [id img title price desc] :as gig} (vals @state/gigs)] 41 | [:div.gig {:key id} 42 | [:img.gig__artwork.gig__edit {:src img 43 | :alt title 44 | :on-click #(toggle-modal {:active true 45 | :gig gig})}] 46 | [:div.gig__body 47 | [:div.gig__title 48 | [:div.btn.btn--primary.float--right.tooltip 49 | {:data-tooltip "Add to order" 50 | :on-click #(add-to-order id)} 51 | [:i.icon.icon--plus]] title] 52 | [:p.gig__price (format-price price)] 53 | [:p.gig__desc desc]]])]]))) 54 | -------------------------------------------------------------------------------- /increments/20-firebase-setup/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.gig-editor :refer [gig-editor]] 5 | [reagent.core :as r] 6 | [clojure.string :as str])) 7 | 8 | (defn gigs 9 | [] 10 | (let [modal (r/atom {:active false}) 11 | initial-values {:id nil :title "" :desc "" :price 0 :img "" :sold-out false} 12 | values (r/atom initial-values) 13 | add-to-order #(swap! state/orders update % inc) 14 | toggle-modal (fn 15 | [{:keys [active gig]}] 16 | (swap! modal assoc :active active) 17 | (reset! values gig)) 18 | upsert-gig (fn [{:keys [id title desc price img sold-out]}] 19 | (swap! state/gigs assoc id {:id (or id (str "gig-" (random-uuid))) 20 | :title (str/trim title) 21 | :desc (str/trim desc) 22 | :img (str/trim img) 23 | :price (js/parseInt price) 24 | :sold-out sold-out}) 25 | (toggle-modal {:active false :gig initial-values}))] 26 | (fn 27 | [] 28 | [:main 29 | [:div.gigs 30 | [:button.add-gig 31 | {:on-click #(toggle-modal {:active true :gig initial-values})} 32 | [:div.add__title 33 | [:i.icon.icon--plus] 34 | [:p "Add gig"]]] 35 | [gig-editor {:modal modal 36 | :values values 37 | :upsert-gig upsert-gig 38 | :toggle-modal toggle-modal 39 | :initial-values initial-values}] 40 | (for [{:keys [id img title price desc] :as gig} (vals @state/gigs)] 41 | [:div.gig {:key id} 42 | [:img.gig__artwork.gig__edit {:src img 43 | :alt title 44 | :on-click #(toggle-modal {:active true 45 | :gig gig})}] 46 | [:div.gig__body 47 | [:div.gig__title 48 | [:div.btn.btn--primary.float--right.tooltip 49 | {:data-tooltip "Add to order" 50 | :on-click #(add-to-order id)} 51 | [:i.icon.icon--plus]] title] 52 | [:p.gig__price (format-price price)] 53 | [:p.gig__desc desc]]])]]))) 54 | -------------------------------------------------------------------------------- /increments/19-ajax-transformations/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.gig-editor :refer [gig-editor]] 5 | [reagent.core :as r] 6 | [clojure.string :as str])) 7 | 8 | (defn gigs 9 | [] 10 | (let [modal (r/atom {:active false}) 11 | initial-values {:id nil :title "" :desc "" :price 0 :img "" :sold-out false} 12 | values (r/atom initial-values) 13 | add-to-order #(swap! state/orders update % inc) 14 | toggle-modal (fn 15 | [{:keys [active gig]}] 16 | (swap! modal assoc :active active) 17 | (reset! values gig)) 18 | upsert-gig (fn [{:keys [id title desc price img sold-out]}] 19 | (swap! state/gigs assoc id {:id (or id (str "gig-" (random-uuid))) 20 | :title (str/trim title) 21 | :desc (str/trim desc) 22 | :img (str/trim img) 23 | :price (js/parseInt price) 24 | :sold-out sold-out}) 25 | (toggle-modal {:active false :gig initial-values}))] 26 | (fn 27 | [] 28 | [:main 29 | [:div.gigs 30 | [:button.add-gig 31 | {:on-click #(toggle-modal {:active true :gig initial-values})} 32 | [:div.add__title 33 | [:i.icon.icon--plus] 34 | [:p "Add gig"]]] 35 | [gig-editor {:modal modal 36 | :values values 37 | :upsert-gig upsert-gig 38 | :toggle-modal toggle-modal 39 | :initial-values initial-values}] 40 | (for [{:keys [id img title price desc] :as gig} (vals @state/gigs)] 41 | [:div.gig {:key id} 42 | [:img.gig__artwork.gig__edit {:src img 43 | :alt title 44 | :on-click #(toggle-modal {:active true 45 | :gig gig})}] 46 | [:div.gig__body 47 | [:div.gig__title 48 | [:div.btn.btn--primary.float--right.tooltip 49 | {:data-tooltip "Add to order" 50 | :on-click #(add-to-order id)} 51 | [:i.icon.icon--plus]] title] 52 | [:p.gig__price (format-price price)] 53 | [:p.gig__desc desc]]])]]))) 54 | -------------------------------------------------------------------------------- /increments/21-firebase-database/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.gig-editor :refer [gig-editor]] 5 | [reagent.core :as r] 6 | [clojure.string :as str])) 7 | 8 | (defn gigs 9 | [] 10 | (let [modal (r/atom {:active false}) 11 | initial-values {:id nil :title "" :desc "" :price 0 :img "" :sold-out false} 12 | values (r/atom initial-values) 13 | add-to-order #(swap! state/orders update % inc) 14 | toggle-modal (fn 15 | [{:keys [active gig]}] 16 | (swap! modal assoc :active active) 17 | (reset! values gig)) 18 | upsert-gig (fn [{:keys [id title desc price img sold-out]}] 19 | (swap! state/gigs assoc id {:id (or id (str "gig-" (random-uuid))) 20 | :title (str/trim title) 21 | :desc (str/trim desc) 22 | :img (str/trim img) 23 | :price (js/parseInt price) 24 | :sold-out sold-out}) 25 | (toggle-modal {:active false :gig initial-values}))] 26 | (fn 27 | [] 28 | [:main 29 | [:div.gigs 30 | [:button.add-gig 31 | {:on-click #(toggle-modal {:active true :gig initial-values})} 32 | [:div.add__title 33 | [:i.icon.icon--plus] 34 | [:p "Add gig"]]] 35 | [gig-editor {:modal modal 36 | :values values 37 | :upsert-gig upsert-gig 38 | :toggle-modal toggle-modal 39 | :initial-values initial-values}] 40 | (for [{:keys [id img title price desc] :as gig} (vals @state/gigs)] 41 | [:div.gig {:key id} 42 | [:img.gig__artwork.gig__edit {:src img 43 | :alt title 44 | :on-click #(toggle-modal {:active true 45 | :gig gig})}] 46 | [:div.gig__body 47 | [:div.gig__title 48 | [:div.btn.btn--primary.float--right.tooltip 49 | {:data-tooltip "Add to order" 50 | :on-click #(add-to-order id)} 51 | [:i.icon.icon--plus]] title] 52 | [:p.gig__price (format-price price)] 53 | [:p.gig__desc desc]]])]]))) 54 | -------------------------------------------------------------------------------- /increments/23-sold-out/src/giggin/components/gigs.cljs: -------------------------------------------------------------------------------- 1 | (ns giggin.components.gigs 2 | (:require [giggin.state :as state] 3 | [giggin.helpers :refer [format-price]] 4 | [giggin.components.gig-editor :refer [gig-editor]] 5 | [reagent.core :as r] 6 | [clojure.string :as str] 7 | [giggin.fb.db :refer [db-save!]])) 8 | 9 | (defn gigs 10 | [] 11 | (let [modal (r/atom {:active false}) 12 | initial-values {:id nil :title "" :desc "" :price 0 :img "" :sold-out false} 13 | values (r/atom initial-values) 14 | add-to-order #(swap! state/orders update (keyword %) inc) 15 | toggle-modal (fn 16 | [{:keys [active gig]}] 17 | (swap! modal assoc :active active) 18 | (reset! values gig)) 19 | upsert-gig (fn [{:keys [id title desc price img sold-out]}] 20 | (let [id (or id (str "gig-" (random-uuid)))] 21 | (db-save! ["gigs" id] #js {:id id 22 | :title (str/trim title) 23 | :desc (str/trim desc) 24 | :img (str/trim img) 25 | :price (js/parseInt price) 26 | :sold-out sold-out})) 27 | (toggle-modal {:active false :gig initial-values}))] 28 | (fn 29 | [] 30 | [:main 31 | [:div.gigs 32 | [:button.add-gig 33 | {:on-click #(toggle-modal {:active true :gig initial-values})} 34 | [:div.add__title 35 | [:i.icon.icon--plus] 36 | [:p "Add gig"]]] 37 | [gig-editor {:modal modal 38 | :values values 39 | :upsert-gig upsert-gig 40 | :toggle-modal toggle-modal 41 | :initial-values initial-values}] 42 | (for [{:keys [id img title price desc] :as gig} (vals @state/gigs)] 43 | [:div.gig {:key id} 44 | [:img.gig__artwork.gig__edit {:src img 45 | :alt title 46 | :on-click #(toggle-modal {:active true 47 | :gig gig})}] 48 | [:div.gig__body 49 | [:div.gig__title 50 | [:div.btn.btn--primary.float--right.tooltip 51 | {:data-tooltip "Add to order" 52 | :on-click #(add-to-order id)} 53 | [:i.icon.icon--plus]] 54 | title] 55 | [:p.gig__price (format-price price)] 56 | [:p.gig__desc desc]]])]]))) 57 | --------------------------------------------------------------------------------