diff --git a/.bowerrc b/.bowerrc index a534449..da0df18 100644 --- a/.bowerrc +++ b/.bowerrc @@ -1,4 +1,4 @@ { - "directory": "app/static/libs", + "directory": "rfs/static/libs", "json": "bower.json" } diff --git a/.gitignore b/.gitignore index 0e41d5d..e43d940 100644 --- a/.gitignore +++ b/.gitignore @@ -57,7 +57,8 @@ docs/_build/ target/ # project specific -app/static/libs/* +rfs/static/libs/* .module-cache/ node_modules/ -test.db \ No newline at end of file +test.db +.webassets-cache/ diff --git a/README.md b/README.md index 5b56990..3a23778 100644 --- a/README.md +++ b/README.md @@ -2,21 +2,22 @@ Shopping cart application build with flask and facebook react ## Installation -Inspired from https://github.com/cbalan/react-flask-todo-app +Inspired from https://github.com/cbalan/react-flask-todo-app, +and https://github.com/Fibio/flamaster * install python dependencies pip install -r requirements.txt -* install bower + * install bower npm install -g bower -* install js dependencies + * install js dependencies bower install -* compile jsx files using [React tool](http://facebook.github.io/react/docs/tooling-integration.html#productionizing-precompiled-jsx) for development purpose + * compile jsx files using [React tool](http://facebook.github.io/react/docs/tooling-integration.html#productionizing-precompiled-jsx) for development purpose jsx --watch static/js static/jsx diff --git a/manage.py b/manage.py index 7e99017..07331c8 100644 --- a/manage.py +++ b/manage.py @@ -3,8 +3,9 @@ import os from flask.ext.script import Manager +from flask.ext.assets import ManageAssets -from rfs.app import create_app +from rfs.app import create_app, assets app = create_app(config=os.environ.get('APP_CONFIG', 'rfs.config.DevelopmentConfig')) manager = Manager(app) @@ -26,5 +27,9 @@ def run(): """ app.run() +@manager.command +def assets(): + ManageAssets(assets) + if __name__ == "__main__": manager.run() diff --git a/requirements.txt b/requirements.txt index 6556658..651ef4e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,6 @@ Flask-SQLAlchemy Flask-WTF satchless #trafaret +Flask-Mail +#Flask-Assets +#Flask-Login diff --git a/rfs/app.py b/rfs/app.py index c8e097a..ccd265f 100644 --- a/rfs/app.py +++ b/rfs/app.py @@ -5,10 +5,12 @@ from flask import Flask, render_template from flask.ext.sqlalchemy import SQLAlchemy +from flask.ext.assets import Environment, Bundle from rfs.config import DefaultConfig db = SQLAlchemy() +assets = Environment() from products.views import products DEFAULT_BLUEPRINTS = ( @@ -33,7 +35,8 @@ def create_app(config=None, app_name=None, blueprints=None): configure_logging(app) configure_error_handlers(app) configure_database(app) - + configure_assets(app) + return app def configure_app(app, config=None): @@ -93,3 +96,21 @@ def server_error_page(error): def configure_database(app): db.init_app(app) + +def configure_assets(app): + assets.init_app(app) + js = Bundle("libs/react/react.js", + "libs/jquery/dist/jquery.js", + "libs/bootstrap/dist/js/bootstrap.min.js", + filters="jsmin", output="libs/bundle.js") + assets.register("js_all",js) + + css = Bundle("libs/bootstrap/dist/css/bootstrap.css", + "css/app.css", + filters="cssmin", + output="libs/bundle.css") + assets.register("css_all",css) + + + + diff --git a/rfs/products/models.py b/rfs/products/models.py index 60cd372..4b03e90 100644 --- a/rfs/products/models.py +++ b/rfs/products/models.py @@ -7,13 +7,13 @@ class Product(db.Model): description = db.Column(db.Text) image = db.Column(db.String(512)) -class ProductVariant(db.model) +class ProductVariant(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(512), nullable=False) description = db.Column(db.Text) sku = db.Column(db.String(512)) - price = db.Column(db.Integer)) - inventory = db.Column(db.Integer)) + price = db.Column(db.Integer) + inventory = db.Column(db.Integer) - mainproduct_id = db.Column(Integer, ForeignKey('products.id')) - mainproduct = relationship("Product", backref=backref('varients', order_by=id)) + mainproduct_id = db.Column(db.Integer, db.ForeignKey('products.id')) + mainproduct = db.relationship("Product", backref=db.backref('varients', order_by=id)) diff --git a/rfs/static/js/app.js b/rfs/static/js/app.js index 7705457..7b997f1 100644 --- a/rfs/static/js/app.js +++ b/rfs/static/js/app.js @@ -1,127 +1,16 @@ -'use strict'; +var React = require('react'); +var ProductData = require('./ProductData'); +var CartAPI = require('./utils/CartAPI') +var FluxCartApp = require('./components/FluxCartApp.react'); -// Simple pure-React component so we don't have to remember -// Bootstrap's classes -var BootstrapButton = React.createClass({ - render: function() { - return ( - - ); - } -}); +// Load Mock Product Data into localStorage +ProductData.init(); -var BootstrapModal = React.createClass({ - // The following two methods are the only places we need to - // integrate Bootstrap or jQuery with the components lifecycle methods. - componentDidMount: function() { - // When the component is added, turn it into a modal - $(React.findDOMNode(this)) - .modal({backdrop: 'static', keyboard: false, show: false}); - }, - componentWillUnmount: function() { - $(React.findDOMNode(this)).off('hidden', this.handleHidden); - }, - close: function() { - $(React.findDOMNode(this)).modal('hide'); - }, - open: function() { - $(React.findDOMNode(this)).modal('show'); - }, - render: function() { - var confirmButton = null; - var cancelButton = null; +// Load Mock API Call +CartAPI.getProductData(); - if (this.props.confirm) { - confirmButton = ( - - {this.props.confirm} - - ); - } - if (this.props.cancel) { - cancelButton = ( - - {this.props.cancel} - - ); - } - - return ( -
-
-
-
- -

{this.props.title}

-
-
- {this.props.children} -
-
- {cancelButton} - {confirmButton} -
-
-
-
- ); - }, - handleCancel: function() { - if (this.props.onCancel) { - this.props.onCancel(); - } - }, - handleConfirm: function() { - if (this.props.onConfirm) { - this.props.onConfirm(); - } - } -}); - -var Example = React.createClass({ - handleCancel: function() { - if (confirm('Are you sure you want to cancel?')) { - this.refs.modal.close(); - } - }, - render: function() { - var modal = null; - modal = ( - - This is a React component powered by jQuery and Bootstrap! - - ); - return ( -
- {modal} - - Open modal - -
- ); - }, - openModal: function() { - this.refs.modal.open(); - }, - closeModal: function() { - this.refs.modal.close(); - } -}); - -React.render(, document.getElementById('jqueryexample')); +// Render FluxCartApp Controller View +React.render( + , + document.getElementById('flux-cart') +); diff --git a/rfs/templates/base.html b/rfs/templates/base.html index 69c12d9..791a336 100644 --- a/rfs/templates/base.html +++ b/rfs/templates/base.html @@ -4,16 +4,18 @@ jQuery Integration - - +{% assets "css_all" %} + +{% endassets %} +
- - - - + {% assets "js_all" %} + + {% endassets %} + {# compiled with: $ jsx app/static/jsx app/static/js diff --git a/rfs/templates/index.html b/rfs/templates/index.html index 161829c..a5f8aa3 100644 --- a/rfs/templates/index.html +++ b/rfs/templates/index.html @@ -1 +1,22 @@ -Hoi + + + + + + jQuery Integration +{% assets "css_all" %} + +{% endassets %} + + + +
+ + {% assets "js_all" %} + + {% endassets %} + + + + +