code from amapei

This commit is contained in:
cagette@ct8
2020-09-26 18:25:18 +00:00
parent 42fe367911
commit 72b4699871
1966 changed files with 220437 additions and 2 deletions
+103
View File
@@ -0,0 +1,103 @@
package react.store;
import react.ReactComponent;
import react.ReactMacro.jsx;
import Common;
typedef CartProps = {
var order:OrderSimple;
var addToCart:ProductInfo -> Int -> Void;
var removeFromCart:ProductInfo -> ?Int -> Void;
var submitOrder:OrderSimple -> Void;
};
class Cart extends react.ReactComponentOfProps<CartProps>
{
function addToCart(product:ProductInfo, quantity:Int):Void {
props.addToCart(product, quantity);
}
function removeFromCart(product:ProductInfo, quantity:Int):Void {
props.removeFromCart(product, quantity);
}
function removeAllFromCart(product:ProductInfo):Void {
props.removeFromCart(product);
}
function submitOrder():Void {
props.submitOrder(props.order);
}
override public function render(){
return jsx('
<div className="cart">
<h3>Ma Commande</h3>
${renderProducts()}
${renderFooter()}
</div>
');
}
function renderProducts() {
var productsToOrder = props.order.products.map(function(product:ProductWithQuantity) {
var quantity = product.quantity;
var product = product.product;
return jsx('
<div className="product-to-order" key=${product.name}>
<div>${product.name}</div>
<div>$quantity</div>
<div className="cart-action-buttons">
<div onClick=${function(){
this.addToCart(product, 1);
}}>
+
</div>
<div onClick=${function(){
this.removeFromCart(product, 1);
}}>
-
</div>
<div onClick=${function(){
this.removeAllFromCart(product);
}}>
x
</div>
</div>
</div>
');
});
return jsx('
<div className="products-to-order">
${productsToOrder}
</div>
');
}
function renderFooter() {
var buttonClasses = ["order-button"];
var submit = submitOrder;
if (props.order.products.length == 0) {
buttonClasses.push("order-button--disabled");
submit = null;
}
return jsx('
<div className="cart-footer">
<div className="total">
Total
<div>${props.order.total} </div>
</div>
<div className=${buttonClasses.join(" ")} onClick=$submit>Commander</div>
</div>
');
}
}
+45
View File
@@ -0,0 +1,45 @@
package react.store;
import react.ReactComponent;
import react.ReactMacro.jsx;
import Common;
using Lambda;
typedef FiltersProps = {
var categories:Array<CategoryInfo>;
var filters:Array<String>;
var toggleFilter:String -> Void;
};
class Filters extends react.ReactComponentOfProps<FiltersProps>
{
override public function render(){
return jsx('
<div className="filters">
<h3>Filtres</h3>
${renderFilters()}
</div>
');
}
function renderFilters() {
return props.categories.map(function(category) {
var classNames = ["filter"];
if (props.filters.has(category.name))
classNames.push("active");
return jsx('
<div
className=${classNames.join(" ")}
key=${category.id}
onClick=${function(){
props.toggleFilter(category.name);
}}
>
${category.name}
</div>
');
});
}
}
+65
View File
@@ -0,0 +1,65 @@
package react.store;
import js.Browser.window;
import react.ReactComponent;
import react.ReactMacro.jsx;
import Common;
typedef ProductProps = {
var product:ProductInfo;
var addToCart:ProductInfo -> Int -> Void;
};
typedef ProductState = {
var quantity:Int;
};
class Product extends react.ReactComponentOfPropsAndState<ProductProps, ProductState>
{
static inline var OVERLAY_URL = '/shop/productInfo';
static inline var IMAGE_WIDTH = 120;
static inline var IMAGE_HEIGHT = 120;
public function new() {
super();
state = {
quantity: 1
};
}
function openOverlay() {
untyped window._.overlay('$OVERLAY_URL/${props.product.id}', props.product.name);
}
function updateQuantity(event:Dynamic) {
var quantity = Std.parseInt(event.target.value);
if (Std.is(quantity, Int) && quantity > 0)
setState({
quantity: Std.int(quantity)
});
}
function addToCart() {
props.addToCart(props.product, state.quantity);
}
override public function render(){
var product = props.product;
return jsx('
<div className="product">
<img src=${product.image} width=${IMAGE_WIDTH+'px'} height=${IMAGE_HEIGHT+'px'} alt={product.name} />
<div className="body">
<a onClick=$openOverlay>
${product.name}
</a>
<div>${product.price} </div>
<input type="number" value=${state.quantity} onChange=$updateQuantity />
<div className="button" onClick=$addToCart>Ajouter</div>
</div>
</div>
');
}
}
+73
View File
@@ -0,0 +1,73 @@
package react.store;
import react.ReactComponent;
import react.ReactMacro.jsx;
import Common;
using Lambda;
typedef ProductListProps = {
var categories:Array<CategoryInfo>;
var productsBySubcategoryIdMap:Map<Int, Array<ProductInfo>>;
var filters:Array<String>;
var addToCart:ProductInfo -> Int -> Void;
};
class ProductList extends react.ReactComponentOfProps<ProductListProps>
{
override public function render(){
return jsx('
<div className="categories">
${renderCategories()}
</div>
');
}
function renderCategories() {
return props.categories.map(function(category) {
if (!props.filters.has(category.name))
return null;
return jsx('
<div className="category" key=${category.name}>
<h2>${category.name}</h2>
<div className="subCategories">
${renderSubCategories(category)}
</div>
</div>
');
});
}
function renderSubCategories(category) {
var subCategories = category.subcategories.map(function(category) {
if (!props.productsBySubcategoryIdMap.exists(category.id))
return jsx('<div key=${category.name}>Loading...</div>');
var products = props.productsBySubcategoryIdMap.get(category.id);
return jsx('
<div className="sub-category" key=${category.name}>
<h3>${category.name}</h3>
<div className="products">
${renderProducts(products)}
</div>
</div>
');
});
return jsx('
<div className="sub-categories">
$subCategories
</div>
');
}
function renderProducts(products) {
return products.map(function(product) {
return jsx('
<Product product=${product} key=${product.id} addToCart=${props.addToCart}/>
');
});
}
}
+229
View File
@@ -0,0 +1,229 @@
package react.store;
import react.ReactComponent;
import react.ReactMacro.jsx;
import haxe.Json;
using Lambda;
import Common;
import utils.CartUtils;
import utils.HttpUtil;
typedef StoreProps = {
var place:Int;
var date:String;
};
typedef StoreState = {
var place:PlaceInfos;
var orderByEndDates:Array<OrderByEndDate>;
var categories:Array<CategoryInfo>;
var productsBySubcategoryIdMap:Map<Int, Array<ProductInfo>>;
var order:OrderSimple;
var filters:Array<String>;
};
class Store extends react.ReactComponentOfPropsAndState<StoreProps, StoreState>
{
static inline var CATEGORY_URL = '/api/shop/categories';
static inline var PRODUCT_URL = '/api/shop/products';
static inline var INIT_URL = '/api/shop/init';
static inline var VIEW_URL = '/place/view';
public function new() {
super();
state = {
place: null,
orderByEndDates: [],
categories: [],
filters: [],
productsBySubcategoryIdMap: new Map(),
order: {
products: [],
total: 0
}
};
}
override function componentDidMount() {
var categoriesRequest = HttpUtil.fetch(CATEGORY_URL, GET, {date: props.date, place: props.place}, JSON);
var initRequest = HttpUtil.fetch(INIT_URL, GET, {date: props.date, place: props.place}, JSON);
initRequest.then(function(infos:Dynamic) {
setState({
place: infos.place,
orderByEndDates: infos.orderEndDates
});
})
.catchError(function(error) {
trace("ERROR", error);
});
categoriesRequest.then(function(categories:Dynamic) {
var categories:Array<CategoryInfo> = categories.categories;
var subCategories = [];
for (category in categories) {
subCategories = subCategories.concat(category.subcategories);
}
setState({
categories: categories,
filters: categories.map(function(category) {
return category.name;
})
});
subCategories.map(function(category:CategoryInfo) {
return HttpUtil.fetch(PRODUCT_URL, GET, {date: props.date, place: props.place, subcategory: category.id}, JSON)
.then(function(result) {
var productsBySubcategoryIdMapCopy = [
for (key in state.productsBySubcategoryIdMap.keys())
key => state.productsBySubcategoryIdMap.get(key)
];
productsBySubcategoryIdMapCopy.set(category.id, result.products);
setState({
productsBySubcategoryIdMap: productsBySubcategoryIdMapCopy
});
});
});
})
.catchError(function(error) {
trace("ERROR", error);
});
}
function toggleFilter(category:String) {
var filters = state.filters.copy();
if (state.filters.find(function(categoryInFilter) {
return category == categoryInFilter;
}) != null)
filters.remove(category);
else
filters.push(category);
if (filters.length == 0)
filters = state.categories.map(function(category) {
return category.name;
});
setState({
filters: filters
});
}
function addToCart(productToAdd:ProductInfo, quantity:Int):Void {
setState({
order: CartUtils.addToCart(state.order, productToAdd, quantity)
});
}
function removeFromCart(productToRemove:ProductInfo, ?quantity:Int):Void {
setState({
order: CartUtils.removeFromCart(state.order, productToRemove, quantity)
});
}
function submitOrder(order:OrderSimple) {
var orderInSession = {
total: order.total,
products: order.products.map(function(p:ProductWithQuantity){
return {
productId: p.product.id,
quantity: p.quantity
};
})
}
trace('Order', orderInSession);
}
override public function render(){
return jsx('
<div className="shop">
${renderHeader()}
<ProductList
categories=${state.categories}
productsBySubcategoryIdMap=${state.productsBySubcategoryIdMap}
filters=${state.filters}
addToCart=$addToCart
/>
<Filters
categories=${state.categories}
filters=${state.filters}
toggleFilter=$toggleFilter
/>
<Cart
order=${state.order}
addToCart=$addToCart
removeFromCart=$removeFromCart
submitOrder=$submitOrder
/>
</div>
');
}
function renderHeader() {
if (state.orderByEndDates == null || state.orderByEndDates.length == 0)
return null;
var endDates;
if (state.orderByEndDates.length == 1) {
var orderEndDate = state.orderByEndDates[0].date;
endDates = [jsx('<div key=$orderEndDate>La commande fermera le $orderEndDate</div>')];
}
else {
endDates = state.orderByEndDates.map(function(order) {
if (order.contracts.length == 1)
return jsx('
<div key=${order.date}>
La commande ${order.contracts[0]} fermera le: ${order.date}
</div>
');
return jsx('
<div key=${order.date}>
Les autres commandes fermeront: ${order.date}
</div>
');
});
}
var viewUrl = '$VIEW_URL/${props.place}';
var addressBlock = Lambda.array([
state.place.address1,
state.place.address2,
[state.place.zipCode, state.place.city].join(" "),
].mapi(function(index, element) {
if (element == null)
return null;
return jsx('<div className="address" key=$index>$element</div>');
}));
return jsx('
<div className="shop-header">
<div>
<div className="shop-distribution">
Distribution le ${props.date}
</div>
<div className="shop-order-ends">
$endDates
</div>
</div>
<div className="shop-place">
<span className="info">
<span className="glyphicon glyphicon-map-marker"></span>
<a href=$viewUrl>${state.place.name}</a>
</span>
<div>
$addressBlock
</div>
</div>
</div>
');
}
}