====== Single Page Catalog ====== ===== Objective ===== The single page catalog seeks to provide one unified page on which: * Users see My Learning items, Required/Recommended items, browse and search the general catalog items, register/pay for courses and immediately play them in one single page. * Provide a responsive UI * User can choose between “Single Page” and “Classic” UI(current panel design) ===== Functionality ===== Complete details of the single page catalog functionalities are provided in the following link: https://wiki.exphosted.com/doku.php/single_page_catalog_functionality ===== Implementation ===== 1) Create a controller action which renders single page view, once the page is rendered every request after that will is an Ajax call. 2) Need to create a layout named "single_page" which will load Vuejs framework, bootstrap css and other vue compoonents. 3) There can be 2 approaches to fetch data from Learnexa * Making use of existing controllers to support json response * Creating an API support and fetching data based on authenticity token passed on each API call 4) On using existing controllers we need not have to make much code changes, all data fetch code is already available only json response need to be added(recommended option). Just an Ajax call will retrieve all the expected data. 5) On using API call session management should be handled and authentication token should be saved in session to make use of it for each API call. All this session management/token authentication has to be implemented(implementation time will increase). 6) On using either of the above approach, view rendering is achieved using Vuejs framework. Every view part of the page will be developed as a component. * http://vuejs.org/v2/guide/ * https://unpkg.com/vue@2.3.4. 7) All Ajax request from UI is achieved using Vue-resource, the plugin for Vue.js provides services for making web requests and handle responses using a XMLHttpRequest or JSONP. * https://github.com/pagekit/vue-resource 8) Responsive and design styles are achieved using Bootstrap js * https://github.com/twbs/bootstrap/releases/tag/v3.3.7 9) Following are the bootstrap classes that can be used to achieve the expected UI * modal-popup can be used to create a responsive light box. * .img-rounded/.img-thumbnail can be used for the course thumbnail img * .btn-link for all the blue links in site * .badge to attach the number count to image links(notification/inbox/cart) * .breadcrumb to align all link in horizontal line * .dropdown, .dropdown-menu can be used for all dropdowns * .collapse can be used for more item button in product details page * .buttonload for loading icon/button * .modal for confirmation/alert popups * Code for banner image body, html { height: 100%; margin: 0; } .bg { /* The image used */ background-image: url("img_girl.jpg"); height: 50%; /* Center and scale the image nicely */ background-position: center; background-repeat: no-repeat; background-size: cover; } * Animated search input can be referred from https://www.w3schools.com/howto/howto_css_animated_search.asp * Item play progress can be implemented using https://kimmobrunfeldt.github.io/progressbar.js/ plugin 10) The user should be able to switch between the old “Classic” UI(current panel design) and the “Single Page” UI by making a setting change in the “Site Properties” page. {{:site_properties.png?800x600}} ===== DB Changes ===== Table name - companies ^ Column_name ^ type ^ Description ^ |single_page_catalog_enabled| boolean |default false| ===== Mocks ===== https://wiki.exphosted.com/doku.php/single_page_catalog_issues_list_with_mock ===== POC Using Existing Controllers ===== Create a sample page which will make an ajax call to existing controllers, fetch products and dynamically render using Vue component: 1) HTML file looks like:
Bird

Available Courses

2) Sample products controller app/controllers/products_controller.rb (already existing controller) class ProductsController < BaseController def index search_featured_items = Product.search(current_account, current_user, params.merge(:only_featured => true)) search_except_featured_items = Product.search(current_account, current_user, params.merge(:except_featured => true)) @products = search_featured_items.results + search_except_featured_items.results respond_to do |format| format.json { render :json => @products.to_json } end end end 3) Vue template for rending item tile structure comes from vue_template.js Vue.component('my-component', { template: `
`, props: { item: Object, } })
===== POC For API Approach ===== Create a sample page which will make an API call to fetch products and dynamically render using Vue component: 1) HTML file looks like:
Bird

Available Courses

2) Enable API in application by adding following in 'config/application.yml' api_enabled: true 3) Created sample api controller app/controllers/api/v1/products_controller.rb class Api::V1::ProductsController < Api::V1::BaseController before_filter :verify_access_token def index current_account = Company.find_by_id(params[:company_id]) current_user = User.find_by_id(params[:user_id]) search_featured_items = Product.search(current_account, current_user, params.merge(:only_featured => true)) search_except_featured_items = Product.search(current_account, current_user, params.merge(:except_featured => true)) @products = search_featured_items.results + search_except_featured_items.results end end 4) API render file is index.rabl, show.rabl index.rabl: collection @products extends "api/v1/products/show" show.rabl: object @product attributes :id, :title, :description, :item_type, :item_id, :thumbnail_url, :description child :categories => :categories do attributes :id, :name end child :tags => :tags do attributes :id, :name end 5) Vue template for rending item tile structure comes from vue_template.js Vue.component('my-component', { template: `
`, props: { item: Object, } })
6) Screen shot of the sample page: {{:sample_page.png?800x600}} ===== Code Snippets for Animation ===== 1) Play progress button code using progressbar.js plugin:
30%
{{:play_progress.png|}}