Compare commits
No commits in common. "685417b2599e69ddfb30baf685625304930a2c9a" and "main" have entirely different histories.
685417b259
...
main
15
.env
15
.env
|
@ -1,15 +0,0 @@
|
|||
REACT_APP_DOMAIN=192.168.0.68
|
||||
REACT_APP_PATH=UniOilLoyaltyApp-BackEnd/public/index.php/api/cms
|
||||
REACT_APP_DEV=http://$REACT_APP_DOMAIN/$REACT_APP_PATH
|
||||
REACT_APP_QA=http://$REACT_APP_DOMAIN:4000/$REACT_APP_PATH
|
||||
REACT_APP_IMG_URL=http://$REACT_APP_DOMAIN/UniOilLoyaltyApp-BackEnd/
|
||||
REACT_APP_API=https://mobileapi.unioilapps.com/api/cms
|
||||
REACT_APP_TOKEN=X_TOKEN
|
||||
NODE_PATH=src/
|
||||
GENERATE_SOURCEMAP=false
|
||||
REACT_APP_PUBLIC=false
|
||||
REACT_APP_NOTIF_API=http://unioilcms.taxikel.com:3000/api/
|
||||
REACT_APP_STATION_API_TESTING=https://testing-api-station-locator.herokuapp.com/api/
|
||||
REACT_APP_STATION_API_TESTINGX=https://station-locator-api.herokuapp.com/api/
|
||||
REACT_APP_STATION_API=https://cors-anywhere.herokuapp.com/13.212.2.253/api/
|
||||
REACT_APP_API_SYNC=https://mobileapi.unioilapps.com/api/mobile/
|
12
.flowconfig
12
.flowconfig
|
@ -1,12 +0,0 @@
|
|||
[ignore]
|
||||
./components
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
.*/node_modules/*
|
||||
[lints]
|
||||
|
||||
[options]
|
||||
|
||||
|
||||
[strict]
|
|
@ -1,50 +0,0 @@
|
|||
# These are some examples of commonly ignored file patterns.
|
||||
# You should customize this list as applicable to your project.
|
||||
# Learn more about .gitignore:
|
||||
# https://www.atlassian.com/git/tutorials/saving-changes/gitignore
|
||||
|
||||
# Node artifact files
|
||||
node_modules/
|
||||
dist/
|
||||
|
||||
# Compiled Java class files
|
||||
*.class
|
||||
|
||||
# Compiled Python bytecode
|
||||
*.py[cod]
|
||||
|
||||
# Log files
|
||||
*.log
|
||||
|
||||
# Package files
|
||||
*.jar
|
||||
|
||||
# Maven
|
||||
target/
|
||||
dist/
|
||||
|
||||
# JetBrains IDE
|
||||
.idea/
|
||||
|
||||
# Unit test reports
|
||||
TEST*.xml
|
||||
|
||||
# Generated by MacOS
|
||||
.DS_Store
|
||||
|
||||
# Generated by Windows
|
||||
Thumbs.db
|
||||
|
||||
# Applications
|
||||
*.app
|
||||
*.exe
|
||||
*.war
|
||||
|
||||
# Large media files
|
||||
*.mp4
|
||||
*.tiff
|
||||
*.avi
|
||||
*.flv
|
||||
*.mov
|
||||
*.wmv
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
image: node:latest
|
||||
|
||||
before_script:
|
||||
- apt-get update -qy
|
||||
- apt-get install -y ruby-dev
|
||||
- gem install dpl
|
||||
|
||||
stages:
|
||||
- testing
|
||||
- staging
|
||||
- production
|
||||
|
||||
testing:
|
||||
type: deploy
|
||||
stage: testing
|
||||
image: ruby:latest
|
||||
script:
|
||||
- dpl --provider=heroku --app=$HEROKU_APP_TESTING --api-key=$HEROKU_API_KEY
|
||||
only:
|
||||
- testing
|
||||
|
||||
staging:
|
||||
type: deploy
|
||||
stage: staging
|
||||
image: ruby:latest
|
||||
script:
|
||||
- dpl --provider=heroku --app=$HEROKU_APP_STAGING --api-key=$HEROKU_API_KEY
|
||||
only:
|
||||
- staging
|
||||
|
||||
# production:
|
||||
# type: deploy
|
||||
# stage: production
|
||||
# image: ruby:latest
|
||||
# script:
|
||||
# - dpl --provider=heroku --app=$HEROKU_APP_PRODUCTION --api-key=$HEROKU_API_KEY
|
||||
# only:
|
||||
# - master
|
||||
|
||||
|
30
Dockerfile
30
Dockerfile
|
@ -1,30 +0,0 @@
|
|||
# Stage 1 - the build process
|
||||
FROM node:8.11.3 as builder
|
||||
RUN mkdir /usr/src/app
|
||||
WORKDIR /usr/src/app
|
||||
ENV PATH /usr/src/app/node_modules/.bin:$PATH
|
||||
ARG REACT_APP_PATH
|
||||
ARG REACT_APP_DOMAIN
|
||||
ARG REACT_APP_IMG_PATH
|
||||
ARG REACT_APP_PUBLIC
|
||||
ARG PUBLIC_URL
|
||||
ARG GENERATE_SOURCEMAP
|
||||
ENV REACT_APP_API $REACT_APP_DOMAIN/$REACT_APP_PATH
|
||||
ENV REACT_APP_IMG_URL $REACT_APP_DOMAIN/$REACT_APP_IMG_PATH
|
||||
RUN echo "DEBUG": $PUBLIC_URL
|
||||
|
||||
COPY package.json yarn.lock /usr/src/app/
|
||||
RUN yarn install
|
||||
COPY . /usr/src/app
|
||||
RUN yarn build
|
||||
|
||||
# Stage 2 - the production environment
|
||||
FROM nginx:1.13.9-alpine
|
||||
|
||||
RUN rm -rf /etc/nginx/conf.d
|
||||
COPY conf /etc/nginx
|
||||
|
||||
RUN rm -rf /usr/share/nginx/html/*
|
||||
COPY --from=builder /usr/src/app/build /usr/share/nginx/html
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
54
Makefile
54
Makefile
|
@ -1,54 +0,0 @@
|
|||
dev-server:
|
||||
docker-compose up -d --build dev-build
|
||||
.PHONY: dev-server
|
||||
|
||||
dev-server-stop:
|
||||
docker-compose stop -t 1 dev-build
|
||||
.PHONY: dev-server-stop
|
||||
|
||||
test-server:
|
||||
docker-compose up -d --build test-build
|
||||
.PHONY: test-server
|
||||
|
||||
test-server-stop:
|
||||
docker-compose stop -t 1 test-build
|
||||
.PHONY: test-server-stop
|
||||
|
||||
prod-server:
|
||||
docker-compose -f docker-compose-prod.yml up -d --build
|
||||
.PHONY: prod-server
|
||||
|
||||
prod-server-stop:
|
||||
docker-compose -f docker-compose-prod.yml down
|
||||
.PHONY: prod-server-stop
|
||||
|
||||
dev-public-callback-server:
|
||||
docker-compose up -d --build public-dev-build
|
||||
.PHONY: dev-public-callback-server
|
||||
|
||||
dev-public-callback-server-stop:
|
||||
docker-compose stop -t 1 public-dev-build
|
||||
.PHONY: dev-public-callback-server-stop
|
||||
|
||||
test-public-callback-server:
|
||||
docker-compose up -d --build public-test-build
|
||||
.PHONY: test-public-callback-server
|
||||
|
||||
test-public-callback-server-stop:
|
||||
docker-compose stop -t 1 public-test-build
|
||||
.PHONY: test-public-callback-server-stop
|
||||
|
||||
prod-public-callback-server:
|
||||
docker-compose -f docker-compose-public.yml up -d --build
|
||||
.PHONY: prod-public-callback-server
|
||||
|
||||
prod-public-callback-server-stop:
|
||||
docker-compose -f docker-compose-public.yml down
|
||||
.PHONY: prod-public-callback-server-stop
|
||||
|
||||
stop:
|
||||
docker-compose down
|
||||
.PHONY: stop
|
||||
|
||||
clean:
|
||||
docker system prune --volumes -f
|
74
README.md
74
README.md
|
@ -1,74 +1,2 @@
|
|||
|
||||
## Server Dependences
|
||||
|
||||
* [Docker/Linux](https://docs.docker.com/install/linux/docker-ce/ubuntu/)
|
||||
* [Docker Compose/Linux](https://docs.docker.com/compose/install/#install-compose)
|
||||
|
||||
### `sudo apt-get update`
|
||||
### `sudo apt-get install build-essential`
|
||||
|
||||
## CMS - Local Development Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm start`
|
||||
|
||||
Runs the app in the development mode.<br>
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
|
||||
|
||||
The page will reload if you make edits.<br>
|
||||
You will also see any lint errors in the console.
|
||||
|
||||
## Development Server Scripts
|
||||
|
||||
Up the server for staging development run:
|
||||
### `make dev-server`
|
||||
|
||||
Stop the server run:
|
||||
### `make dev-server-stop`
|
||||
|
||||
## QA/Testing Server Scripts
|
||||
|
||||
Up the server for staging QA/Testing run:
|
||||
### `make test-server`
|
||||
|
||||
Stop the server run:
|
||||
### `make test-server-stop`
|
||||
|
||||
## Production Server Scripts
|
||||
|
||||
Up the server for production run:
|
||||
### `make prod-server`
|
||||
|
||||
Stop the server run:
|
||||
### `make prod-server-stop`
|
||||
|
||||
Clean image container run:
|
||||
### `make clean`
|
||||
|
||||
|
||||
|
||||
## Public Development Server Scripts
|
||||
|
||||
Up the server for staging development run:
|
||||
### `make dev-public-callback-server`
|
||||
|
||||
Stop the server run:
|
||||
### `make dev-public-callback-server-stop`
|
||||
|
||||
## Public QA/Testing Server Scripts
|
||||
|
||||
Up the server for staging QA/Testing run:
|
||||
### `make test-public-callback-server`
|
||||
|
||||
Stop the server run:
|
||||
### `make test-public-callback-server-stop`
|
||||
|
||||
## Public Production Server Scripts
|
||||
|
||||
Up the server for staging QA/Testing run:
|
||||
### `make prod-public-callback-server`
|
||||
|
||||
Stop the server run:
|
||||
### `make prod-public-callback-server-stop`
|
||||
# loyalty-cms
|
||||
|
||||
|
|
|
@ -1,133 +0,0 @@
|
|||
# read more here http://tautt.com/best-nginx-configuration-for-security/
|
||||
|
||||
# add_header Server "mystartup/1.0" always;
|
||||
# config to don't allow the browser to render the page inside an frame or iframe
|
||||
# and avoid clickjacking http://en.wikipedia.org/wiki/Clickjacking
|
||||
# if you need to allow [i]frames, you can use SAMEORIGIN or even set an uri with ALLOW-FROM uri
|
||||
# https://developer.mozilla.org/en-US/docs/HTTP/X-Frame-Options
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
|
||||
# when serving user-supplied content, include a X-Content-Type-Options: nosniff header along with the Content-Type: header,
|
||||
# to disable content-type sniffing on some browsers.
|
||||
# https://www.owasp.org/index.php/List_of_useful_HTTP_headers
|
||||
# currently suppoorted in IE > 8 http://blogs.msdn.com/b/ie/archive/2008/09/02/ie8-security-part-vi-beta-2-update.aspx
|
||||
# http://msdn.microsoft.com/en-us/library/ie/gg622941(v=vs.85).aspx
|
||||
# 'soon' on Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=471020
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
|
||||
# This header enables the Cross-site scripting (XSS) filter built into most recent web browsers.
|
||||
# It's usually enabled by default anyway, so the role of this header is to re-enable the filter for
|
||||
# this particular website if it was disabled by the user.
|
||||
# https://www.owasp.org/index.php/List_of_useful_HTTP_headers
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
|
||||
# with Content Security Policy (CSP) enabled(and a browser that supports it(http://caniuse.com/#feat=contentsecuritypolicy),
|
||||
# you can tell the browser that it can only download content from the domains you explicitly allow
|
||||
# http://www.html5rocks.com/en/tutorials/security/content-security-policy/
|
||||
# https://www.owasp.org/index.php/Content_Security_Policy
|
||||
# I need to change our application code so we can increase security by disabling 'unsafe-inline' 'unsafe-eval'
|
||||
# directives for css and js(if you have inline css or js, you will need to keep it too).
|
||||
# more: http://www.html5rocks.com/en/tutorials/security/content-security-policy/#inline-code-considered-harmful
|
||||
# add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://ssl.google-analytics.com https://assets.zendesk.com https://connect.facebook.net; img-src 'self' https://ssl.google-analytics.com https://s-static.ak.facebook.com https://assets.zendesk.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://assets.zendesk.com; font-src 'self' https://themes.googleusercontent.com; frame-src https://assets.zendesk.com https://www.facebook.com https://s-static.ak.facebook.com https://tautt.zendesk.com; object-src 'none'";
|
||||
# add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
|
||||
|
||||
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
sendfile on;
|
||||
|
||||
default_type application/octet-stream;
|
||||
# more_clear_headers Server;
|
||||
# more_set_headers 'Server: Powered by Yondu';
|
||||
# don't send the nginx version number in error pages and Server header
|
||||
server_tokens off;
|
||||
|
||||
|
||||
|
||||
gzip on;
|
||||
gzip_http_version 1.1;
|
||||
gzip_disable "MSIE [1-6]\.";
|
||||
gzip_min_length 256;
|
||||
gzip_vary on;
|
||||
gzip_proxied expired no-cache no-store private auth;
|
||||
gzip_types
|
||||
application/atom+xml
|
||||
application/javascript
|
||||
application/json
|
||||
application/ld+json
|
||||
application/manifest+json
|
||||
application/rss+xml
|
||||
application/vnd.geo+json
|
||||
application/vnd.ms-fontobject
|
||||
application/x-font-ttf
|
||||
application/x-web-app-manifest+json
|
||||
application/xhtml+xml
|
||||
application/xml
|
||||
font/opentype
|
||||
image/bmp
|
||||
image/svg+xml
|
||||
image/x-icon
|
||||
text/cache-manifest
|
||||
text/css
|
||||
text/plain
|
||||
text/vcard
|
||||
text/vnd.rim.location.xloc
|
||||
text/vtt
|
||||
text/x-component
|
||||
text/x-cross-domain-policy;
|
||||
# text/html is always compressed by gzip module
|
||||
gzip_comp_level 9;
|
||||
server_name *.example.org;
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
# . files
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
}
|
||||
# cache.appcache, your document html and data
|
||||
location ~* \.(?:manifest|appcache|html?|xml|json)$ {
|
||||
expires -1;
|
||||
# access_log logs/static.log; # I don't usually include a static log
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
# Media: images, icons, video, audio, HTC
|
||||
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
|
||||
expires 1M;
|
||||
access_log off;
|
||||
|
||||
}
|
||||
|
||||
# location ~* (service-worker\.js)$ {
|
||||
# add_header Cache-Control no-store, no-cache;
|
||||
# expires -1;
|
||||
# proxy_no_cache 1;
|
||||
|
||||
# }
|
||||
|
||||
# CSS and Javascript
|
||||
location ~* /static/.*\.(?:css|js)$ {
|
||||
expires 1y;
|
||||
access_log off;
|
||||
|
||||
}
|
||||
|
||||
|
||||
# location /service-worker.js {
|
||||
# expires -1;
|
||||
# add_header Cache-Control no-store, no-cache;
|
||||
# access_log off;
|
||||
# }
|
||||
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,491 +0,0 @@
|
|||
const { injectBabelPlugin } = require("react-app-rewired");
|
||||
const rewireLess = require("react-app-rewire-less");
|
||||
// const VariablesOutput = require('less-plugin-variables-output');
|
||||
|
||||
// const fs = require('fs');
|
||||
// const path = require('path');
|
||||
// const less = require('less');
|
||||
|
||||
module.exports = function override(config, env) {
|
||||
|
||||
config = injectBabelPlugin(['import', { libraryName: 'antd', style: true }], config); // change importing css to less
|
||||
config = rewireLess.withLoaderOptions({
|
||||
javascriptEnabled: true,
|
||||
modifyVars: {
|
||||
// "@primary-color": "#1DA57A" ,
|
||||
|
||||
|
||||
'@primary-color' : '#1890ff',
|
||||
'@info-color' : '#1890ff',
|
||||
'@success-color ' : '#52c41a',
|
||||
'@processing-color' : '#1890ff',
|
||||
'@error-color' : '#f5222d',
|
||||
'@highlight-color' : '#f5222d',
|
||||
'@warning-color' : '#faad14',
|
||||
'@normal-color' : '#d9d9d9',
|
||||
|
||||
// Color used by default to control hover and active backgrounds and for
|
||||
// alert info backgrounds.
|
||||
// @primary-1: color(~`colorPalette("@{primary-color}", 1)`); // replace tint(@primary-color, 90%)
|
||||
// @primary-2: color(~`colorPalette("@{primary-color}", 2)`); // replace tint(@primary-color, 80%)
|
||||
// @primary-3: color(~`colorPalette("@{primary-color}", 3)`); // unused
|
||||
// @primary-4: color(~`colorPalette("@{primary-color}", 4)`); // unused
|
||||
// @primary-5: color(~`colorPalette("@{primary-color}", 5)`); // color used to control the text color in many active and hover states, replace tint(@primary-color, 20%)
|
||||
// @primary-6: @primary-color; // color used to control the text color of active buttons, don't use, use @primary-color
|
||||
// @primary-7: color(~`colorPalette("@{primary-color}", 7)`); // replace shade(@primary-color, 5%)
|
||||
// @primary-8: color(~`colorPalette("@{primary-color}", 8)`); // unused
|
||||
// @primary-9: color(~`colorPalette("@{primary-color}", 9)`); // unused
|
||||
// @primary-10: color(~`colorPalette("@{primary-color}", 10)`); // unused
|
||||
|
||||
// Base Scaffolding Variables
|
||||
// ---
|
||||
|
||||
// Background color for `<body>`
|
||||
// @body-background : #fff;
|
||||
// Base background color for most components
|
||||
// @component-background : #fff;
|
||||
// @font-family-no-number : "Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
// @font-family : "Monospaced Number", @font-family-no-number;
|
||||
// @code-family : Consolas, Menlo, Courier, monospace;
|
||||
// @heading-color : fade(#000, 85%);
|
||||
// @text-color : fade(#000, 65%);
|
||||
// @text-color-secondary : fade(#000, 45%);
|
||||
// @heading-color-dark : fade(#fff, 100%);
|
||||
// @text-color-dark : fade(#fff, 85%);
|
||||
// @text-color-secondary-dark: fade(#fff, 65%);
|
||||
'@font-size-base' : '14px'
|
||||
// @font-size-lg : @font-size-base + 2px;
|
||||
// @font-size-sm : 12px;
|
||||
// @line-height-base : 1.5;
|
||||
// @border-radius-base : 4px;
|
||||
// @border-radius-sm : 2px;
|
||||
|
||||
// vertical paddings
|
||||
// @padding-lg : 24px; // containers
|
||||
// @padding-md : 16px; // small containers and buttons
|
||||
// @padding-sm : 12px; // Form controls and items
|
||||
// @padding-xs : 8px; // small items
|
||||
|
||||
// vertical padding for all form controls
|
||||
// @control-padding-horizontal: @padding-sm;
|
||||
// @control-padding-horizontal-sm: @padding-xs;
|
||||
|
||||
// The background colors for active and hover states for things like
|
||||
// list items or table cells.
|
||||
// @item-active-bg : @primary-1;
|
||||
// @item-hover-bg : @primary-1;
|
||||
|
||||
// ICONFONT
|
||||
// @iconfont-css-prefix : anticon;
|
||||
// @icon-url : "https://at.alicdn.com/t/font_148784_v4ggb6wrjmkotj4i";
|
||||
|
||||
// LINK
|
||||
// @link-color : @primary-color;
|
||||
// @link-hover-color : color(~`colorPalette("@{link-color}", 5)`);
|
||||
// @link-active-color : color(~`colorPalette("@{link-color}", 7)`);
|
||||
// @link-decoration : none;
|
||||
// @link-hover-decoration : none;
|
||||
|
||||
// Animation
|
||||
// @ease-out : cubic-bezier(0.215, 0.61, 0.355, 1);
|
||||
// @ease-in : cubic-bezier(0.55, 0.055, 0.675, 0.19);
|
||||
// @ease-in-out : cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
// @ease-out-back : cubic-bezier(0.12, 0.4, 0.29, 1.46);
|
||||
// @ease-in-back : cubic-bezier(0.71, -0.46, 0.88, 0.6);
|
||||
// @ease-in-out-back : cubic-bezier(0.71, -0.46, 0.29, 1.46);
|
||||
// @ease-out-circ : cubic-bezier(0.08, 0.82, 0.17, 1);
|
||||
// @ease-in-circ : cubic-bezier(0.6, 0.04, 0.98, 0.34);
|
||||
// @ease-in-out-circ : cubic-bezier(0.78, 0.14, 0.15, 0.86);
|
||||
// @ease-out-quint : cubic-bezier(0.23, 1, 0.32, 1);
|
||||
// @ease-in-quint : cubic-bezier(0.755, 0.05, 0.855, 0.06);
|
||||
// @ease-in-out-quint : cubic-bezier(0.86, 0, 0.07, 1);
|
||||
|
||||
// Border color
|
||||
// @border-color-base : hsv(0, 0, 85%); // base border outline a component
|
||||
// @border-color-split : hsv(0, 0, 91%); // split border inside a component
|
||||
// @border-width-base : 1px; // width of the border for a component
|
||||
// @border-style-base : solid; // style of a components border
|
||||
|
||||
// Outline
|
||||
// @outline-blur-size : 0;
|
||||
// @outline-width : 2px;
|
||||
// @outline-color : @primary-color;
|
||||
|
||||
// @background-color-light : hsv(0, 0, 98%); // background of header and selected item
|
||||
// @background-color-base : hsv(0, 0, 96%); // Default grey background color
|
||||
|
||||
// Disabled states
|
||||
// @disabled-color : fade(#000, 25%);
|
||||
// @disabled-bg : @background-color-base;
|
||||
// @disabled-color-dark : fade(#fff, 35%);
|
||||
|
||||
// Shadow
|
||||
// @shadow-color : rgba(0, 0, 0, .15);
|
||||
// @box-shadow-base : @shadow-1-down;
|
||||
// @shadow-1-up : 0 2px 8px @shadow-color;
|
||||
// @shadow-1-down : 0 2px 8px @shadow-color;
|
||||
// @shadow-1-left : -2px 0 8px @shadow-color;
|
||||
// @shadow-1-right : 2px 0 8px @shadow-color;
|
||||
// @shadow-2 : 0 4px 12px @shadow-color;
|
||||
|
||||
// Buttons
|
||||
// @btn-font-weight : 400;
|
||||
// @btn-border-radius-base : @border-radius-base;
|
||||
// @btn-border-radius-sm : @border-radius-base;
|
||||
|
||||
// @btn-primary-color : #fff;
|
||||
// @btn-primary-bg : @primary-color;
|
||||
|
||||
// @btn-default-color : @text-color;
|
||||
// @btn-default-bg : #fff;
|
||||
// @btn-default-border : @border-color-base;
|
||||
|
||||
// @btn-danger-color : @error-color;
|
||||
// @btn-danger-bg : @background-color-base;
|
||||
// @btn-danger-border : @border-color-base;
|
||||
|
||||
// @btn-disable-color : @disabled-color;
|
||||
// @btn-disable-bg : @disabled-bg;
|
||||
// @btn-disable-border : @border-color-base;
|
||||
|
||||
// @btn-padding-base : 0 @padding-md - 1px;
|
||||
// @btn-font-size-lg : @font-size-lg;
|
||||
// @btn-font-size-sm : @font-size-base;
|
||||
// @btn-padding-lg : @btn-padding-base;
|
||||
// @btn-padding-sm : 0 @padding-xs - 1px;
|
||||
|
||||
// @btn-height-base : 32px;
|
||||
// @btn-height-lg : 40px;
|
||||
// @btn-height-sm : 24px;
|
||||
|
||||
// @btn-circle-size : @btn-height-base;
|
||||
// @btn-circle-size-lg : @btn-height-lg;
|
||||
// @btn-circle-size-sm : @btn-height-sm;
|
||||
|
||||
// @btn-group-border : @primary-5;
|
||||
|
||||
// Checkbox
|
||||
// @checkbox-size : 16px;
|
||||
// @checkbox-color : @primary-color;
|
||||
|
||||
// Radio
|
||||
// @radio-size : 16px;
|
||||
// @radio-dot-color : @primary-color;
|
||||
|
||||
// Radio buttons
|
||||
// @radio-button-bg : @btn-default-bg;
|
||||
// @radio-button-color : @btn-default-color;
|
||||
// @radio-button-hover-color : @primary-5;
|
||||
// @radio-button-active-color : @primary-7;
|
||||
|
||||
// Media queries breakpoints
|
||||
// Extra small screen / phone
|
||||
// @screen-xs : 480px;
|
||||
// @screen-xs-min : @screen-xs;
|
||||
|
||||
// Small screen / tablet
|
||||
// @screen-sm : 576px;
|
||||
// @screen-sm-min : @screen-sm;
|
||||
|
||||
// Medium screen / desktop
|
||||
// @screen-md : 768px;
|
||||
// @screen-md-min : @screen-md;
|
||||
|
||||
// Large screen / wide desktop
|
||||
// @screen-lg : 992px;
|
||||
// @screen-lg-min : @screen-lg;
|
||||
|
||||
// Extra large screen / full hd
|
||||
// @screen-xl : 1200px;
|
||||
// @screen-xl-min : @screen-xl;
|
||||
|
||||
// Extra extra large screen / large descktop
|
||||
// @screen-xxl : 1600px;
|
||||
// @screen-xxl-min : @screen-xxl;
|
||||
|
||||
// provide a maximum
|
||||
// @screen-xs-max : (@screen-sm-min - 1px);
|
||||
// @screen-sm-max : (@screen-md-min - 1px);
|
||||
// @screen-md-max : (@screen-lg-min - 1px);
|
||||
// @screen-lg-max : (@screen-xl-min - 1px);
|
||||
// @screen-xl-max : (@screen-xxl-min - 1px);
|
||||
|
||||
// Grid system
|
||||
// @grid-columns : 24;
|
||||
// @grid-gutter-width : 0;
|
||||
|
||||
// Layout
|
||||
// @layout-body-background : #f0f2f5;
|
||||
// @layout-header-background : #001529;
|
||||
// @layout-footer-background : @layout-body-background;
|
||||
// @layout-header-height : 64px;
|
||||
// @layout-header-padding : 0 50px;
|
||||
// @layout-footer-padding : 24px 50px;
|
||||
// @layout-sider-background : @layout-header-background;
|
||||
// @layout-trigger-height : 48px;
|
||||
// @layout-trigger-background : #002140;
|
||||
// @layout-trigger-color : #fff;
|
||||
// @layout-zero-trigger-width : 36px;
|
||||
// @layout-zero-trigger-height : 42px;
|
||||
// Layout light theme
|
||||
// @layout-sider-background-light : #fff;
|
||||
// @layout-trigger-background-light: #fff;
|
||||
// @layout-trigger-color-light : @text-color;
|
||||
|
||||
// z-index list
|
||||
// @zindex-affix : 10;
|
||||
// @zindex-back-top : 10;
|
||||
// @zindex-modal-mask : 1000;
|
||||
// @zindex-modal : 1000;
|
||||
// @zindex-notification : 1010;
|
||||
// @zindex-message : 1010;
|
||||
// @zindex-popover : 1030;
|
||||
// @zindex-picker : 1050;
|
||||
// @zindex-dropdown : 1050;
|
||||
// @zindex-tooltip : 1060;
|
||||
|
||||
// Animation
|
||||
// @animation-duration-slow: .3s; // Modal
|
||||
// @animation-duration-base: .2s;
|
||||
// @animation-duration-fast: .1s; // Tooltip
|
||||
|
||||
// Form
|
||||
// ---
|
||||
// @label-required-color : @highlight-color;
|
||||
// @label-color : @heading-color;
|
||||
// @form-item-margin-bottom : 24px;
|
||||
// @form-item-trailing-colon : true;
|
||||
// @form-vertical-label-padding : 0 0 8px;
|
||||
// @form-vertical-label-margin : 0;
|
||||
|
||||
// Input
|
||||
// ---
|
||||
// @input-height-base : 32px;
|
||||
// @input-height-lg : 40px;
|
||||
// @input-height-sm : 24px;
|
||||
// @input-padding-horizontal : @control-padding-horizontal - 1px;
|
||||
// @input-padding-horizontal-base: @input-padding-horizontal;
|
||||
// @input-padding-horizontal-sm : @control-padding-horizontal-sm - 1px;
|
||||
// @input-padding-horizontal-lg : @input-padding-horizontal;
|
||||
// @input-padding-vertical-base : 4px;
|
||||
// @input-padding-vertical-sm : 1px;
|
||||
// @input-padding-vertical-lg : 6px;
|
||||
// @input-placeholder-color : hsv(0, 0, 75%);
|
||||
// @input-color : @text-color;
|
||||
// @input-border-color : @border-color-base;
|
||||
// @input-bg : #fff;
|
||||
// @input-addon-bg : @background-color-light;
|
||||
// @input-hover-border-color : @primary-color;
|
||||
// @input-disabled-bg : @disabled-bg;
|
||||
|
||||
// Tooltip
|
||||
// ---
|
||||
//* Tooltip max width
|
||||
// @tooltip-max-width: 250px;
|
||||
//** Tooltip text color
|
||||
// @tooltip-color: #fff;
|
||||
//** Tooltip background color
|
||||
// @tooltip-bg: rgba(0, 0, 0, .75);
|
||||
//** Tooltip arrow width
|
||||
// @tooltip-arrow-width: 5px;
|
||||
//** Tooltip distance with trigger
|
||||
// @tooltip-distance: @tooltip-arrow-width - 1px + 4px;
|
||||
//** Tooltip arrow color
|
||||
// @tooltip-arrow-color: @tooltip-bg;
|
||||
|
||||
// Popover
|
||||
// ---
|
||||
//** Popover body background color
|
||||
// @popover-bg: #fff;
|
||||
//** Popover text color
|
||||
// @popover-color: @text-color;
|
||||
//** Popover maximum width
|
||||
// @popover-min-width: 177px;
|
||||
//** Popover arrow width
|
||||
// @popover-arrow-width: 6px;
|
||||
//** Popover arrow color
|
||||
// @popover-arrow-color: @popover-bg;
|
||||
//** Popover outer arrow width
|
||||
//** Popover outer arrow color
|
||||
// @popover-arrow-outer-color: @popover-bg;
|
||||
//** Popover distance with trigger
|
||||
// @popover-distance: @popover-arrow-width + 4px;
|
||||
|
||||
// Modal
|
||||
// --
|
||||
// @modal-mask-bg: rgba(0, 0, 0, 0.65);
|
||||
|
||||
// Progress
|
||||
// --
|
||||
// @progress-default-color: @processing-color;
|
||||
// @progress-remaining-color: @background-color-base;
|
||||
|
||||
// Menu
|
||||
// ---
|
||||
// @menu-inline-toplevel-item-height: 40px;
|
||||
// @menu-item-height: 40px;
|
||||
// @menu-collapsed-width: 80px;
|
||||
// @menu-bg: @component-background;
|
||||
// @menu-item-color: @text-color;
|
||||
// @menu-highlight-color: @primary-color;
|
||||
// @menu-item-active-bg: @item-active-bg;
|
||||
// @menu-item-group-title-color: @text-color-secondary;
|
||||
// dark theme
|
||||
// @menu-dark-color: @text-color-secondary-dark;
|
||||
// @menu-dark-bg: @layout-header-background;
|
||||
// @menu-dark-arrow-color: #fff;
|
||||
// @menu-dark-submenu-bg: #000c17;
|
||||
// @menu-dark-highlight-color: #fff;
|
||||
// @menu-dark-item-active-bg: @primary-color;
|
||||
|
||||
// Spin
|
||||
// ---
|
||||
// @spin-dot-size-sm: 14px;
|
||||
// @spin-dot-size: 20px;
|
||||
// @spin-dot-size-lg: 32px;
|
||||
|
||||
// Table
|
||||
// --
|
||||
// @table-header-bg: @background-color-light;
|
||||
// @table-header-sort-bg: @background-color-base;
|
||||
// @table-row-hover-bg: @primary-1;
|
||||
// @table-selected-row-bg: #fafafa;
|
||||
// @table-expanded-row-bg: #fbfbfb;
|
||||
// @table-padding-vertical: 16px;
|
||||
// @table-padding-horizontal: 16px;
|
||||
|
||||
// Tag
|
||||
// --
|
||||
// @tag-default-bg: @background-color-light;
|
||||
// @tag-default-color: @text-color;
|
||||
// @tag-font-size: @font-size-sm;
|
||||
|
||||
// TimePicker
|
||||
// ---
|
||||
// @time-picker-panel-column-width: 56px;
|
||||
// @time-picker-panel-width: @time-picker-panel-column-width * 3;
|
||||
// @time-picker-selected-bg: @background-color-base;
|
||||
|
||||
// Carousel
|
||||
// ---
|
||||
// @carousel-dot-width: 16px;
|
||||
// @carousel-dot-height: 3px;
|
||||
// @carousel-dot-active-width: 24px;
|
||||
|
||||
// Badge
|
||||
// ---
|
||||
// @badge-height: 20px;
|
||||
// @badge-dot-size: 6px;
|
||||
// @badge-font-size: @font-size-sm;
|
||||
// @badge-font-weight: normal;
|
||||
// @badge-status-size: 6px;
|
||||
|
||||
// Rate
|
||||
// ---
|
||||
// @rate-star-color: @yellow-6;
|
||||
// @rate-star-bg: @border-color-split;
|
||||
|
||||
// Card
|
||||
// ---
|
||||
// @card-head-color: @heading-color;
|
||||
// @card-head-background: @component-background;
|
||||
// @card-head-padding: 16px;
|
||||
// @card-inner-head-padding: 12px;
|
||||
// @card-padding-base: 24px;
|
||||
// @card-padding-wider: 32px;
|
||||
// @card-actions-background: @background-color-light;
|
||||
// @card-shadow: 0 2px 8px rgba(0, 0, 0, .09);
|
||||
|
||||
// Tabs
|
||||
// ---
|
||||
// '@tabs-card-head-background': '@background-color-light';
|
||||
// '@tabs-card-height': '40px';
|
||||
// '@tabs-card-active-color': '@primary-color';
|
||||
// '@tabs-title-font-size': '@font-size-base';
|
||||
// '@tabs-title-font-size-lg': '@font-size-lg';
|
||||
// '@tabs-title-font-size-sm': '@font-size-base';
|
||||
// '@tabs-ink-bar-color': '@primary-color';
|
||||
// '@tabs-bar-margin': '0 0 16px 0';
|
||||
// '@tabs-horizontal-margin': '0 32px 0 0';
|
||||
// '@tabs-horizontal-padding': '12px 16px';
|
||||
// '@tabs-vertical-padding': '8px 24px';
|
||||
// '@tabs-vertical-margin': '0 0 16px 0';
|
||||
// '@tabs-scrolling-size': '32px';
|
||||
// '@tabs-highlight-color': '@primary-color';
|
||||
// '@tabs-hover-color': '@primary-5';
|
||||
// '@tabs-active-color': '@primary-7';
|
||||
|
||||
// BackTop
|
||||
// ---
|
||||
// '@back-top-color': '#fff';
|
||||
// '@back-top-bg': '@text-color-secondary';
|
||||
// '@back-top-hover-bg': '@text-color';
|
||||
|
||||
// Avatar
|
||||
// ---
|
||||
// '@avatar-size-base': '32px';
|
||||
// '@avatar-size-lg': '40px';
|
||||
// '@avatar-size-sm': '24px';
|
||||
// '@avatar-font-size-base': '18px';
|
||||
// '@avatar-font-size-lg': '24px';
|
||||
// '@avatar-font-size-sm': '14px';
|
||||
// '@avatar-bg': '#ccc';
|
||||
// '@avatar-color': '#fff';
|
||||
// '@avatar-border-radius': '@border-radius-base;'
|
||||
|
||||
// Switch
|
||||
// ---
|
||||
// '@switch-height': '22px';
|
||||
// '@switch-sm-height': '16px';
|
||||
// '@switch-sm-checked-margin-left': '-(@switch-sm-height - 3px)';
|
||||
// '@switch-disabled-opacity': '0.4';
|
||||
// '@switch-color': '@primary-color';
|
||||
|
||||
// Pagination
|
||||
// ---
|
||||
// '@pagination-item-size': '32px';
|
||||
// '@pagination-item-size-sm': '24px';
|
||||
// '@pagination-font-family': 'Arial';
|
||||
// '@pagination-font-weight-active': '500';
|
||||
|
||||
// Breadcrumb
|
||||
// ---
|
||||
// '@breadcrumb-base-color': '@text-color-secondary';
|
||||
// '@breadcrumb-last-item-color': '@text-color';
|
||||
// '@breadcrumb-font-size': '@font-size-base';
|
||||
// '@breadcrumb-icon-font-size': '@font-size-sm';
|
||||
// '@breadcrumb-link-color': '@text-color-secondary';
|
||||
// '@breadcrumb-link-color-hover': '@primary-5';
|
||||
// '@breadcrumb-separator-color': '@text-color-secondary';
|
||||
// '@breadcrumb-separator-margin': '0 @padding-xs';
|
||||
|
||||
// Slider
|
||||
// ---
|
||||
// '@slider-margin': '14px 6px 10px';
|
||||
// '@slider-rail-background-color': '@background-color-base';
|
||||
// '@slider-rail-background-color-hover': '#e1e1e1';
|
||||
// '@slider-track-background-color': '@primary-3';
|
||||
// '@slider-track-background-color-hover': '@primary-4';
|
||||
// '@slider-handle-color': '@primary-3';
|
||||
// '@slider-handle-color-hover': '@primary-4';
|
||||
// '@slider-handle-color-focus': 'tint(@primary-color, 20%)';
|
||||
// '@slider-handle-color-focus-shadow': 'tint(@primary-color, 50%)';
|
||||
// '@slider-handle-color-tooltip-open': '@primary-color';
|
||||
// '@slider-dot-border-color': '@border-color-split';
|
||||
// '@slider-dot-border-color-active': 'tint(@primary-color, 50%)';
|
||||
// '@slider-disabled-color': '@disabled-color';
|
||||
// '@slider-disabled-background-color': '@component-background';
|
||||
|
||||
// Collapse
|
||||
// ---
|
||||
// '@collapse-header-padding': '12px 0 12px 40px';
|
||||
// '@collapse-header-bg': '@background-color-light';
|
||||
// '@collapse-content-padding': '@padding-md';
|
||||
// '@collapse-content-bg': '@component-background';
|
||||
|
||||
|
||||
|
||||
},
|
||||
})(config, env);
|
||||
return config;
|
||||
};
|
|
@ -1,25 +0,0 @@
|
|||
version: '3.5'
|
||||
services:
|
||||
prod-build:
|
||||
container_name: prod-build
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
# - REACT_APP_DOMAIN=http://mobilecorelb-1807532632.ap-southeast-1.elb.amazonaws.com/
|
||||
# - REACT_APP_DOMAIN=https://mobilelink.unioil.com
|
||||
- REACT_APP_DOMAIN=https://mobileapi.unioilapps.com
|
||||
- REACT_APP_PATH=api/cms
|
||||
- REACT_APP_IMG_PATH=unioilQA/
|
||||
restart: always
|
||||
ports:
|
||||
- 8089:80
|
||||
volumes:
|
||||
- '.:/usr/src/app'
|
||||
- '/usr/src/app/node_modules'
|
||||
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
version: '3.5'
|
||||
services:
|
||||
public-build:
|
||||
container_name: public-build
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- REACT_APP_PUBLIC=true
|
||||
# - PUBLIC_URL=/paypal
|
||||
- REACT_APP_DOMAIN=https://mobileapid.unioil.com
|
||||
- REACT_APP_PATH=api/cms
|
||||
- REACT_APP_IMG_PATH=unioilQA
|
||||
- GENERATE_SOURCEMAP=false
|
||||
restart: always
|
||||
ports:
|
||||
- 8095:80
|
||||
volumes:
|
||||
- '.:/usr/src/app'
|
||||
- '/usr/src/app/node_modules'
|
|
@ -1,80 +0,0 @@
|
|||
version: '3.5'
|
||||
services:
|
||||
test-build:
|
||||
container_name: test-build
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- REACT_APP_DOMAIN=http://192.168.0.68
|
||||
- REACT_APP_PATH=unioilQA/public/index.php/api/cms
|
||||
- REACT_APP_IMG_PATH=unioilQA/
|
||||
restart: always
|
||||
ports:
|
||||
- 8089:80
|
||||
volumes:
|
||||
- '.:/usr/src/app'
|
||||
- '/usr/src/app/node_modules'
|
||||
dev-build:
|
||||
container_name: dev-build
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- REACT_APP_DOMAIN=http://192.168.0.68
|
||||
- REACT_APP_PATH=UniOilLoyaltyApp-BackEnd/public/index.php/api/cms
|
||||
- REACT_APP_IMG_PATH=UniOilLoyaltyApp-BackEnd
|
||||
restart: always
|
||||
ports:
|
||||
- 8081:80
|
||||
volumes:
|
||||
- '.:/usr/src/app'
|
||||
- '/usr/src/app/node_modules'
|
||||
public-dev-build:
|
||||
container_name: public-dev-build
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- REACT_APP_PUBLIC=true
|
||||
- REACT_APP_DOMAIN=http://192.168.0.68
|
||||
- REACT_APP_PATH=UniOilLoyaltyApp-BackEnd/public/index.php/api/cms
|
||||
- REACT_APP_IMG_PATH=UniOilLoyaltyApp-BackEnd/
|
||||
restart: always
|
||||
ports:
|
||||
- 8093:80
|
||||
volumes:
|
||||
- '.:/usr/src/app'
|
||||
- '/usr/src/app/node_modules'
|
||||
public-test-build:
|
||||
container_name: public-test-build
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- REACT_APP_PUBLIC=true
|
||||
- REACT_APP_DOMAIN=http://192.168.0.68
|
||||
- REACT_APP_PATH=unioilQA/public/index.php/api/cms
|
||||
- REACT_APP_IMG_PATH=unioilQA
|
||||
restart: always
|
||||
ports:
|
||||
- 8090:80
|
||||
volumes:
|
||||
- '.:/usr/src/app'
|
||||
- '/usr/src/app/node_modules'
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2015",
|
||||
"baseUrl": "src",
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"build",
|
||||
"public",
|
||||
"__test__"
|
||||
]
|
||||
}
|
|
@ -1,278 +0,0 @@
|
|||
{
|
||||
"posts": [
|
||||
{
|
||||
"id": 1441,
|
||||
"title": "11-json-server",
|
||||
"author": "11-server-deauthor"
|
||||
},
|
||||
{
|
||||
"title": "14-Title",
|
||||
"author": "14-Title Data",
|
||||
"id": 4414
|
||||
},
|
||||
{
|
||||
"title": "tes wafe",
|
||||
"author": "weataewtaew",
|
||||
"id": 1446
|
||||
},
|
||||
{
|
||||
"title": "1-json-server-test",
|
||||
"author": "werewrwe",
|
||||
"id": 1447
|
||||
},
|
||||
{
|
||||
"id": 447,
|
||||
"title": "7-json-server",
|
||||
"author": "7-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 449,
|
||||
"title": "9-json-server",
|
||||
"author": "9-tserver-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 14440,
|
||||
"title": "10-json-server",
|
||||
"author": "10-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 1441,
|
||||
"title": "11-json-server",
|
||||
"author": "11-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 12443,
|
||||
"title": "12-json-server",
|
||||
"author": "12-server-deauthor"
|
||||
},
|
||||
{
|
||||
"title": "tes",
|
||||
"author": "ewrwer",
|
||||
"id": 1334444
|
||||
},
|
||||
{
|
||||
"title": "14-Title",
|
||||
"author": "14-Title Data",
|
||||
"id": 143444
|
||||
},
|
||||
{
|
||||
"title": "fytyiftyfy",
|
||||
"author": "ftftcftc",
|
||||
"id": 15344
|
||||
},
|
||||
{
|
||||
"title": "tes wafe",
|
||||
"author": "weataewtaew",
|
||||
"id": 163444
|
||||
},
|
||||
{
|
||||
"title": "1-json-server-test",
|
||||
"author": "werewrwe",
|
||||
"id": 17344
|
||||
},
|
||||
{
|
||||
"id": 744,
|
||||
"title": "7-json-server",
|
||||
"author": "7-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 944,
|
||||
"title": "9-json-server",
|
||||
"author": "9-tserver-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 104,
|
||||
"title": "10-json-server",
|
||||
"author": "10-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 141,
|
||||
"title": "11-json-server",
|
||||
"author": "11-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 1244,
|
||||
"title": "12-json-server",
|
||||
"author": "12-server-deauthor"
|
||||
},
|
||||
{
|
||||
"title": "tes",
|
||||
"author": "ewrwer",
|
||||
"id": 1344
|
||||
},
|
||||
{
|
||||
"title": "14-Title",
|
||||
"author": "14-Title Data",
|
||||
"id": 1444
|
||||
},
|
||||
{
|
||||
"title": "fytyiftyfy",
|
||||
"author": "ftftcftc",
|
||||
"id": 1544
|
||||
},
|
||||
{
|
||||
"title": "tes wafe",
|
||||
"author": "weataewtaew",
|
||||
"id": 164
|
||||
},
|
||||
{
|
||||
"title": "1-json-server-test",
|
||||
"author": "werewrwe",
|
||||
"id": 1744
|
||||
},
|
||||
{
|
||||
"id": 744,
|
||||
"title": "7-json-server",
|
||||
"author": "7-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 944,
|
||||
"title": "9-json-server",
|
||||
"author": "9-tserver-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 1044,
|
||||
"title": "10-json-server",
|
||||
"author": "10-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 1144,
|
||||
"title": "11-json-server",
|
||||
"author": "11-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 12344,
|
||||
"title": "12-json-server",
|
||||
"author": "12-server-deauthor"
|
||||
},
|
||||
{
|
||||
"title": "tes",
|
||||
"author": "ewrwer",
|
||||
"id": 13344
|
||||
},
|
||||
{
|
||||
"title": "14-Title",
|
||||
"author": "14-Title Data",
|
||||
"id": 14344
|
||||
},
|
||||
{
|
||||
"title": "fytyiftyfy",
|
||||
"author": "ftftcftc",
|
||||
"id": 15344
|
||||
},
|
||||
{
|
||||
"title": "tes wafe",
|
||||
"author": "weataewtaew",
|
||||
"id": 16344
|
||||
},
|
||||
{
|
||||
"title": "1-json-server-test",
|
||||
"author": "werewrwe",
|
||||
"id": 17344
|
||||
},
|
||||
{
|
||||
"id": 744,
|
||||
"title": "7-json-server",
|
||||
"author": "7-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 944,
|
||||
"title": "9-json-server",
|
||||
"author": "9-tserver-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 1044,
|
||||
"title": "10-json-server",
|
||||
"author": "10-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 114444,
|
||||
"title": "11-json-server",
|
||||
"author": "11-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 1244,
|
||||
"title": "12-json-server",
|
||||
"author": "12-server-deauthor"
|
||||
},
|
||||
{
|
||||
"title": "tes",
|
||||
"author": "ewrwer",
|
||||
"id": 1344
|
||||
},
|
||||
{
|
||||
"title": "14-Title",
|
||||
"author": "14-Title Data",
|
||||
"id": 1444
|
||||
},
|
||||
{
|
||||
"title": "fytyiftyfy",
|
||||
"author": "ftftcftc",
|
||||
"id": 1544
|
||||
},
|
||||
{
|
||||
"title": "tes wafe",
|
||||
"author": "weataewtaew",
|
||||
"id": 1644
|
||||
},
|
||||
{
|
||||
"title": "1-json-server-test",
|
||||
"author": "werewrwe",
|
||||
"id": 174
|
||||
},
|
||||
{
|
||||
"id": 744,
|
||||
"title": "7-json-server",
|
||||
"author": "7-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 944,
|
||||
"title": "9-json-server",
|
||||
"author": "9-tserver-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 104,
|
||||
"title": "10-json-server",
|
||||
"author": "10-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 114,
|
||||
"title": "11-json-server",
|
||||
"author": "11-server-deauthor"
|
||||
},
|
||||
{
|
||||
"id": 1234,
|
||||
"title": "12-json-server",
|
||||
"author": "12-server-deauthor"
|
||||
},
|
||||
{
|
||||
"title": "tes",
|
||||
"author": "ewrwer",
|
||||
"id": 1334
|
||||
},
|
||||
{
|
||||
"title": "14-Title",
|
||||
"author": "14-Title Data",
|
||||
"id": 1434
|
||||
},
|
||||
{
|
||||
"title": "fytyiftyfy",
|
||||
"author": "ftftcftc",
|
||||
"id": 15344
|
||||
},
|
||||
{
|
||||
"title": "tes wafe",
|
||||
"author": "weataewtaew",
|
||||
"id": 1634
|
||||
},
|
||||
{
|
||||
"title": "1-json-server-test",
|
||||
"author": "werewrwe",
|
||||
"id": 1734
|
||||
}
|
||||
],
|
||||
"comments": [],
|
||||
"profile": {
|
||||
"name": "typicode"
|
||||
}
|
||||
}
|
65
package.json
65
package.json
|
@ -1,65 +0,0 @@
|
|||
{
|
||||
"name": "my-app",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "4.0.0",
|
||||
"@react-google-maps/api": "^1.9.7",
|
||||
"antd": "^3.9.1",
|
||||
"antd-input-password": "^0.3.0",
|
||||
"axios": "^0.18.0",
|
||||
"crypto-js": "^3.1.9-1",
|
||||
"dsbridge": "^3.1.3",
|
||||
"filesize": "^3.6.1",
|
||||
"formik": "^1.2.0",
|
||||
"history": "^4.7.2",
|
||||
"js-file-download": "^0.4.4",
|
||||
"libsodium-wrappers": "^0.7.3",
|
||||
"moment": "^2.27.0",
|
||||
"query-string": "^5.1.1",
|
||||
"react": "^16.7.0",
|
||||
"react-copy-to-clipboard": "^5.0.1",
|
||||
"react-csv": "^2.0.3",
|
||||
"react-csv-reader": "^3.1.0",
|
||||
"react-device-detect": "^1.6.1",
|
||||
"react-dom": "^16.5.0",
|
||||
"react-geocode": "^0.2.1",
|
||||
"react-google-autocomplete": "^1.2.6",
|
||||
"react-google-map": "^3.1.1",
|
||||
"react-google-maps": "^9.4.5",
|
||||
"react-helmet": "^5.2.0",
|
||||
"react-idle-timer": "^4.0.9",
|
||||
"react-input-mask": "^2.0.4",
|
||||
"react-loadable": "^5.5.0",
|
||||
"react-papaparse": "^3.7.1",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-router-dom": "^4.2.2",
|
||||
"react-router-redux": "^4.0.8",
|
||||
"react-scripts": "1.1.5",
|
||||
"redux": "^4.0.0",
|
||||
"redux-logger": "^3.0.6",
|
||||
"redux-saga": "^0.16.0",
|
||||
"styled-components": "^3.4.5",
|
||||
"universal-cookie": "3.0.4",
|
||||
"yup": "^0.26.3"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-app-rewired start",
|
||||
"build": "react-app-rewired build",
|
||||
"test": "react-app-rewired test --env=jsdom",
|
||||
"eject": "react-app-rewired eject",
|
||||
"dev": "docker-compose up -d --build",
|
||||
"dev:stop": "docker-compose down",
|
||||
"prod": "docker-compose -f docker-compose-prod.yml up -d --build",
|
||||
"prod:stop": "docker-compose -f docker-compose-prod.yml down",
|
||||
"flow": "flow"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-plugin-import": "^1.7.0",
|
||||
"debug": "^3.1.0",
|
||||
"flow-bin": "0.80.0",
|
||||
"less-plugin-variables-output": "^1.2.0",
|
||||
"react-app-rewire-less": "^2.1.3",
|
||||
"react-app-rewired": "^1.6.2"
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
|
@ -1,69 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is added to the
|
||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon_unioil.ico">
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
<script type="text/javascript">
|
||||
|
||||
// For Adroid
|
||||
//window.AndroidTopUpSuccess = AndroidTopUpFailed;
|
||||
window.AndroidTopUpFailed = AndroidTopUpFailed;
|
||||
|
||||
// For iOS
|
||||
window.iOStopUpSuccess = iOStopUpSuccess;
|
||||
window.iOStopUpFailed = iOStopUpFailed;
|
||||
|
||||
function AndroidTopUpFailed() {
|
||||
// For Adroid
|
||||
AndroidInterface.returnTopUpPage();
|
||||
|
||||
}
|
||||
|
||||
function iOStopUpSuccess() {
|
||||
//alert('top up success ' );
|
||||
// For iOS
|
||||
window.webkit.messageHandlers.backToHomePage.postMessage({'ButtonId':'clickMeButton'})
|
||||
}
|
||||
|
||||
function iOStopUpFailed() {
|
||||
//alert('back to top up' );
|
||||
// For iOS
|
||||
window.webkit.messageHandlers.backToTopUp.postMessage({'ButtonId':'clickMeButton'})
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon_unioil.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
}
|
||||
],
|
||||
"start_url": "./index.html",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
215
src/App.js
215
src/App.js
|
@ -1,215 +0,0 @@
|
|||
import React, { Component, Fragment } from 'react';
|
||||
import { BrowserRouter as Router, Route, Redirect, Switch, withRouter } from 'react-router-dom';
|
||||
import Loadable from 'react-loadable';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import LoginLayoutRoute from './components/Login/Routes';
|
||||
import DashboardRoute from './components/Dashboard/Routes';
|
||||
import Loading from './components/Loading';
|
||||
|
||||
import { getCookie } from './utils/cookie';
|
||||
import { customAction } from './actions';
|
||||
import { API_UNI_OIL, API_POST } from 'utils/Api';
|
||||
|
||||
const AsyncLogin = Loadable({
|
||||
loader: () => import('./containers/public/Login'),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AsyncRegistration = Loadable({
|
||||
loader: () => import('./containers/public/Registration'),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AsyncChangePassword = Loadable({
|
||||
loader: () => import('./containers/public/ChangePassword'),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AsyncPublicTopSuccessPage = Loadable({
|
||||
loader: () => import('./containers/public/PublicTopSuccessPage'),
|
||||
loading: () => {
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
const AsyncPublicTopErrorPage = Loadable({
|
||||
loader: () => import('./containers/public/PublicTopErrorPage'),
|
||||
loading: () => {
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
const AsyncMyProfile = Loadable({
|
||||
loader: () => import('./containers/private/MyProfile'),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AsyncNotification = Loadable({
|
||||
loader: () => import('./containers/private/Notifications'),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AsyncUserManagement = Loadable({
|
||||
loader: () => import('./containers/private/UserManagement'),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AsyncMemberManagement = Loadable({
|
||||
loader: () => import('./containers/private/MemberManagement'),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AsyncPhotoSlider = Loadable({
|
||||
loader: () => import('./containers/private/HomePage/PhotoSlider'),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AsyncPromotions = Loadable({
|
||||
loader: () => import('./containers/private/Promotions'),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AsyncTopUp = Loadable({
|
||||
loader: () => import('./containers/private/TopUp'),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AsyncCardTypes = Loadable({
|
||||
loader: () => import('./containers/private/AboutUs'),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AsyncReports = Loadable({
|
||||
loader: () => import('./containers/private/Reports'),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AsyncSystemPreferences = Loadable({
|
||||
loader: () => import('./containers/private/SystemPreferences'),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AsyncPage404 = Loadable({
|
||||
loader: () => import('./components/PageError/404'),
|
||||
loading: Loading,
|
||||
});
|
||||
const AsyncLocator = Loadable({
|
||||
loader: () => import('./containers/private/StationLocator/Location'),
|
||||
loading: Loading,
|
||||
});
|
||||
const AsyncBranches = Loadable({
|
||||
loader: () => import('./containers/private/StationLocator/Branches'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
const AsyncFuels = Loadable({
|
||||
loader: () => import('./containers/private/StationLocator/Fuels'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
const CaptureRouteNotFound = withRouter(({ children, location }) => {
|
||||
return location && location.state && location.state.pageNotFound ? <AsyncPage404 /> : children;
|
||||
});
|
||||
|
||||
const publicRoutes = [
|
||||
'/',
|
||||
'/login',
|
||||
'/registration',
|
||||
'/forgot-password',
|
||||
'/change-password',
|
||||
'/topup-success-page',
|
||||
'/topup-error-page',
|
||||
];
|
||||
|
||||
class App extends Component {
|
||||
state = {
|
||||
accessAuth: false,
|
||||
mounting: true,
|
||||
};
|
||||
|
||||
componentDidMount = async () => {
|
||||
if (getCookie('TOKEN')) {
|
||||
let { history, customAction } = this.props;
|
||||
let { replace, location } = history;
|
||||
|
||||
API_UNI_OIL.defaults.headers.common['Authorization'] = `Bearer ${getCookie('TOKEN').token}`;
|
||||
//customAction({type: 'LOGIN_SUCCESS' });
|
||||
|
||||
try {
|
||||
let response = await API_POST(`adminProfile`);
|
||||
response.data.data['userInfo'] = { ...response.data.data };
|
||||
|
||||
customAction({
|
||||
type: 'LOGIN_SUCCESS',
|
||||
payload: { ...response.data.data },
|
||||
});
|
||||
} catch ({ response: error }) {
|
||||
//notification.error({ message: "Error", description: "Something went wrong loading user data." , duration: 20, });
|
||||
}
|
||||
|
||||
if (publicRoutes.includes(location.pathname)) replace('/user-management');
|
||||
}
|
||||
this.setState({ mounting: false });
|
||||
};
|
||||
|
||||
render() {
|
||||
console.log('====================================');
|
||||
console.log(process.env.REACT_APP_API, process.env.REACT_APP_IMG_URL, process.env.REACT_APP_PUBLIC, 'API LIST!!!');
|
||||
console.log('====================================');
|
||||
if (this.state.mounting) return null;
|
||||
|
||||
if (process.env.REACT_APP_PUBLIC === 'false') {
|
||||
return (
|
||||
<Router>
|
||||
<Switch>
|
||||
<Redirect exact from='/' to='/login' />
|
||||
<LoginLayoutRoute exact path='/login' component={AsyncLogin} />
|
||||
<LoginLayoutRoute exact path='/registration' component={AsyncRegistration} />
|
||||
<LoginLayoutRoute exact path='/change-password' component={AsyncChangePassword} />
|
||||
{/* PRIVATE ROUTES */}
|
||||
<DashboardRoute path='/user-management' component={AsyncUserManagement} />
|
||||
<DashboardRoute path='/notifications' component={AsyncNotification} />
|
||||
<DashboardRoute path='/member-management' component={AsyncMemberManagement} />
|
||||
<DashboardRoute path='/home-page' component={AsyncPhotoSlider} />
|
||||
<DashboardRoute path='/promotions' component={AsyncPromotions} />
|
||||
<DashboardRoute path='/top-up' component={AsyncTopUp} />
|
||||
<DashboardRoute path='/about-us' component={AsyncCardTypes} />
|
||||
<DashboardRoute path='/reports' component={AsyncReports} />
|
||||
<DashboardRoute path='/stations' component={AsyncLocator}/>
|
||||
<DashboardRoute path='/branches' component={AsyncBranches}/>
|
||||
<DashboardRoute path='/fuels' component={AsyncFuels} />
|
||||
<DashboardRoute path='/system-parameters' component={AsyncSystemPreferences} />
|
||||
<DashboardRoute path='/my-profile' component={AsyncMyProfile} />
|
||||
<Route exact path='/topup-success-page' component={AsyncPublicTopSuccessPage} />
|
||||
<Route exact path='/topup-error-page' component={AsyncPublicTopErrorPage} />
|
||||
<Route exact path='/404' component={AsyncPage404} />
|
||||
<DashboardRoute path='*' component={AsyncPage404} />
|
||||
</Switch>
|
||||
</Router>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Router>
|
||||
<Switch>
|
||||
<Redirect exact from='/' to='/topup-success-page' />
|
||||
<Redirect exact from='/login' to='/topup-success-page' />
|
||||
<Route exact path='/topup-success-page' component={AsyncPublicTopSuccessPage} />
|
||||
<Route exact path='/topup-error-page' component={AsyncPublicTopErrorPage} />
|
||||
<Route exact path='/404' component={AsyncPage404} />
|
||||
<DashboardRoute path='*' component={AsyncPage404} />
|
||||
</Switch>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
App = connect(
|
||||
(state) => ({
|
||||
isAuthenticated: state.auth.isAuthenticated,
|
||||
}),
|
||||
{ customAction }
|
||||
)(App);
|
||||
|
||||
export default withRouter(App);
|
|
@ -1,9 +0,0 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<App />, div);
|
||||
ReactDOM.unmountComponentAtNode(div);
|
||||
});
|
|
@ -1,6 +0,0 @@
|
|||
export function customAction({type, payload}) {
|
||||
return {
|
||||
type: type,
|
||||
payload
|
||||
};
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 224 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 57.834 57.955"><defs><style>.a{fill:#f4825c;stroke:#707070;}.b{fill:#e74610;}.c{stroke:none;}.d{fill:none;}</style></defs><g transform="translate(-0.498 0.199)"><g transform="translate(0 0)"><g class="a" transform="translate(1.009 0.934)"><circle class="c" cx="27.989" cy="27.989" r="27.989"/><circle class="d" cx="27.989" cy="27.989" r="27.489"/></g><g transform="translate(-26.502 -27.6)"><g transform="translate(27 27.4)"><path class="b" d="M55.917,85.355A28.978,28.978,0,1,1,84.834,56.317,29.012,29.012,0,0,1,55.917,85.355Zm0-54.31A25.272,25.272,0,1,0,81.189,56.317,25.253,25.253,0,0,0,55.917,31.045Z" transform="translate(-27 -27.4)"/><g transform="translate(18.529 18.65)"><path class="b" d="M59.638,63.344a1.827,1.827,0,0,1-1.337-.486l-8.5-8.5a1.762,1.762,0,0,1,0-2.551l8.5-8.5a1.8,1.8,0,0,1,2.551,2.551l-7.168,7.168,7.168,7.169a1.762,1.762,0,0,1,0,2.551A1.234,1.234,0,0,1,59.638,63.344Z" transform="translate(-40.745 -42.75)"/><path class="b" d="M44.133,63.323a1.827,1.827,0,0,1-1.336-.486,1.762,1.762,0,0,1,0-2.551l7.169-7.169L42.8,45.948A1.8,1.8,0,0,1,45.348,43.4l8.5,8.5a1.762,1.762,0,0,1,0,2.551l-8.5,8.5A1.814,1.814,0,0,1,44.133,63.323Z" transform="translate(-42.25 -42.729)"/></g></g></g></g></g></svg>
|
Before Width: | Height: | Size: 1.2 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 58.184 58.184"><defs><style>.a{fill:#56b68b;stroke:#707070;}.b{fill:#018952;fill-rule:evenodd;}.c{stroke:none;}.d{fill:none;}</style></defs><g transform="translate(-138.502 -248.613)"><g transform="translate(138.502 248.613)"><g transform="translate(0 0)"><g class="a" transform="translate(1.009 0.934)"><circle class="c" cx="27.989" cy="27.989" r="27.989"/><circle class="d" cx="27.989" cy="27.989" r="27.489"/></g><path class="b" d="M47.664,22.747l2.3,2.3L31.8,43.209l-2.3,2.3-2.3-2.3-8.978-8.978,2.3-2.3L29.5,40.913ZM34.092,5A29.092,29.092,0,1,1,5,34.092,29.079,29.079,0,0,1,34.092,5Zm0,3.967A25.16,25.16,0,1,1,8.967,34.092,25.173,25.173,0,0,1,34.092,8.967Z" transform="translate(-5 -5)"/></g></g></g></svg>
|
Before Width: | Height: | Size: 763 B |
Binary file not shown.
Before Width: | Height: | Size: 8.1 KiB |
|
@ -1,683 +0,0 @@
|
|||
import React from "react";
|
||||
import {
|
||||
Table,
|
||||
Input,
|
||||
Icon,
|
||||
Divider,
|
||||
Tooltip,
|
||||
Popconfirm,
|
||||
message,
|
||||
Button,
|
||||
Pagination,
|
||||
Row,
|
||||
Col
|
||||
} from "antd";
|
||||
//import { callApi } from "utils/Api";
|
||||
import { Link, withRouter } from "react-router-dom";
|
||||
import querystring from "querystring";
|
||||
import { encrypt, decrypt } from 'utils/encrypto'
|
||||
// const querystring = require("querystring");
|
||||
const { Column, ColumnGroup } = Table;
|
||||
const Search = Input.Search;
|
||||
|
||||
class CustomTable extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
data: [],
|
||||
loading: false,
|
||||
filteredInfo: null,
|
||||
sortedInfo: null,
|
||||
pageName: '_page',
|
||||
currentPage: 1,
|
||||
sizeName: '_limit',
|
||||
pageSize: 10,
|
||||
totalData: 100,
|
||||
searchValue: null,
|
||||
headerColumns: props.columns.map(column => {
|
||||
if (column.sorter) {
|
||||
column.sorter = (a, b) => a[column.dataIndex] - b[column.dataIndex];
|
||||
column.sortOrder = null;
|
||||
}
|
||||
return column;
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.handleInitialLoad()
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState, snapshot) {
|
||||
const { currentPage, pageSize, pageName } = this.state;
|
||||
|
||||
if (prevProps.location.search !== this.props.location.search) {
|
||||
|
||||
if (this.props.location.search === "") {
|
||||
this.handleclearAll();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (prevState.sortedInfo !== this.state.sortedInfo) {
|
||||
//Sort Columns Function
|
||||
this.setState({
|
||||
headerColumns: this.state.headerColumns.map(column => {
|
||||
if (
|
||||
this.state.sortedInfo &&
|
||||
this.state.sortedInfo.columnKey === column.dataIndex
|
||||
) {
|
||||
column.sortOrder = this.state.sortedInfo.order;
|
||||
}
|
||||
return column;
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
handleInitialLoad = () => {
|
||||
const { search } = this.props.location;
|
||||
const { currentPage, pageSize, pageName, sizeName } = this.state;
|
||||
|
||||
if (search) {
|
||||
let parsed = querystring.parse(search.substring(1));
|
||||
console.log('====================================');
|
||||
console.log(parsed,pageName, sizeName,parsed[pageName], parsed[sizeName], "&&&&&&SEARCH!!");
|
||||
console.log('====================================');
|
||||
|
||||
if (parsed) {
|
||||
if (parsed[pageName] && parsed[sizeName] && parsed.q && parsed._sort && parsed._order ) {
|
||||
this.handleUpdateData({
|
||||
page: parseInt(parsed[pageName]),
|
||||
size: parseInt(parsed[sizeName]),
|
||||
search: parsed.q
|
||||
});
|
||||
} else if (parsed[pageName] && parsed[sizeName] && parsed.q) {
|
||||
alert("Search")
|
||||
this.handleUpdateData({
|
||||
page: parseInt(parsed[pageName]),
|
||||
size: parseInt(parsed[sizeName]),
|
||||
search: parsed.q
|
||||
});
|
||||
} else if (parsed[pageName] && parsed[sizeName]) {
|
||||
this.handleUpdateData({
|
||||
page: parseInt(parsed[pageName]),
|
||||
size: parseInt(parsed[sizeName]),
|
||||
});
|
||||
}
|
||||
// this.fetch({
|
||||
// ...parsed
|
||||
// });
|
||||
}
|
||||
} else {
|
||||
this.handleUpdateData({
|
||||
page: currentPage,
|
||||
size: pageSize,
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
handleTableChange = (pagination, filters, sorter) => {
|
||||
const { currentPage, pageSize, searchValue } = this.state;
|
||||
console.log("====================================");
|
||||
console.log(filters, sorter, "tesadasdas");
|
||||
console.log("====================================");
|
||||
// this.setState({
|
||||
// filteredInfo: filters,
|
||||
// sortedInfo: sorter
|
||||
// });
|
||||
if (Object.keys(sorter).length !== 0) {
|
||||
// this.fetch({
|
||||
// _page: currentPage,
|
||||
// _limit: pageSize,
|
||||
// _sort: sorter.field,
|
||||
// _order: sorter.order === "ascend" ? "asc" : "desc",
|
||||
|
||||
// ...filters
|
||||
// });
|
||||
|
||||
if (searchValue) {
|
||||
this.handleUpdateData({
|
||||
sort: sorter,
|
||||
filter: filters,
|
||||
search: searchValue
|
||||
});
|
||||
} else {
|
||||
this.handleUpdateData({ sort: sorter, filter: filters });
|
||||
}
|
||||
} else {
|
||||
if (searchValue) {
|
||||
this.handleUpdateData({ filter: filters, search: searchValue });
|
||||
} else {
|
||||
this.handleUpdateData({ filter: filters });
|
||||
}
|
||||
// this.fetch({
|
||||
// _page: currentPage,
|
||||
// _limit: pageSize,
|
||||
// ...filters
|
||||
// });
|
||||
}
|
||||
};
|
||||
|
||||
fetch = async (params = {}) => {
|
||||
let { url, history } = this.props;
|
||||
const stringified = querystring.stringify(params);
|
||||
|
||||
console.log("GGGGG3333", url.default, stringified, params, window.location);
|
||||
this.setState({ loading: true });
|
||||
// history.push(`${url.default}?${stringified}`);
|
||||
history.push({
|
||||
pathname: url.default,
|
||||
search: stringified
|
||||
});
|
||||
try {
|
||||
// let response = await callApi({
|
||||
// url: url.default,
|
||||
// params: {
|
||||
// _page: params._page,
|
||||
// _limit: params._limit,
|
||||
// ...params
|
||||
// }
|
||||
// });
|
||||
|
||||
// if (response.status === 200) {
|
||||
// this.setState({
|
||||
// loading: false,
|
||||
// data: response.data,
|
||||
// totalData: response.data.total ? response.data.total : 100
|
||||
// });
|
||||
// }
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
handleUpdateData = ({ search, sort, page, size, filter }) => {
|
||||
const {
|
||||
currentPage,
|
||||
pageSize,
|
||||
filteredInfo,
|
||||
sortedInfo,
|
||||
searchValue
|
||||
} = this.state;
|
||||
|
||||
console.log("====================================");
|
||||
console.log(
|
||||
search, sort, page, size, filter,
|
||||
"WWOOOPS!!"
|
||||
);
|
||||
console.log("====================================");
|
||||
|
||||
if (search && sort && filter) {
|
||||
|
||||
this.setState({
|
||||
filteredInfo: filter,
|
||||
sortedInfo: sort,
|
||||
searchValue: search,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: currentPage,
|
||||
_limit: pageSize,
|
||||
q: search,
|
||||
_sort: sort.field,
|
||||
_order: sort.order === "ascend" ? "asc" : "desc",
|
||||
...filter
|
||||
});
|
||||
|
||||
//filteredInfo value
|
||||
} else if (filter) {
|
||||
if (sort) {
|
||||
|
||||
this.setState({
|
||||
filteredInfo: filter,
|
||||
sortedInfo: sort,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: currentPage,
|
||||
_limit: pageSize,
|
||||
_sort: sort.field,
|
||||
_order: sort.order === "ascend" ? "asc" : "desc",
|
||||
...filter
|
||||
});
|
||||
} else if (search) {
|
||||
|
||||
this.setState({
|
||||
filteredInfo: filter,
|
||||
searchValue: search,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: currentPage,
|
||||
_limit: pageSize,
|
||||
q: search,
|
||||
...filter
|
||||
});
|
||||
} else {
|
||||
|
||||
this.setState({
|
||||
filteredInfo: filter,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: currentPage,
|
||||
_limit: pageSize,
|
||||
...filter
|
||||
});
|
||||
}
|
||||
//sortedInfo value
|
||||
} else if (sort) {
|
||||
if (filter) {
|
||||
this.setState({
|
||||
filteredInfo: filter,
|
||||
sortedInfo: sort,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: currentPage,
|
||||
_limit: pageSize,
|
||||
_sort: sort.field,
|
||||
_order: sort.order === "ascend" ? "asc" : "desc",
|
||||
...filter
|
||||
});
|
||||
} else if (search) {
|
||||
|
||||
this.setState({
|
||||
sortedInfo: sort,
|
||||
searchValue: search,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: currentPage,
|
||||
_limit: pageSize,
|
||||
q: search,
|
||||
_sort: sort.field,
|
||||
_order: sort.order === "ascend" ? "asc" : "desc"
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
sortedInfo: sort,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: currentPage,
|
||||
_limit: pageSize,
|
||||
_sort: sort.field,
|
||||
_order: sort.order === "ascend" ? "asc" : "desc"
|
||||
});
|
||||
}
|
||||
|
||||
//search Value
|
||||
} else if (search) {
|
||||
if (filter) {
|
||||
|
||||
this.setState({
|
||||
filteredInfo: filter,
|
||||
searchValue: search,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: currentPage,
|
||||
_limit: pageSize,
|
||||
q: search,
|
||||
...filter
|
||||
});
|
||||
} else if (sort) {
|
||||
|
||||
this.setState({
|
||||
sortedInfo: sort,
|
||||
searchValue: search,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: currentPage,
|
||||
_limit: pageSize,
|
||||
q: search,
|
||||
_sort: sort.field,
|
||||
_order: sort.order === "ascend" ? "asc" : "desc"
|
||||
});
|
||||
} else if (page && size) {
|
||||
alert(page, size, "OOOPS@")
|
||||
this.setState({
|
||||
currentPage: page,
|
||||
pageSize: size,
|
||||
searchValue: search,
|
||||
})
|
||||
this.fetch({
|
||||
_page: page,
|
||||
_limit: size,
|
||||
q: search
|
||||
});
|
||||
} else if (page) {
|
||||
|
||||
this.setState({
|
||||
currentPage: page,
|
||||
searchValue: search,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: page,
|
||||
_limit: pageSize,
|
||||
q: search
|
||||
});
|
||||
} else if (size) {
|
||||
|
||||
this.setState({
|
||||
pageSize: size,
|
||||
searchValue: search,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: currentPage,
|
||||
_limit: size,
|
||||
q: search
|
||||
});
|
||||
} else {
|
||||
|
||||
this.setState({
|
||||
searchValue: search,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: currentPage,
|
||||
_limit: pageSize,
|
||||
q: search
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (page && size) {
|
||||
this.setState({
|
||||
currentPage: page,
|
||||
pageSize: size,
|
||||
})
|
||||
|
||||
|
||||
this.fetch({
|
||||
_page: page,
|
||||
_limit: size
|
||||
});
|
||||
} else if (page) {
|
||||
|
||||
this.setState({
|
||||
currentPage: page,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: page,
|
||||
_limit: pageSize
|
||||
});
|
||||
} else if (size) {
|
||||
|
||||
this.setState({
|
||||
pageSize: size,
|
||||
})
|
||||
|
||||
this.fetch({
|
||||
_page: currentPage,
|
||||
_limit: size
|
||||
});
|
||||
} else {
|
||||
this.fetch({
|
||||
_page: currentPage,
|
||||
_limit: pageSize
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handleSearch = e => {
|
||||
const { currentPage, pageSize, filteredInfo, sortedInfo } = this.state;
|
||||
console.log("====================================");
|
||||
console.log(e);
|
||||
console.log("====================================");
|
||||
// this.setState({
|
||||
// searchValue: e
|
||||
// });
|
||||
if (e) {
|
||||
this.handleUpdateData({ search: e, page: 1 });
|
||||
} else {
|
||||
this.handleUpdateData({ search: null, page: 1 });
|
||||
}
|
||||
};
|
||||
|
||||
handleSearchChange = e => {
|
||||
const { currentPage, pageSize, filteredInfo, sortedInfo } = this.state;
|
||||
|
||||
// this.setState({
|
||||
// searchValue: e
|
||||
// });
|
||||
if (e) {
|
||||
this.setState({
|
||||
searchValue: e.target.value
|
||||
})
|
||||
} else {
|
||||
this.setState({
|
||||
searchValue: null
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
handleDeleteConfirmYes = e => {
|
||||
console.log(e);
|
||||
message.success("Click on Yes");
|
||||
};
|
||||
|
||||
handleDeleteConfirmNo = e => {
|
||||
console.log(e);
|
||||
message.error("Click on No");
|
||||
};
|
||||
handleclearAll = () => {
|
||||
console.log("====================================");
|
||||
console.log("reset");
|
||||
console.log("====================================");
|
||||
this.setState({
|
||||
filteredInfo: null,
|
||||
sortedInfo: null,
|
||||
searchValue: null,
|
||||
// currentPage: 1,
|
||||
// pageSize: 10
|
||||
});
|
||||
|
||||
this.handleUpdateData({
|
||||
page: 1,
|
||||
size: 10,
|
||||
});
|
||||
// this.fetch({
|
||||
// _page: 1,
|
||||
// _limit: 10
|
||||
// });
|
||||
};
|
||||
handlePagination = page => {
|
||||
const { pageSize, searchValue } = this.state;
|
||||
|
||||
// this.fetch({
|
||||
// _page: page,
|
||||
// _limit: pageSize
|
||||
// });
|
||||
|
||||
if (searchValue) {
|
||||
this.handleUpdateData({ page, search: searchValue });
|
||||
} else {
|
||||
this.handleUpdateData({ page });
|
||||
}
|
||||
|
||||
// this.setState({
|
||||
// currentPage: page
|
||||
// });
|
||||
};
|
||||
|
||||
handleSizeChange = (current, pageSize) => {
|
||||
console.log("TEST!", current, pageSize, searchValue);
|
||||
const { searchValue } = this.state;
|
||||
// this.fetch({
|
||||
// _page: current,
|
||||
// _limit: pageSize
|
||||
// });
|
||||
|
||||
if (searchValue) {
|
||||
this.handleUpdateData({
|
||||
page: current,
|
||||
size: pageSize,
|
||||
search: searchValue
|
||||
});
|
||||
} else {
|
||||
this.handleUpdateData({ page: current, size: pageSize });
|
||||
}
|
||||
|
||||
// this.setState({
|
||||
// currentPage: current,
|
||||
// pageSize
|
||||
// });
|
||||
};
|
||||
|
||||
|
||||
handleRenderActionButton = ({action, item}) => {
|
||||
let {keyValue} = this.props
|
||||
|
||||
let idValue = item[keyValue].toString()
|
||||
console.log('====================================');
|
||||
|
||||
console.log('====================================');
|
||||
switch (action.type) {
|
||||
case 'edit':
|
||||
return <Tooltip key={action.key} placement="top" title={action.name}>
|
||||
<Link to={`${action.path}/1`} style={{padding: '5px 8px'}}>
|
||||
<Icon type='edit' />
|
||||
</Link>
|
||||
</Tooltip>
|
||||
|
||||
break;
|
||||
case 'view':
|
||||
return <Tooltip key={action.key} placement="top" title={action.name}>
|
||||
<Link to={`${action.path}/2`} style={{padding: '5px 8px'}}>
|
||||
<Icon type='right-circle-o' />
|
||||
</Link>
|
||||
</Tooltip>
|
||||
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
return <Tooltip key={action.key} placement="top" title={action.name}>
|
||||
<Popconfirm
|
||||
title="Are you sure delete this item?"
|
||||
onConfirm={() => this.handleDeleteConfirmYes(item)}
|
||||
onCancel={() => this.handleDeleteConfirmNo(item)}
|
||||
okText="Yes"
|
||||
cancelText="No" >
|
||||
<a href="javascript:;" style={{padding: '5px 8px'}}>
|
||||
<Icon type='delete' />
|
||||
</a>
|
||||
</Popconfirm>
|
||||
</Tooltip>
|
||||
break;
|
||||
|
||||
default:
|
||||
return null
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
let { columns, keyValue, actions } = this.props;
|
||||
let {
|
||||
sortedInfo,
|
||||
filteredInfo,
|
||||
headerColumns,
|
||||
currentPage,
|
||||
pageSize,
|
||||
totalData,
|
||||
data,
|
||||
searchValue
|
||||
} = this.state;
|
||||
|
||||
// let headerColumns = columns.map(column => {
|
||||
// if (column.sorter) {
|
||||
// column.sorter = (a, b) => a[column.dataIndex] - b[column.dataIndex];
|
||||
// column.sortOrder =
|
||||
// sortedInfo &&
|
||||
// sortedInfo.columnKey === column.dataIndex &&
|
||||
// sortedInfo.order;
|
||||
// }
|
||||
// return column;
|
||||
// });
|
||||
|
||||
console.log("====================================");
|
||||
console.log(currentPage, pageSize, "TESTASDASD");
|
||||
console.log("====================================");
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="table-operations">
|
||||
<Button onClick={this.handleclearAll}>
|
||||
Clear filters
|
||||
</Button>
|
||||
</div>
|
||||
<Search
|
||||
value={searchValue}
|
||||
placeholder="input search text"
|
||||
onSearch={this.handleSearch}
|
||||
onChange={this.handleSearchChange}
|
||||
enterButton
|
||||
/>
|
||||
<Table
|
||||
rowKey={keyValue}
|
||||
dataSource={data}
|
||||
loading={this.state.loading}
|
||||
onChange={this.handleTableChange}
|
||||
pagination={false}
|
||||
>
|
||||
{columns &&
|
||||
columns.map(column => (
|
||||
<Column
|
||||
key={column.dataIndex ? column.dataIndex : column.key}
|
||||
{...column}
|
||||
/>
|
||||
))}
|
||||
{
|
||||
actions && actions.length > 0 && <Column
|
||||
title="Action"
|
||||
align="center"
|
||||
key="action"
|
||||
width={130}
|
||||
render={(text, record) => (
|
||||
|
||||
actions.map(item => {
|
||||
return item.access === true && this.handleRenderActionButton({action: item, item: record})
|
||||
})
|
||||
|
||||
)}
|
||||
|
||||
|
||||
/>
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
</Table>
|
||||
<Row style={{paddingTop: 20}}>
|
||||
<Col span={8}>col-12</Col>
|
||||
<Col span={16} style={{textAlign: 'right'}}>
|
||||
<Pagination
|
||||
// size="small"
|
||||
current={currentPage}
|
||||
pageSize={pageSize}
|
||||
showSizeChanger
|
||||
onChange={this.handlePagination}
|
||||
onShowSizeChange={this.handleSizeChange}
|
||||
// defaultCurrent={currentPage}
|
||||
total={totalData}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(CustomTable);
|
|
@ -1,90 +0,0 @@
|
|||
import React, { Component } from "react";
|
||||
import { Icon, Avatar, Dropdown, Menu, notification } from "antd";
|
||||
import { Link, withRouter } from "react-router-dom";
|
||||
import Helmet from 'react-helmet';
|
||||
|
||||
import { connect } from "react-redux";
|
||||
import { customAction } from 'actions'
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { API_UNI_OIL , API_POST } from 'utils/Api'
|
||||
|
||||
const HeaderButton = styled.a`
|
||||
/* This renders the buttons above... Edit me! */
|
||||
padding: 0 10px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
|
||||
|
||||
cursor: pointer;
|
||||
-webkit-transition: all .3s,padding 0s;
|
||||
transition: all .3s,padding 0s;
|
||||
|
||||
&:hover {
|
||||
background-color: rgb(243, 243, 243);
|
||||
color: #fff
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
class HeaderDropdown extends Component {
|
||||
state = {
|
||||
}
|
||||
|
||||
|
||||
handleLogout = () => {
|
||||
this.props.customAction({type: 'LOGOUT'});
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
//const { userInfo } = this.state
|
||||
const { history, userInfo } = this.props;
|
||||
|
||||
const menu = (
|
||||
<Menu style={{width: 150 , margin: '0 0 0 auto'}} >
|
||||
<Menu.Item key="0">
|
||||
<a
|
||||
onClick={()=> history.push("/my-profile")}
|
||||
role="button"
|
||||
rel="noopener noreferrer" >
|
||||
<Icon type="user" /> My Profile
|
||||
</a>
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item key="1">
|
||||
<a
|
||||
role="button"
|
||||
onClick={this.handleLogout}>
|
||||
<Icon type="logout" /> Logout
|
||||
</a>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
<Helmet title = "Dashboard" />
|
||||
<Dropdown overlay={menu} placement="bottomRight">
|
||||
<HeaderButton role="button" style={{
|
||||
marginRight: 16, color: '#8E8E93', maxWidth: '256px',
|
||||
whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' , position: 'relative'
|
||||
}} >
|
||||
<Avatar size="small"
|
||||
style={{ background: '#B8BBC9', marginRight: 5 }} icon="user"
|
||||
/> { userInfo && (`${userInfo.firstname} ${userInfo.lastname}`) } <Icon type="down" />
|
||||
</HeaderButton>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
HeaderDropdown = connect(
|
||||
state => ({
|
||||
//fetchData: state.fetchData
|
||||
// put initial values from account reducer
|
||||
}),
|
||||
{ customAction }
|
||||
)(HeaderDropdown)
|
||||
|
||||
export default withRouter(HeaderDropdown);
|
|
@ -1,75 +0,0 @@
|
|||
import React from "react";
|
||||
import { Breadcrumb, Icon } from 'antd';
|
||||
|
||||
// import styled from 'styled-components';
|
||||
import { Link, withRouter } from 'react-router-dom';
|
||||
|
||||
|
||||
function MainBreadcrumbs(props) {
|
||||
const {
|
||||
pageRoutes,
|
||||
// match,
|
||||
location,
|
||||
root
|
||||
} = props;
|
||||
|
||||
const pathSnippets = location.pathname.split('/').filter(i => i);
|
||||
const extraBreadcrumbItems = pathSnippets.map((route, index) => {
|
||||
const url = `/${pathSnippets.slice(0, index + 1).join('/')}`;
|
||||
const routeCompare = pageRoutes.find((myRoute) => myRoute.path === url)
|
||||
const paramsId = pathSnippets[pathSnippets.length - 1]
|
||||
|
||||
if (routeCompare) {
|
||||
if (routeCompare.params) {
|
||||
return (
|
||||
<Breadcrumb.Item key={index}>
|
||||
<Link to={`${url}/${paramsId}`}>
|
||||
{routeCompare.name}
|
||||
</Link>
|
||||
</Breadcrumb.Item>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Breadcrumb.Item key={index}>
|
||||
<Link to={url}>
|
||||
{routeCompare.name}
|
||||
</Link>
|
||||
</Breadcrumb.Item>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// return <Breadcrumb.Item key={index}></Breadcrumb.Item>;
|
||||
})
|
||||
if (root) {
|
||||
return (
|
||||
<Breadcrumb
|
||||
separator={<Icon type="right" style={{fontSize: '10px', opacity: 0.6}} />}
|
||||
routeComparestyle={{ padding: '11px 24px 9px', fontSize: '12px' }}
|
||||
>
|
||||
<Breadcrumb.Item>
|
||||
<Link to='/my-profile'>
|
||||
<Icon type="home" /> {` Home`}
|
||||
</Link>
|
||||
</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Breadcrumb
|
||||
separator={<Icon type="right" style={{fontSize: '10px', opacity: 0.6}} />}
|
||||
style={{ padding: '11px 24px 9px', fontSize: '12px' }}
|
||||
>
|
||||
<Breadcrumb.Item>
|
||||
<Link to='/my-profile'>
|
||||
<Icon type="home" /> {` Home`}
|
||||
</Link>
|
||||
</Breadcrumb.Item>
|
||||
{extraBreadcrumbItems}
|
||||
</Breadcrumb>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default withRouter(MainBreadcrumbs);
|
|
@ -1,36 +0,0 @@
|
|||
import React from "react";
|
||||
import { Layout } from 'antd';
|
||||
import { withRouter } from 'react-router-dom'
|
||||
|
||||
import MainBreadcrumbs from './MainBreadcrumbs'
|
||||
const { Content } = Layout;
|
||||
|
||||
function MainContent(props) {
|
||||
const {
|
||||
children,
|
||||
pageRoutes,
|
||||
root
|
||||
} = props;
|
||||
|
||||
return (
|
||||
[
|
||||
props.location && props.location.key && (
|
||||
<div key={1} style={{
|
||||
background: '#fff' ,
|
||||
marginBottom: '75px',
|
||||
position: 'fixed',
|
||||
marginTop: '-110px',
|
||||
width: '100%'}}
|
||||
>
|
||||
<MainBreadcrumbs root={root} pageRoutes={pageRoutes} />
|
||||
</div>
|
||||
)
|
||||
,
|
||||
<Content key={2} style={{ margin: '0 16px', padding: '0', background: '#fff', }}>
|
||||
{children}
|
||||
</Content>,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
export default withRouter(MainContent);
|
|
@ -1,19 +0,0 @@
|
|||
import React from "react";
|
||||
import { Layout } from "antd";
|
||||
|
||||
// import styled from 'styled-components';
|
||||
// import { Link } from 'react-router-dom';
|
||||
|
||||
const { Footer } = Layout;
|
||||
|
||||
function MainFooter(props) {
|
||||
// const {} = props;
|
||||
|
||||
return (
|
||||
<Footer style={{ textAlign: "center", background: '#fcfcfc' }} >
|
||||
{/* YONDU-SDG ©2018 Created by Front End Team! */}
|
||||
</Footer>
|
||||
);
|
||||
}
|
||||
|
||||
export default MainFooter;
|
|
@ -1,83 +0,0 @@
|
|||
import React from "react";
|
||||
import { Layout, Icon } from "antd";
|
||||
import { connect } from "react-redux";
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
import HeaderDropdown from './HeaderDropdown';
|
||||
|
||||
const { Header } = Layout;
|
||||
|
||||
|
||||
const HeaderLink = styled(Link)`
|
||||
/* This renders the buttons above... Edit me! */
|
||||
padding: 0 10px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
|
||||
|
||||
cursor: pointer;
|
||||
-webkit-transition: all .3s,padding 0s;
|
||||
transition: all .3s,padding 0s;
|
||||
|
||||
&:hover {
|
||||
background-color: #1890ff;
|
||||
color: #fff
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
|
||||
|
||||
const RightHeader = styled.div`
|
||||
/* This renders the buttons above... Edit me! */
|
||||
float: right;
|
||||
|
||||
|
||||
`
|
||||
|
||||
const IconTrigger = styled(Icon)`
|
||||
/* This renders the buttons above... Edit me! */
|
||||
font-size: 20px;
|
||||
line-height: 69px;
|
||||
cursor: pointer;
|
||||
-webkit-transition: all .3s,padding 0s;
|
||||
transition: all .3s,padding 0s;
|
||||
padding: 0 24px;
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
}
|
||||
`
|
||||
|
||||
function MainHeader(props) {
|
||||
const {
|
||||
collapsed,
|
||||
toggle,
|
||||
userInfo,
|
||||
} = props
|
||||
|
||||
return (
|
||||
<Header style={{ background: '#fff', padding: 0, height: '66px', lineHeight: '69px', borderBottom: '1px solid rgb(230, 236, 245)', }}>
|
||||
<IconTrigger
|
||||
className="trigger"
|
||||
type={collapsed ? 'menu-unfold' : 'menu-fold'}
|
||||
onClick={toggle}
|
||||
/>
|
||||
<RightHeader>
|
||||
<HeaderDropdown userInfo={userInfo}/>
|
||||
</RightHeader>
|
||||
</Header>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
MainHeader = connect(
|
||||
state => ({
|
||||
|
||||
// pull initial values from account reducer
|
||||
}),
|
||||
// { customAction }
|
||||
)(MainHeader);
|
||||
|
||||
export default MainHeader;
|
|
@ -1,262 +0,0 @@
|
|||
import React from 'react';
|
||||
import { Layout, Icon, Menu } from 'antd';
|
||||
import styled from 'styled-components';
|
||||
import { withRouter, Link } from 'react-router-dom';
|
||||
|
||||
const { SubMenu } = Menu;
|
||||
const { Sider } = Layout;
|
||||
|
||||
const LogoPlaceholder = styled.div`
|
||||
height: 32px;
|
||||
margin: 16px;
|
||||
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
`;
|
||||
|
||||
function MainSidebar(props) {
|
||||
const { collapsed, match, location, userInfo, systemPreferences } = props;
|
||||
|
||||
const navigation = [
|
||||
{
|
||||
key: 0,
|
||||
label: 'User Management',
|
||||
path: '/user-management',
|
||||
icon: 'team',
|
||||
access: userInfo && userInfo.role == 1 ? true : false,
|
||||
//access: userInfo && (userInfo.role == 1 || userInfo.role == 3) ? true : false,
|
||||
},
|
||||
{
|
||||
key: 9,
|
||||
label: 'Notifications',
|
||||
path: '/notifications',
|
||||
icon: 'notification',
|
||||
access: true,
|
||||
//access: userInfo && (userInfo.role == 1 || userInfo.role == 3) ? true : false,
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
label: 'Member Management',
|
||||
path: '/member-management',
|
||||
icon: 'credit-card',
|
||||
access: userInfo && userInfo.role == 1 ? true : false,
|
||||
child: [
|
||||
{
|
||||
key: 0.0,
|
||||
label: 'Card Member',
|
||||
path: '/member-management/card-member',
|
||||
access: true,
|
||||
},
|
||||
{
|
||||
key: 0.1,
|
||||
label: 'Locked Accounts',
|
||||
path: '/member-management/lock-account',
|
||||
access: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 8,
|
||||
label: 'Home Page ( Mobile ) ',
|
||||
path: '/home-page',
|
||||
icon: 'home',
|
||||
access: true,
|
||||
child: [
|
||||
{
|
||||
key: 0.0,
|
||||
label: 'Photo Slider',
|
||||
path: '/home-page/photo-slider',
|
||||
access: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
label: 'Promotions',
|
||||
path: '/promotions',
|
||||
icon: 'tags',
|
||||
access: true,
|
||||
},
|
||||
|
||||
{
|
||||
key: 2,
|
||||
label: 'Top-Up',
|
||||
path: '/top-up',
|
||||
icon: 'plus-circle',
|
||||
access: userInfo && userInfo.role == 1 ? true : false,
|
||||
},
|
||||
{
|
||||
key: 6,
|
||||
label: 'About Us',
|
||||
path: '/about-us',
|
||||
icon: 'info-circle',
|
||||
access: userInfo && userInfo.role == 1 ? true : false,
|
||||
child: [
|
||||
{
|
||||
key: 0.6,
|
||||
label: 'Card Types',
|
||||
path: '/about-us/card-types',
|
||||
access: true,
|
||||
},
|
||||
{
|
||||
key: 0.5,
|
||||
label: 'Terms & Privacy',
|
||||
path: '/about-us/term-privacy',
|
||||
access: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 7,
|
||||
label: 'Reports',
|
||||
path: '/reports',
|
||||
icon: 'file-text',
|
||||
access: true,
|
||||
child: [
|
||||
{
|
||||
key: 0.7,
|
||||
label: 'Registration Report',
|
||||
path: '/reports/registration-report',
|
||||
access: true,
|
||||
},
|
||||
{
|
||||
key: 0.8,
|
||||
label: 'Top-Up Usage Report',
|
||||
path: '/reports/top-up',
|
||||
access: true,
|
||||
},
|
||||
{
|
||||
key: 0.9,
|
||||
label: 'Mobile Usage Report',
|
||||
path: '/reports/mobile-report',
|
||||
access: true,
|
||||
},
|
||||
{
|
||||
key: 0.1,
|
||||
label: 'Station Rating Report',
|
||||
path: '/reports/station-rating',
|
||||
access: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 8,
|
||||
label: 'System Parameters',
|
||||
path: '/system-parameters',
|
||||
icon: 'setting',
|
||||
access: userInfo && userInfo.role == 1 ? true : false,
|
||||
},
|
||||
{
|
||||
key: 12,
|
||||
label: 'Station Locator',
|
||||
path:'',
|
||||
icon:'environment',
|
||||
access: true,
|
||||
child: [
|
||||
{
|
||||
key: 0.11,
|
||||
label: 'Branches',
|
||||
path:'/branches',
|
||||
access: true
|
||||
},
|
||||
{
|
||||
key: 0.12,
|
||||
label: 'Stations',
|
||||
path:'/stations',
|
||||
access: true
|
||||
},
|
||||
{
|
||||
key: 0.13,
|
||||
label: 'Fuels',
|
||||
path:'/fuels',
|
||||
access: true
|
||||
}
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
let newURL = location.pathname.split('/');
|
||||
let appendedUrl = newURL[2];
|
||||
if (appendedUrl == 'create' || appendedUrl == 'view' || appendedUrl == 'edit') appendedUrl = null;
|
||||
let isSeondDaryPathExist = appendedUrl ? `/${appendedUrl}` : '';
|
||||
let secondaryURL = `${match.path}${isSeondDaryPathExist}`;
|
||||
|
||||
return (
|
||||
<Sider
|
||||
trigger={null}
|
||||
collapsible
|
||||
width={295}
|
||||
collapsed={collapsed}
|
||||
style={{ background: '#fff', border: 'solid 1px #e6ecf5', zIndex: '999' }}
|
||||
>
|
||||
{!collapsed ? (
|
||||
<div style={{ height: '65px', padding: '12px 0', textAlign: 'center', borderBottom: '1px solid #e6ecf5' }}>
|
||||
{/* <img src={ require("assets/img/logo_unioil.png") } style={{ height: 40 }} /> */}
|
||||
{userInfo && (
|
||||
<img src={`${systemPreferences ? systemPreferences : userInfo.logo}`} style={{ height: '100%' }} />
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<LogoPlaceholder
|
||||
className='logo'
|
||||
style={{ backgroundImage: `url(${systemPreferences ? systemPreferences : userInfo.logo})` }}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Menu
|
||||
style={{ borderRight: !collapsed ? 0 : null, height: '90vh', overflow: 'auto', paddingTop: '17px' }}
|
||||
//inlineIndent={10}
|
||||
defaultOpenKeys={[ match.path ]}
|
||||
selectedKeys={[ secondaryURL ]}
|
||||
mode='inline'
|
||||
>
|
||||
{navigation.map((item) => {
|
||||
if (item.access) {
|
||||
if (item.child) {
|
||||
return (
|
||||
<SubMenu
|
||||
key={item.path}
|
||||
title={
|
||||
<span>
|
||||
<Icon type={item.icon} />
|
||||
<span>{item.label}</span>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
{item.child.map((subItem) => {
|
||||
if (subItem.access) {
|
||||
return (
|
||||
<Menu.Item key={subItem.path}>
|
||||
<Link to={subItem.path} style={{ paddingLeft: '15px' }}>
|
||||
{subItem.icon && <Icon type={subItem.icon} />}
|
||||
{subItem.label}
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
</SubMenu>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Menu.Item key={item.path}>
|
||||
<Link to={item.path}>
|
||||
{item.icon && <Icon type={item.icon} />}
|
||||
<span>{item.label}</span>
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
})}
|
||||
</Menu>
|
||||
</Sider>
|
||||
);
|
||||
}
|
||||
|
||||
export default withRouter(MainSidebar);
|
|
@ -1,107 +0,0 @@
|
|||
|
||||
import React from 'react'
|
||||
import { Layout } from 'antd';
|
||||
import { notification } from "antd";
|
||||
import { connect } from 'react-redux';
|
||||
import IdleTimer from 'react-idle-timer'
|
||||
|
||||
import MainFooter from './components/MainFooter'
|
||||
import MainHeader from './components/MainHeader'
|
||||
import MainSidebar from './components/MainSidebar'
|
||||
|
||||
import { API_UNI_OIL , API_POST } from 'utils/Api'
|
||||
import { customAction } from 'actions'
|
||||
|
||||
class DashboardLayout extends React.Component {
|
||||
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.idleTimer = null
|
||||
this.onActive = this.handleActive.bind(this)
|
||||
this.onIdle = this.handleIdle.bind(this)
|
||||
|
||||
this.state = {
|
||||
collapsed: false,
|
||||
userInfo: null,
|
||||
updatedLogo: null
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nexProps, prevProps) {
|
||||
if(nexProps && nexProps.systemPreferences) {
|
||||
if(nexProps.systemPreferences.data && nexProps.systemPreferences.data) {
|
||||
this.setState({
|
||||
updatedLogo: nexProps.systemPreferences.data.logo
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(nexProps) {
|
||||
|
||||
}
|
||||
|
||||
handleActive(e) {
|
||||
// console.log('user is active', e)
|
||||
}
|
||||
|
||||
handleIdle(e) {
|
||||
// console.log('user is idle', e)
|
||||
notification.error({
|
||||
message: "Error",
|
||||
description: <div>You are logout automatically for being idle more than 10 minutes.</div>,
|
||||
duration: 0,
|
||||
key: 'idle-notification-1'
|
||||
});
|
||||
this.props.customAction({type: 'LOGOUT'});
|
||||
}
|
||||
|
||||
toggle = () => {
|
||||
this.setState({
|
||||
collapsed: !this.state.collapsed,
|
||||
});
|
||||
}
|
||||
render() {
|
||||
|
||||
//const { userInfo } = this.state
|
||||
const { children, userInfo } = this.props
|
||||
|
||||
return (
|
||||
<Layout style={{ height: '100%' }}>
|
||||
<MainSidebar collapsed={this.state.collapsed} userInfo={userInfo.data.userInfo} systemPreferences={this.state.updatedLogo}/>
|
||||
<Layout style={{background: '#fcfcfc', paddingBottom: '10px'}}>
|
||||
<MainHeader
|
||||
collapsed={this.state.collapsed}
|
||||
toggle={this.toggle}
|
||||
userInfo={userInfo.data.userInfo}
|
||||
/>
|
||||
<div style={{ overflow: 'auto', marginTop: '94px', paddingTop: '16px', position: 'relative' }}>
|
||||
<IdleTimer
|
||||
ref={ref => { this.idleTimer = ref }}
|
||||
element={document}
|
||||
onActive={this.onActive}
|
||||
onIdle={this.onIdle}
|
||||
timeout={600000}
|
||||
>
|
||||
{children}
|
||||
</IdleTimer>
|
||||
</div>
|
||||
</Layout>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
DashboardLayout = connect(
|
||||
state => ({
|
||||
// pull initial values from account reducer
|
||||
userInfo: state.login,
|
||||
systemPreferences: state.systemPreferences
|
||||
}),
|
||||
{ customAction }
|
||||
)(DashboardLayout);
|
||||
|
||||
export default DashboardLayout
|
|
@ -1,31 +0,0 @@
|
|||
import React from 'react';
|
||||
import DashboardLayout from '../Layout'
|
||||
import { Route, Redirect } from 'react-router-dom'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
|
||||
function DashboardRoute({ component: Component, isAuthenticated, ...rest }) {
|
||||
return (
|
||||
<Route {...rest} render={props => isAuthenticated ? (
|
||||
<DashboardLayout>
|
||||
<Component {...props} />
|
||||
</DashboardLayout>
|
||||
) : <Redirect
|
||||
to={{
|
||||
pathname: "/login",
|
||||
state: { from: props.location, message: "You must log in to Enter this page" }
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
export default DashboardRoute = connect(
|
||||
state => ({
|
||||
isAuthenticated: state.auth.isAuthenticated
|
||||
}),
|
||||
)(DashboardRoute);
|
||||
|
||||
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
import React, { Component, Fragment } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { List, Avatar } from 'antd';
|
||||
|
||||
import { fetchData } from 'utils/Api';
|
||||
|
||||
class ListDataDisplay extends Component {
|
||||
state = {
|
||||
data: []
|
||||
};
|
||||
|
||||
async componentDidMount() {
|
||||
// const { url } = this.props;
|
||||
// const response = await fetchData(url);
|
||||
// this.setState({
|
||||
// data: response.data
|
||||
// })
|
||||
}
|
||||
|
||||
render() {
|
||||
const { layout, avatar, viewPath, header, footer } = this.props;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<List
|
||||
header={header}
|
||||
footer={footer}
|
||||
itemLayout={layout}
|
||||
dataSource={this.state && this.state.data.data}
|
||||
renderItem={item => (
|
||||
<List.Item>
|
||||
<List.Item.Meta
|
||||
avatar={avatar && <Avatar
|
||||
src={item.avatar}
|
||||
/>}
|
||||
title={<Link to={viewPath.replace(':id', item.id)}>{item.first_name}</Link>}
|
||||
description={`${item.first_name.toLowerCase()}_${item.last_name.toLowerCase()}@gmail.com`}
|
||||
/>
|
||||
</List.Item>
|
||||
)}
|
||||
/>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default ListDataDisplay;
|
|
@ -1,5 +0,0 @@
|
|||
import List from './List';
|
||||
|
||||
export {
|
||||
List,
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
import React, { PureComponent } from "react";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import { Menu, Dropdown, Button, notification } from "antd";
|
||||
import DownloadFile from "js-file-download";
|
||||
import queryString from "query-string";
|
||||
import moment from 'moment';
|
||||
|
||||
import { API_UNI_OIL } from "utils/Api";
|
||||
|
||||
class DropdownExport extends PureComponent {
|
||||
state = {
|
||||
loading: false
|
||||
}
|
||||
|
||||
handleExportCSV = async() => {
|
||||
this.setState({ loading: true });
|
||||
|
||||
let { location } = this.props;
|
||||
let { search } = location;
|
||||
let params = queryString.parse(search);
|
||||
|
||||
if(this.props.defaultFilter){
|
||||
params = {
|
||||
...params,
|
||||
...this.props.defaultFilter
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
let response = await API_UNI_OIL.get(this.props.url.path, {
|
||||
params,
|
||||
responseType: 'blob'
|
||||
});
|
||||
|
||||
if (response.status === 200 || response.status === 201) {
|
||||
//let dateNow = moment(new Date()).format('DD-MMM-YYYY')
|
||||
let dateNow = moment(new Date()).format('MMDDYYYY')
|
||||
DownloadFile(response.data, `${this.props.url.fileName}_${dateNow}.csv`);
|
||||
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const { loading } = this.state;
|
||||
|
||||
return(
|
||||
<Button
|
||||
loading={loading}
|
||||
onClick={this.handleExportCSV}
|
||||
style={{background: 'rgb(231, 70, 16)', borderColor: 'rgb(231, 70, 16)', color: '#fff'}}
|
||||
>
|
||||
Export CSV
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(DropdownExport);
|
|
@ -1 +0,0 @@
|
|||
export { default as DropdownExport } from "./DropdownExport";
|
|
@ -1,69 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
//import { Field, reduxForm } from 'redux-form';
|
||||
import { Form, Row, Col, Button, Icon, Input,Select } from 'antd';
|
||||
|
||||
import { required } from 'constants/validation';
|
||||
import {AInput,ASelect,ARangePicker} from './AntdForms'
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const { Option } = Select;
|
||||
|
||||
class AdvancedSearchForm extends Component {
|
||||
render() {
|
||||
|
||||
const { handleSubmit,onSubmit, reset } = this.props;
|
||||
|
||||
return (
|
||||
<Form
|
||||
onSubmit={onSubmit}
|
||||
className="login-form"
|
||||
>
|
||||
<Row gutter={24}>
|
||||
<Col span={8}>
|
||||
{/* <Field
|
||||
name="filter_field"
|
||||
label="Filter by Code"
|
||||
component={ASelect}
|
||||
validate={required}
|
||||
defaultValue="1"
|
||||
>
|
||||
<Option value="ff0000">Red</Option>
|
||||
<Option value="00ff00">Green</Option>
|
||||
<Option value="0000ff">Blue</Option>
|
||||
</Field> */}
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
{/* <Field
|
||||
name="filter_value"
|
||||
label="Filter by Name"
|
||||
component={ARangePicker}
|
||||
width={4}
|
||||
placeholder={["From", "To"]}
|
||||
hasFeedback
|
||||
onFocus={e => e.preventDefault()}
|
||||
onBlur={e => e.preventDefault()}
|
||||
// validate={required}
|
||||
/> */}
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<Col span={24} style={{ textAlign: 'right' }}>
|
||||
<Button type="primary" htmlType="submit">Search</Button>
|
||||
<Button style={{ marginLeft: 8 }} onClick={reset}>
|
||||
Clear
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// AdvancedSearchForm = reduxForm({
|
||||
// form: "CreateEmployeeFieldsForm",
|
||||
// })(AdvancedSearchForm);
|
||||
|
||||
export default AdvancedSearchForm;
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
import React from "react";
|
||||
import { Form, Input, Radio, Select, Checkbox, Button, DatePicker } from "antd";
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const RadioGroup = Radio.Group;
|
||||
const { Option } = Select;
|
||||
const { TextArea } = Input;
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
const formItemLayout = {
|
||||
// labelCol: {
|
||||
// xs: { span: 24 },
|
||||
// sm: { span: 7 }
|
||||
// },
|
||||
// wrapperCol: {
|
||||
// xs: { span: 24 },
|
||||
// sm: { span: 14 }
|
||||
// }
|
||||
};
|
||||
|
||||
|
||||
|
||||
const makeField = Component => ({ input, meta, children, hasFeedback, label, ...rest }) => {
|
||||
const hasError = meta.touched && meta.invalid;
|
||||
const inputs = {...input};
|
||||
const rests = {...rest};
|
||||
console.log(inputs,'inputss', rests , 'ressttss')
|
||||
return (
|
||||
<FormItem
|
||||
{...formItemLayout}
|
||||
label={label}
|
||||
validateStatus={hasError ? "error" : "success"}
|
||||
hasFeedback={hasFeedback && hasError}
|
||||
help={hasError && meta.error}
|
||||
>
|
||||
<Component {...input} {...rest} children={children} />
|
||||
</FormItem>
|
||||
);
|
||||
};
|
||||
|
||||
export const AInput = makeField(Input);
|
||||
export const ARadioGroup = makeField(RadioGroup);
|
||||
export const ASelect = makeField(Select);
|
||||
export const ACheckbox = makeField(Checkbox);
|
||||
export const ATextarea = makeField(TextArea);
|
||||
export const ARangePicker = makeField(RangePicker);
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Form, Cascader } from 'antd';
|
||||
import { fetchData } from 'utils/Api';
|
||||
const FormItem = Form.Item;
|
||||
|
||||
const options = [{
|
||||
value: 'zhejiang',
|
||||
label: 'Zhejiang',
|
||||
children: [{
|
||||
value: 'hangzhou',
|
||||
label: 'Hangzhou',
|
||||
children: [{
|
||||
value: 'xihu',
|
||||
label: 'West Lake',
|
||||
}],
|
||||
}],
|
||||
}, {
|
||||
value: 'jiangsu',
|
||||
label: 'Jiangsu',
|
||||
children: [{
|
||||
value: 'nanjing',
|
||||
label: 'Nanjing',
|
||||
children: [{
|
||||
value: 'zhonghuamen',
|
||||
label: 'Zhong Hua Men',
|
||||
}],
|
||||
}],
|
||||
}];
|
||||
|
||||
class CascaderForm extends Component {
|
||||
async componentDidMount() {
|
||||
const { url } = this.props;
|
||||
const response = await fetchData(url);
|
||||
this.setState({
|
||||
options: response.data.data
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
field: { name, /* ...field */ },
|
||||
form: { errors, setFieldValue, /* ...form */ },
|
||||
layout,
|
||||
label,
|
||||
required,
|
||||
...props
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
label={label}
|
||||
validateStatus={errors[name] && 'error'}
|
||||
help={errors[name]}
|
||||
>
|
||||
<Cascader
|
||||
{...props}
|
||||
onChange={this.handleChange = (value) => { setFieldValue(name, value) }}
|
||||
options={options}
|
||||
/>
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CascaderForm;
|
|
@ -1,55 +0,0 @@
|
|||
import React from 'react';
|
||||
import { Checkbox, Form } from 'antd';
|
||||
const FormItem = Form.Item;
|
||||
|
||||
const CheckboxForm = ({
|
||||
field: { name, ...field },
|
||||
form: { touched, errors, handleChange, setFieldValue, ...form },
|
||||
label,
|
||||
inline,
|
||||
layout,
|
||||
required,
|
||||
...props,
|
||||
}) => {
|
||||
|
||||
if (inline) {
|
||||
return (
|
||||
<Checkbox
|
||||
{...props}
|
||||
{...field}
|
||||
name={name}
|
||||
type="checkbox"
|
||||
checked={field.value}
|
||||
onChange={this.handleChange = (value) => { setFieldValue(name, !field.value) }}
|
||||
>
|
||||
{label}
|
||||
</Checkbox>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
style={{marginBottom: '10px',marginLeft: '20.9%'}}
|
||||
validateStatus={touched[name] && errors[name] && 'error'}
|
||||
help={touched[name] && errors[name]}
|
||||
>
|
||||
<Checkbox
|
||||
{...props}
|
||||
{...field}
|
||||
|
||||
name={name}
|
||||
type="checkbox"
|
||||
checked={field.value}
|
||||
onChange={this.handleChange = (value) => { setFieldValue(name, !field.value) }}
|
||||
>
|
||||
{label}
|
||||
</Checkbox>
|
||||
</FormItem>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default CheckboxForm;
|
|
@ -1,160 +0,0 @@
|
|||
import React from 'react';
|
||||
import { Form, DatePicker } from 'antd';
|
||||
import moment from 'moment'
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
const DatePickerForm = ({
|
||||
field: { ...field },
|
||||
form: { touched, errors, handleSubmit, setFieldValue, handlePanelChange, ...form },
|
||||
type,
|
||||
layout,
|
||||
label,
|
||||
format,
|
||||
minDateToday,
|
||||
required,
|
||||
disabledDateStart,
|
||||
dateStartEnd,
|
||||
disabledDateStartEndPhotoSlider,
|
||||
disabledDateStartEndPhotoSliderEndDate,
|
||||
isEdit,
|
||||
isAutoFill,
|
||||
...props
|
||||
}) => {
|
||||
|
||||
const onDateChange = (value, isDateRange = false) => {
|
||||
|
||||
value && setFieldValue(field.name, isDateRange
|
||||
? [value[0].format(format), value[1].format(format)]
|
||||
: value.format(format)
|
||||
)
|
||||
|
||||
|
||||
if(value == null) {
|
||||
setFieldValue(field.name, isDateRange
|
||||
? [value[0].format(format), value[1].format(format)]
|
||||
: null
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Disable date less than `Today`
|
||||
// use minDateToday props
|
||||
// const disabledDate = (current) => {
|
||||
// if (minDateToday) {
|
||||
// var oneDay = (1 * 24 * 60 * 60 * 1000);
|
||||
// return current && (current.valueOf() < (Date.now() - oneDay));
|
||||
// }
|
||||
// }
|
||||
|
||||
const disabledDate = (current) => {
|
||||
// Can not select days before today and today
|
||||
|
||||
// for promotions
|
||||
if(disabledDateStart && !disabledDateStartEndPhotoSlider) {
|
||||
if(form.values.date_start) {
|
||||
return current && current < moment(form.values.date_start);
|
||||
} else {
|
||||
//return current && moment(current).add(2,'days') < moment().endOf('day').add(2,'days');
|
||||
}
|
||||
}
|
||||
// for photo slider Date Start
|
||||
if(disabledDateStartEndPhotoSlider && !disabledDateStartEndPhotoSliderEndDate) {
|
||||
if(dateStartEnd) {
|
||||
if(current && current.format() < moment(dateStartEnd.date_start).format()) {
|
||||
if(isEdit) {
|
||||
//return current && current.format() < moment(dateStartEnd.date_start).subtract(1,'days').format()
|
||||
}
|
||||
return current && current.format() < moment(dateStartEnd.date_start).format()
|
||||
} else {
|
||||
if(isEdit) {
|
||||
return current && current.format() > moment(dateStartEnd.date_end).format();
|
||||
}
|
||||
//return current && current.format() > moment(dateStartEnd.date_end).add(1,'days').format();
|
||||
return current && current.format() > moment(dateStartEnd.date_end).format();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for photo slider date End
|
||||
if(disabledDateStartEndPhotoSliderEndDate) {
|
||||
if(dateStartEnd) {
|
||||
if(current && current.format() < form.values.date_start) {
|
||||
// disabled previous date
|
||||
return current && current < moment(form.values.date_start);
|
||||
} else {
|
||||
// diabled past date
|
||||
if(isEdit) {
|
||||
return current && current.format() > moment(dateStartEnd.date_end).format();
|
||||
}
|
||||
//return current && current.format() > moment(dateStartEnd.date_end).add(1,'days').format();
|
||||
return current && current.format() > moment(dateStartEnd.date_end).format();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(disabledDateStart) {
|
||||
if(dateStartEnd) {
|
||||
// return
|
||||
} else {
|
||||
if(form.values.date_start) {
|
||||
return current && current < moment(form.values.date_start);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let _props = {...props}; let _field = {...field};
|
||||
|
||||
|
||||
if(_field.value !== "") {
|
||||
_props.value = _field.value && moment(_field.value,format)
|
||||
}
|
||||
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
label={label}
|
||||
style={{marginBottom: '10px'}}
|
||||
validateStatus={touched[field.name] && errors[field.name] && 'error'}
|
||||
help={touched[field.name] && errors[field.name]}
|
||||
>
|
||||
{ type === 'date' &&
|
||||
<DatePicker
|
||||
{..._props}
|
||||
onChange={(value) => onDateChange(value)}
|
||||
format={format}
|
||||
disabledDate={disabledDateStartEndPhotoSlider || disabledDateStart ? disabledDate : ()=> { return false } }
|
||||
style={{width: '250px'}}
|
||||
/>
|
||||
}
|
||||
|
||||
{ type === 'date-time' &&
|
||||
<DatePicker
|
||||
showTime={true}
|
||||
{..._props}
|
||||
onChange={(value) => onDateChange(value)}
|
||||
format={format}
|
||||
style={{width: '250px'}}
|
||||
/>
|
||||
}
|
||||
|
||||
{ type === 'range' &&
|
||||
<RangePicker
|
||||
{...props}
|
||||
onChange={(value) => onDateChange(value, true)}
|
||||
format={format}
|
||||
disabledDate={disabledDate}
|
||||
/>
|
||||
}
|
||||
</FormItem>
|
||||
);
|
||||
};
|
||||
|
||||
export default DatePickerForm;
|
|
@ -1,145 +0,0 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
import { Button,Popconfirm, Icon, Dropdown, Menu } from 'antd';
|
||||
|
||||
|
||||
class HeaderForm extends Component {
|
||||
|
||||
|
||||
confirm(action) {
|
||||
action();
|
||||
// message.success('Click on Yes');
|
||||
}
|
||||
|
||||
cancel(e) {
|
||||
// console.log(e);
|
||||
// message.error('Click on No');
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
const { action, cancel, deleteAction , title , actionBtnName, cancelBtnName,
|
||||
deleteBtnName, loading, withConfirm, styleBtn, isDropDown , actionPrivacy,
|
||||
actionTerms, disabled, withCancelConfirm, isInsideForm } = this.props;
|
||||
|
||||
const menu = (
|
||||
<Menu className="terms-management"
|
||||
//onClick={handleMenuClick}
|
||||
>
|
||||
<Menu.Item key="1" onClick={actionPrivacy}>{`Terms & Condition`}</Menu.Item>
|
||||
<Menu.Item key="2" onClick={actionTerms}>Privacy Policy</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
return (
|
||||
<div style={{display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
borderBottom: '1px solid #E6ECF5',
|
||||
background: '#fff',
|
||||
position: 'fixed', width: '100%',
|
||||
padding: '0px 24px 5px', zIndex: 99,
|
||||
marginTop: isInsideForm == true ? '-154px' : '-73px' , marginLeft: '-17px' }}
|
||||
>
|
||||
<h1 style={{fontSize: '24px'}}>{title}</h1>
|
||||
<div style={{display: 'flex', position: 'fixed', right: '24px'}}>
|
||||
{
|
||||
action &&
|
||||
<div>
|
||||
{
|
||||
withConfirm
|
||||
?
|
||||
(
|
||||
<Popconfirm
|
||||
placement="bottom"
|
||||
onConfirm={()=>this.confirm(action)}
|
||||
onCancel={this.cancel} okText="Yes" cancelText="No"
|
||||
title={withConfirm && withConfirm.message}
|
||||
>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
loading={loading}
|
||||
style={{ margin: '0 4px', width: '135px',
|
||||
display: 'block', background: '#E74610', borderColor:'#E74610',
|
||||
color: '#fff' ,
|
||||
opacity: disabled ? 0.5 : 'initial'
|
||||
}}
|
||||
>
|
||||
{actionBtnName}
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
) :
|
||||
!isDropDown && (
|
||||
<Button
|
||||
loading={loading}
|
||||
onClick={action}
|
||||
disabled={disabled}
|
||||
style={{
|
||||
margin: '0 4px', width: '135px', display: 'block',
|
||||
background: styleBtn ? styleBtn.background : '#E74610',
|
||||
borderColor: styleBtn ? styleBtn.borderColor : '#E74610',
|
||||
color: styleBtn ? styleBtn.color : '#fff',
|
||||
opacity: disabled ? 0.5 : 'initial'
|
||||
}}
|
||||
>
|
||||
{actionBtnName}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
||||
}
|
||||
{
|
||||
cancel &&
|
||||
<Popconfirm
|
||||
placement="bottomRight"
|
||||
onConfirm={cancel}
|
||||
onCancel={null} okText="Yes" cancelText="No"
|
||||
title={withCancelConfirm && withCancelConfirm.message}
|
||||
>
|
||||
<Button
|
||||
loading={loading}
|
||||
onClick={withCancelConfirm ? null : cancel}
|
||||
style={{ margin: '0 4px', width: '135px', display: 'block', background: 'white', borderColor:'#b8bbc9', color: '#65697f' }}
|
||||
>
|
||||
{cancelBtnName}
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
}
|
||||
{
|
||||
deleteAction &&
|
||||
(
|
||||
<Popconfirm
|
||||
placement="bottom" title={'Are you sure you want to delete this record?'}
|
||||
onConfirm={deleteAction} okText="Yes" cancelText="No"
|
||||
icon={ <Icon type="close-circle" /> }
|
||||
>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
type="danger"
|
||||
loading={loading}
|
||||
style={{ margin: '0 4px', width: '135px', display: 'block', background: 'white', borderColor:'#b8bbc9', color: '#65697f' }}
|
||||
>
|
||||
{deleteBtnName}
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
)
|
||||
}
|
||||
{
|
||||
isDropDown && (
|
||||
<div style={{position: 'relative'}} className="terms-management-parent">
|
||||
<Dropdown overlay={menu} className="terms-management">
|
||||
<Button disabled={disabled}>
|
||||
Add <Icon type="down" />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default HeaderForm;
|
|
@ -1,37 +0,0 @@
|
|||
import * as React from 'react';
|
||||
import { Form, Icon, Input, Row, Col, Button } from 'antd';
|
||||
import ReactInputMask from 'react-input-mask';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
|
||||
const InputNumberForm = ({
|
||||
field: { ...field },
|
||||
form: { touched, errors, ...form },
|
||||
required,
|
||||
icon,
|
||||
layout,
|
||||
withActionBtn,
|
||||
action,
|
||||
loading,
|
||||
mask,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
label={props.label}
|
||||
style={{marginBottom: '10px'}}
|
||||
validateStatus={touched[field.name] && errors[field.name] && 'error'}
|
||||
help={touched[field.name] && errors[field.name]}
|
||||
>
|
||||
<ReactInputMask {...props}
|
||||
className="ant-input"
|
||||
{...field} mask={mask} maskChar=" "
|
||||
/>
|
||||
|
||||
</FormItem>
|
||||
);
|
||||
};
|
||||
|
||||
export default InputNumberForm;
|
|
@ -1,71 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Form, Icon, InputNumber } from 'antd';
|
||||
|
||||
|
||||
|
||||
const FormItem = Form.Item;
|
||||
|
||||
class InputNumberAntD extends Component {
|
||||
|
||||
handleChange = (value) => {
|
||||
const { setFieldValue } = this.props.form;
|
||||
const { name } = this.props.field;
|
||||
|
||||
//let valueNum = parseFloat(value).toFixed(2)
|
||||
// Add custom action `onChange`
|
||||
return setFieldValue(name, value);
|
||||
}
|
||||
|
||||
render() {
|
||||
const children = [];
|
||||
|
||||
|
||||
const {
|
||||
field: { ...field },
|
||||
form: { touched, errors, ...form },
|
||||
required,
|
||||
icon,
|
||||
layout,
|
||||
withActionBtn,
|
||||
action,
|
||||
min,
|
||||
max,
|
||||
step,
|
||||
...props
|
||||
} = this.props;
|
||||
|
||||
const _props = {...props}
|
||||
|
||||
_props.value = field.value
|
||||
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
label={props.label}
|
||||
style={{marginBottom: '10px'}}
|
||||
validateStatus={touched[field.name] && errors[field.name] && 'error'}
|
||||
help={touched[field.name] && errors[field.name]}
|
||||
>
|
||||
|
||||
|
||||
<InputNumber
|
||||
{..._props}
|
||||
//defaultValue={0}
|
||||
style={{width: '100%'}}
|
||||
min={min && min}
|
||||
max={max && max}
|
||||
step={step && step}
|
||||
//formatter={value => value && `${value}`}
|
||||
//parser={value => value && value.replace('', '')}
|
||||
// formatter={value => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
|
||||
// parser={value => value.replace(/\$\s?|(,*)/g, '')}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default InputNumberAntD;
|
|
@ -1,31 +0,0 @@
|
|||
import * as React from 'react';
|
||||
import { Form, Icon, Input, Row, Col, Button } from 'antd';
|
||||
import InputPassword from 'antd-input-password';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
|
||||
const InputPasswords = ({
|
||||
field: { ...field },
|
||||
form: { touched, errors, ...form },
|
||||
required,
|
||||
icon,
|
||||
layout,
|
||||
withActionBtn,
|
||||
action,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<Form.Item
|
||||
{...layout}
|
||||
required={required}
|
||||
label={props.label}
|
||||
style={{marginBottom: '10px'}}
|
||||
validateStatus={touched[field.name] && errors[field.name] && 'error'}
|
||||
help={touched[field.name] && errors[field.name]}
|
||||
>
|
||||
<Input.Password {...props} {...field} />
|
||||
</Form.Item>
|
||||
);
|
||||
};
|
||||
|
||||
export default InputPasswords;
|
|
@ -1,67 +0,0 @@
|
|||
import * as React from 'react';
|
||||
import { Form, Icon, Input, Tooltip } from 'antd';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const { TextArea } = Input;
|
||||
|
||||
|
||||
const content = (
|
||||
<span>
|
||||
<div>This content will be used in the</div>
|
||||
<div>"Enter ID Number" page as part of</div>
|
||||
<div>the Apply for a Card process of</div>
|
||||
<div>the Unioil Mobile App.</div>
|
||||
</span>
|
||||
);
|
||||
|
||||
|
||||
const InputTextArea = ({
|
||||
field: { ...field },
|
||||
form: { touched, setFieldValue, errors, ...form },
|
||||
required,
|
||||
icon,
|
||||
layout,
|
||||
withActionBtn,
|
||||
action,
|
||||
onCountText,
|
||||
charsperpage,
|
||||
pagecount,
|
||||
hasIcon,
|
||||
...props
|
||||
}) => {
|
||||
<Icon type="question-circle" />
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
label={
|
||||
<span>
|
||||
{`${props.label} `}
|
||||
{
|
||||
hasIcon &&
|
||||
<Tooltip placement="top" title={content}>
|
||||
<Icon type="question-circle" />
|
||||
</Tooltip>
|
||||
}
|
||||
</span>
|
||||
}
|
||||
style={{marginBottom: '10px'}}
|
||||
validateStatus={touched[field.name] && errors[field.name] && 'error'}
|
||||
help={touched[field.name] && errors[field.name]}
|
||||
>
|
||||
|
||||
<TextArea
|
||||
{...props}
|
||||
{...field}
|
||||
prefix={icon && <Icon type={icon} style={{ color: 'rgba(0,0,0,.25)' }} />}
|
||||
/>
|
||||
{onCountText && <div style={{position: 'relative'}}>
|
||||
<div style={{position: 'absolute',right: '0%', top: '-18px'}}>
|
||||
<span style={{color: field.value.length > charsperpage ? 'red' : 'rgba(0, 0, 0, 0.65)'}}>{field.value.length}</span>/{charsperpage && charsperpage}</div>
|
||||
</div>
|
||||
}
|
||||
</FormItem>
|
||||
);
|
||||
};
|
||||
|
||||
export default InputTextArea;
|
|
@ -1,93 +0,0 @@
|
|||
import * as React from 'react';
|
||||
import { Form, Icon, Input, Row, Col, Button, message } from 'antd';
|
||||
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
|
||||
const InputForm = ({
|
||||
field: { ...field },
|
||||
form: { touched, errors, ...form },
|
||||
required,
|
||||
icon,
|
||||
layout,
|
||||
withActionBtn,
|
||||
action,
|
||||
loading,
|
||||
isCopyUsername,
|
||||
...props
|
||||
}) => {
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
label={props.label}
|
||||
style={{marginBottom: '10px'}}
|
||||
validateStatus={touched[field.name] && errors[field.name] && 'error'}
|
||||
help={touched[field.name] && errors[field.name]}
|
||||
>
|
||||
{
|
||||
!withActionBtn
|
||||
?
|
||||
<div style={{display: 'flex'}}>
|
||||
<Input
|
||||
{...props}
|
||||
{...field}
|
||||
prefix={icon && <Icon type={icon} style={{ color: 'rgba(0,0,0,.25)' }} />}
|
||||
/>
|
||||
{
|
||||
isCopyUsername && (
|
||||
<CopyToClipboard text={field.value}>
|
||||
<Button
|
||||
loading={loading}
|
||||
disabled={
|
||||
field.value.length > 0 ? false : true
|
||||
}
|
||||
style={{
|
||||
padding: '0 30px',
|
||||
opacity: field.value.length > 0 ? 'initial' : 0.8,
|
||||
margin: '0 0 0 10px',background: '#E74610', borderColor:'#E74610', color: '#fff'
|
||||
}}
|
||||
onClick={()=> message.success('Username successfully copied.')}>
|
||||
Copy
|
||||
</Button>
|
||||
</CopyToClipboard>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
:
|
||||
<Row gutter={8}>
|
||||
<Col span={13}>
|
||||
<Input
|
||||
{...props}
|
||||
{...field}
|
||||
className="generated-input"
|
||||
prefix={icon && <Icon type={icon} style={{ color: 'rgba(0,0,0,.25)' }} />}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={11}>
|
||||
<Button
|
||||
loading={loading}
|
||||
disabled={withActionBtn.disabled}
|
||||
style={{opacity: withActionBtn.disabled ? 0.8 : 'initial' ,background: '#E74610', borderColor:'#E74610', color: '#fff'}} onClick={withActionBtn.action}>{withActionBtn.name}
|
||||
</Button>
|
||||
<CopyToClipboard text={withActionBtn.password} onCopy={withActionBtn.copyAction ? withActionBtn.copyAction : ()=> {return null}}>
|
||||
<Button
|
||||
loading={loading}
|
||||
disabled={withActionBtn.copyAction ? false : true}
|
||||
style={{
|
||||
padding: '0 30px',
|
||||
opacity: withActionBtn.copyAction ? 'initial' : 0.8 , background: '#E74610', borderColor:'#E74610', color: '#fff', marginLeft: '5px'}}
|
||||
// onClick={withActionBtn.copyAction ? withActionBtn.copyAction : ()=> {return null} }
|
||||
>
|
||||
Copy
|
||||
</Button>
|
||||
</CopyToClipboard>
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
|
||||
</FormItem>
|
||||
);
|
||||
};
|
||||
|
||||
export default InputForm;
|
|
@ -1,86 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Form, Select } from 'antd';
|
||||
|
||||
import { fetchData } from 'utils/Api';
|
||||
const FormItem = Form.Item;
|
||||
const Option = Select.Option;
|
||||
|
||||
class MultiSelectForm extends Component {
|
||||
async componentDidMount() {
|
||||
// const { url } = this.props;
|
||||
// const response = await fetchData(url);
|
||||
// this.setState({
|
||||
// options: response.data.data
|
||||
// })
|
||||
}
|
||||
|
||||
handleChange = (value) => {
|
||||
const { setFieldValue } = this.props.form;
|
||||
const { name } = this.props.field;
|
||||
|
||||
if(this.props.handleGetDate) {
|
||||
this.props.handleGetDate(value);
|
||||
this.props.handleAutoFillDeatils(value,setFieldValue,this.props);
|
||||
}
|
||||
// Add custom action `onChange`
|
||||
return setFieldValue(name, value);
|
||||
}
|
||||
|
||||
render() {
|
||||
const children = [];
|
||||
if (this.state && this.state.options) {
|
||||
this.state.options.map((item, key) => {
|
||||
children.push(<Option value={item.id.toString()}>{item.first_name}</Option>)
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
const {
|
||||
field: { ...field },
|
||||
form: { touched, errors, ...form },
|
||||
layout,
|
||||
label,
|
||||
required,
|
||||
optionFilterProp,
|
||||
mode,
|
||||
optionsList,
|
||||
branchesOptionsTwo,
|
||||
placeholder,
|
||||
...props
|
||||
} = this.props;
|
||||
// console.log(field)
|
||||
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
label={label}
|
||||
style={{marginBottom: '10px'}}
|
||||
validateStatus={touched[field.name] && errors[field.name] && 'error'}
|
||||
help={touched[field.name] && errors[field.name]}
|
||||
>
|
||||
<Select
|
||||
{...props}
|
||||
// filterOption={
|
||||
// optionFilterProp ?
|
||||
// (input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 : ''
|
||||
// }
|
||||
placeholder={placeholder}
|
||||
value={field.value}
|
||||
mode={mode}
|
||||
onChange={this.handleChange}
|
||||
children={children}
|
||||
>
|
||||
{
|
||||
optionsList && (optionsList.map((item,i) => {
|
||||
return <Option value={item.id} key={`${i}-${field.name}`}>{item.name}</Option>
|
||||
}))
|
||||
}
|
||||
|
||||
</Select>
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default MultiSelectForm;
|
|
@ -1,69 +0,0 @@
|
|||
import React, {Component} from 'react';
|
||||
import { Form , Select } from 'antd';
|
||||
import { Field } from 'formik';
|
||||
import { Input } from 'components/Forms';
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 4 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 20 },
|
||||
},
|
||||
};
|
||||
|
||||
class MultiSelectOptions extends Component {
|
||||
state= {
|
||||
value: []
|
||||
}
|
||||
|
||||
handleChange(event){
|
||||
console.log(event)
|
||||
this.setState({value: event})
|
||||
}
|
||||
|
||||
render() {
|
||||
const FormItem = Form.Item;
|
||||
const Option = Select.Option;
|
||||
const {
|
||||
field: { ...field },
|
||||
form: { touched, errors, ...form },
|
||||
required,
|
||||
icon,
|
||||
layout,
|
||||
withActionBtn,
|
||||
action,
|
||||
optionsList,
|
||||
...props
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
label={props.label}
|
||||
style={{marginBottom: '10px'}}
|
||||
validateStatus={touched[field.name] && errors[field.name] && 'error'}
|
||||
help={touched[field.name] && errors[field.name]}
|
||||
>
|
||||
<Select
|
||||
style={{ width: '100%' }}
|
||||
placeholder="Select fuels."
|
||||
defaultValue={[]}
|
||||
onChange={(e)=>this.props.onChange (e)}
|
||||
optionLabelProp="label"
|
||||
mode="multiple"
|
||||
>
|
||||
{
|
||||
optionsList && (optionsList.map((item,i) => {
|
||||
return <Option value={item.id} key={`${i}-${field.name}`} label={item.name}>{item.name}</Option>
|
||||
}))
|
||||
}
|
||||
</Select>
|
||||
</FormItem>
|
||||
)};
|
||||
};
|
||||
|
||||
export default MultiSelectOptions;
|
|
@ -1,84 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Form, Radio } from 'antd';
|
||||
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const RadioGroup = Radio.Group;
|
||||
|
||||
let styles = {
|
||||
':select': {
|
||||
backgroundColor: 'yellow',
|
||||
color: 'red'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class InputForm extends Component {
|
||||
|
||||
|
||||
handleChange = (e) => {
|
||||
const { setFieldValue } = this.props.form;
|
||||
const { name } = this.props.field;
|
||||
//Add custom action `onChange`
|
||||
if(this.props.handleResetValue) {
|
||||
this.props.handleResetValue(this.props.form);
|
||||
}
|
||||
if(this.props.handleScheduleStatus) {
|
||||
this.props.handleScheduleStatus(e.target.value)
|
||||
}
|
||||
return setFieldValue(name, e.target.value);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
|
||||
const {
|
||||
field: { ...field },
|
||||
form: { touched, errors, ...form },
|
||||
required,
|
||||
icon,
|
||||
layout,
|
||||
optionsList,
|
||||
isRadioButton,
|
||||
...props,
|
||||
} = this.props;
|
||||
|
||||
let _props = {...props};
|
||||
let _field = {...field};
|
||||
|
||||
if(!_field.value) {
|
||||
_field.value = _props.defaultValue
|
||||
}
|
||||
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
label={props.label}
|
||||
style={{marginBottom: '10px'}}
|
||||
validateStatus={touched[field.name] && errors[field.name] && 'error'}
|
||||
help={touched[field.name] && errors[field.name]}
|
||||
>
|
||||
<Radio.Group {..._field} {..._props} onChange={this.handleChange}>
|
||||
{
|
||||
optionsList ? (
|
||||
optionsList.map((item,i) => {
|
||||
if(isRadioButton) {
|
||||
return <Radio.Button value={item.value} disabled={item.isDisabled} key={i} style={styles}>
|
||||
{item.label}
|
||||
</Radio.Button>
|
||||
}
|
||||
return <Radio value={item.value} key={i} style={styles}>
|
||||
{item.label}
|
||||
</Radio>
|
||||
})
|
||||
) : null
|
||||
}
|
||||
</Radio.Group>
|
||||
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default InputForm;
|
|
@ -1,91 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Form, Select } from 'antd';
|
||||
|
||||
import { fetchData } from 'utils/Api';
|
||||
const FormItem = Form.Item;
|
||||
const Option = Select.Option;
|
||||
|
||||
class SelectForm extends Component {
|
||||
async componentDidMount() {
|
||||
// const { url } = this.props;
|
||||
// const response = await fetchData(url);
|
||||
// this.setState({
|
||||
// options: response.data.data
|
||||
// })
|
||||
}
|
||||
|
||||
handleChange = (value) => {
|
||||
const { setFieldValue } = this.props.form;
|
||||
const { name } = this.props.field;
|
||||
|
||||
if(this.props.handleGetDate) {
|
||||
this.props.handleGetDate(value);
|
||||
this.props.handleAutoFillDeatils(value,setFieldValue,this.props);
|
||||
}
|
||||
// Add custom action `onChange`
|
||||
return setFieldValue(name, value);
|
||||
}
|
||||
|
||||
render() {
|
||||
const children = [];
|
||||
|
||||
if (this.state && this.state.options) {
|
||||
this.state.options.map((item, key) => {
|
||||
children.push(<Option value={item.id.toString()}>{item.first_name}</Option>)
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
const {
|
||||
field: { ...field },
|
||||
form: { touched, errors, ...form },
|
||||
layout,
|
||||
label,
|
||||
required,
|
||||
optionFilterProp,
|
||||
mode,
|
||||
optionsList,
|
||||
branchesOptionsTwo,
|
||||
...props
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
label={label}
|
||||
style={{marginBottom: '10px'}}
|
||||
validateStatus={touched[field.name] && errors[field.name] && 'error'}
|
||||
help={touched[field.name] && errors[field.name]}
|
||||
>
|
||||
<Select
|
||||
{...props}
|
||||
// filterOption={
|
||||
// optionFilterProp ?
|
||||
// (input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 : ''
|
||||
// }
|
||||
mode={mode}
|
||||
onChange={this.handleChange}
|
||||
children={children}
|
||||
>
|
||||
{
|
||||
branchesOptionsTwo
|
||||
?
|
||||
branchesOptionsTwo.map(item => (
|
||||
<Select.Option key={item} value={item}>
|
||||
{item}
|
||||
</Select.Option>
|
||||
))
|
||||
:
|
||||
optionsList && (optionsList.map((item,i) => {
|
||||
return <Option value={item.value} key={`${i}-${field.name}`}>{item.label}</Option>
|
||||
}))
|
||||
}
|
||||
|
||||
</Select>
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SelectForm;
|
|
@ -1,185 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Form, Icon, Input, Upload, message } from 'antd';
|
||||
import filesize from 'filesize';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
|
||||
|
||||
class BackgroundUploadImage extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
fileUpload: null,
|
||||
loading: false,
|
||||
hasError: false,
|
||||
imageUrl: props.imageUrl
|
||||
};
|
||||
}
|
||||
|
||||
normFile = (info) => {
|
||||
const { handleFileUpload } = this.props;
|
||||
const isJPG = info.file.type === 'image/jpeg' || info.file.type === 'image/png' || info.file.type === 'image/gif' ;
|
||||
|
||||
if(isJPG && info.file.originFileObj) {
|
||||
|
||||
this.getBase64(info.file.originFileObj, imageUrl => this.setState({
|
||||
imageUrl,
|
||||
loading: false,
|
||||
}));
|
||||
|
||||
let imageUrl = this.state.imageUrl;
|
||||
this.props.form.setFieldValue(this.props.field.name, imageUrl);
|
||||
|
||||
// this.props.form.setFieldValue("logo", 'imageValue');
|
||||
|
||||
handleFileUpload(info,this.props.form.setFieldValue)
|
||||
}
|
||||
|
||||
// if (Array.isArray(e)) {
|
||||
// return this.setState({fileUpload: e});
|
||||
// }
|
||||
// return e && this.setState({fileUpload: e.fileList});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
getBase64 =(img, callback)=> {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(img);
|
||||
reader.addEventListener('load', () => {
|
||||
callback(reader.result)
|
||||
this.props.form.setFieldValue(this.props.field.name, reader.result);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
beforeUpload =(file)=> {
|
||||
const {notAcceptedImg} = this.props;
|
||||
const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' ;
|
||||
if (!isJPG) {
|
||||
message.error('You can only upload JPG, PNG or GIF file!');
|
||||
}
|
||||
|
||||
if(notAcceptedImg && notAcceptedImg.length > 0) {
|
||||
notAcceptedImg.map(item => {
|
||||
if(file.type == item) return message.error('You can only upload JPG or PNG file!');
|
||||
})
|
||||
}
|
||||
|
||||
let fileSize; let isLt2M;
|
||||
|
||||
if(this.props.limit100kb) {
|
||||
fileSize = filesize(file.size, {output: "array"} ) // 100kb
|
||||
isLt2M = fileSize[0] < 104 && fileSize[1] == "KB"
|
||||
} else {
|
||||
isLt2M = file.size / 1024 / 1024 < 2; // 2MB
|
||||
}
|
||||
//const isLt2M = fileSize[0] < 104;
|
||||
//const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
|
||||
if (!isLt2M) {
|
||||
if(this.props.limit100kb) {
|
||||
message.error('Image must smaller than 100KB!');
|
||||
} else {
|
||||
message.error('Image must smaller than 2MB!');
|
||||
}
|
||||
}
|
||||
return isJPG && isLt2M;
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const {
|
||||
field: { ...field },
|
||||
form: { touched, errors, ...form },
|
||||
required,
|
||||
icon,
|
||||
layout,
|
||||
withActionBtn,
|
||||
action,
|
||||
fileList,
|
||||
messageUpload,
|
||||
multipleFileUpload,
|
||||
imgWidth,
|
||||
imgStyle,
|
||||
isRatioMessage,
|
||||
notAcceptedImg,
|
||||
...props
|
||||
} = this.props;
|
||||
|
||||
let _props = {...props};
|
||||
let _field = {...field};
|
||||
|
||||
const { onChange, onBlur, ...restField } = field;
|
||||
const { fileUpload } =this.state;
|
||||
|
||||
// let props_list_image = {
|
||||
// action: '',
|
||||
// listType: 'picture',
|
||||
// defaultFileList: [...fileList],
|
||||
// className: 'upload-list-inline',
|
||||
// };
|
||||
|
||||
const uploadButton = (
|
||||
<div>
|
||||
<Icon type={this.state.loading ? 'loading' : 'plus'} />
|
||||
<div className="ant-upload-text">Upload</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
label={props.label}
|
||||
style={{marginBottom: '10px'}}
|
||||
validateStatus={touched[field.name] && errors[field.name] && 'error'}
|
||||
help={touched[field.name] && errors[field.name]}
|
||||
>
|
||||
{
|
||||
multipleFileUpload ?
|
||||
(
|
||||
<Upload.Dragger
|
||||
{..._props} {..._field}
|
||||
//{...props_list_image}
|
||||
onChange={this.normFile}
|
||||
>
|
||||
<p className="ant-upload-drag-icon">
|
||||
<Icon type="inbox" />
|
||||
</p>
|
||||
<p className="ant-upload-text">Click or drag file to this area to upload</p>
|
||||
<p className="ant-upload-hint">Support for a single or bulk upload.</p>
|
||||
</Upload.Dragger>
|
||||
) :
|
||||
(
|
||||
<Upload
|
||||
style={{padding: '13px 22px'}}
|
||||
name="avatar"
|
||||
listType="picture-card"
|
||||
className="avatar-uploader"
|
||||
accept=".jpg , .png , .gif"
|
||||
showUploadList={false}
|
||||
notAcceptedImg={notAcceptedImg}
|
||||
beforeUpload={this.beforeUpload}
|
||||
onChange={this.normFile}
|
||||
className="upload-image"
|
||||
>
|
||||
{this.state.imageUrl ? <img src={this.state.imageUrl} alt="avatar" width={imgStyle ? imgStyle.width : "100%" } height={imgStyle ? imgStyle.height : "135"} /> : uploadButton}
|
||||
<div style={{width: imgWidth ? imgWidth : 'initial', margin: '0 auto'}}>
|
||||
<p className="ant-upload-text">Click or drag file to this area to upload.</p>
|
||||
<p className="ant-upload-hint">Support for a single upload only.</p>
|
||||
{ isRatioMessage && <p className="ant-upload-hint">{isRatioMessage.isRatioMessage && isRatioMessage.isRatioMessage}</p> }
|
||||
</div>
|
||||
</Upload>
|
||||
)
|
||||
}
|
||||
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default BackgroundUploadImage;
|
|
@ -1,71 +0,0 @@
|
|||
import React from 'react';
|
||||
import { Form, DatePicker, TimePicker } from 'antd';
|
||||
import moment from 'moment';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
const TimePickerForm = ({
|
||||
field: { ...field },
|
||||
form: { touched, errors, handleSubmit, setFieldValue, handlePanelChange, ...form },
|
||||
type,
|
||||
layout,
|
||||
label,
|
||||
format,
|
||||
minDateToday,
|
||||
required,
|
||||
isAutoFill,
|
||||
...props
|
||||
}) => {
|
||||
|
||||
const onDateChange = (value, isDateRange = false) => {
|
||||
value && setFieldValue(field.name, isDateRange
|
||||
? [value[0].format(format), value[1].format(format)]
|
||||
: value.format(format)
|
||||
)
|
||||
|
||||
if(value == null) {
|
||||
setFieldValue(field.name, isDateRange
|
||||
? [value[0].format(format), value[1].format(format)]
|
||||
: null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Disable date less than `Today`
|
||||
// use minDateToday props
|
||||
const disabledDate = (current) => {
|
||||
if (minDateToday) {
|
||||
var oneDay = (1 * 24 * 60 * 60 * 1000);
|
||||
return current && (current.valueOf() < (Date.now() - oneDay));
|
||||
}
|
||||
}
|
||||
|
||||
let _props = {...props}; let _field = {...field};
|
||||
|
||||
|
||||
if(_field.value !== "") {
|
||||
_props.value = _field.value && moment(_field.value,format)
|
||||
}
|
||||
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
label={label}
|
||||
style={{marginBottom: '10px'}}
|
||||
validateStatus={touched[field.name] && errors[field.name] && 'error'}
|
||||
help={touched[field.name] && errors[field.name]}
|
||||
>
|
||||
<TimePicker
|
||||
{..._props}
|
||||
onChange={(value) => onDateChange(value)}
|
||||
format={format}
|
||||
//disabledDate={disabledDate}
|
||||
style={{width: '250px'}}
|
||||
/>
|
||||
</FormItem>
|
||||
);
|
||||
};
|
||||
|
||||
export default TimePickerForm;
|
|
@ -1,201 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Form, Icon, Input, Upload, message } from 'antd';
|
||||
import filesize from 'filesize';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
|
||||
|
||||
class UploadImage extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
fileUpload: null,
|
||||
loading: false,
|
||||
hasError: false,
|
||||
imageUrl: props.imageUrl
|
||||
};
|
||||
}
|
||||
|
||||
normFile = (info) => {
|
||||
const { handleFileUpload } = this.props;
|
||||
const isJPG = info.file.type === 'image/jpeg' || info.file.type === 'image/png' || info.file.type === 'image/gif' ;
|
||||
|
||||
if(isJPG && info.file.originFileObj) {
|
||||
|
||||
this.getBase64(info.file.originFileObj, imageUrl => this.setState({
|
||||
imageUrl,
|
||||
loading: false,
|
||||
}));
|
||||
|
||||
// if(this.props.isDefault) {
|
||||
// this.props.form.setFieldValue("image", 'imageValue');
|
||||
// } else {
|
||||
// let imageUrl = this.state.imageUrl ? this.state.imageUrl : this.props.imageUrl;
|
||||
// this.props.form.setFieldValue("image", imageUrl);
|
||||
// }
|
||||
|
||||
this.props.form.setFieldValue("logo", 'imageValue');
|
||||
|
||||
handleFileUpload(info,this.props.form.setFieldValue)
|
||||
}
|
||||
|
||||
// if (Array.isArray(e)) {
|
||||
// return this.setState({fileUpload: e});
|
||||
// }
|
||||
// return e && this.setState({fileUpload: e.fileList});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
getBase64 =(img, callback)=> {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(img);
|
||||
//reader.addEventListener('load', () => callback(reader.result));
|
||||
reader.addEventListener('load', () => {
|
||||
callback(reader.result)
|
||||
this.props.form.setFieldValue(this.props.field.name, reader.result);
|
||||
});
|
||||
}
|
||||
|
||||
beforeUpload =(file)=> {
|
||||
const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' ;
|
||||
if (!isJPG) {
|
||||
message.error('You can only upload JPG, PNG or GIF file!');
|
||||
}
|
||||
|
||||
let fileSize; let isLt2M;
|
||||
|
||||
if(this.props.limit100kb) {
|
||||
fileSize = filesize(file.size, {output: "array"} ) // 100kb
|
||||
isLt2M = fileSize[0] < 104 && fileSize[1] == "KB"
|
||||
} else {
|
||||
isLt2M = file.size / 1024 / 1024 < 2; // 2MB
|
||||
}
|
||||
//const isLt2M = fileSize[0] < 104;
|
||||
//const isLt2M = file.size / 1024 / 1024 < 2;
|
||||
|
||||
if (!isLt2M) {
|
||||
if(this.props.limit100kb) {
|
||||
message.error('Image must smaller than 100KB!');
|
||||
} else {
|
||||
message.error('Image must smaller than 2MB!');
|
||||
}
|
||||
}
|
||||
return isJPG && isLt2M;
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const {
|
||||
field: { ...field },
|
||||
form: { touched, errors, ...form },
|
||||
required,
|
||||
icon,
|
||||
layout,
|
||||
withActionBtn,
|
||||
action,
|
||||
fileList,
|
||||
messageUpload,
|
||||
multipleFileUpload,
|
||||
imgWidth,
|
||||
imgStyle,
|
||||
isRatioMessage,
|
||||
...props
|
||||
} = this.props;
|
||||
|
||||
let _props = {...props};
|
||||
let _field = {...field};
|
||||
|
||||
const { onChange, onBlur, ...restField } = field;
|
||||
const { fileUpload } =this.state;
|
||||
|
||||
// let props_list_image = {
|
||||
// action: '',
|
||||
// listType: 'picture',
|
||||
// defaultFileList: [...fileList],
|
||||
// className: 'upload-list-inline',
|
||||
// };
|
||||
|
||||
const uploadButton = (
|
||||
<div>
|
||||
<Icon
|
||||
style={{fontSize: '30px'}}
|
||||
type={this.state.loading ? 'loading' : 'plus'}
|
||||
/>
|
||||
{/* <div className="ant-upload-text">Upload</div> */}
|
||||
</div>
|
||||
);
|
||||
|
||||
let imageUrl;
|
||||
|
||||
if(this.props.isDefault) {
|
||||
imageUrl = this.state.imageUrl
|
||||
} else {
|
||||
imageUrl = this.props.imageUrl
|
||||
}
|
||||
|
||||
return (
|
||||
<FormItem
|
||||
{...layout}
|
||||
required={required}
|
||||
label={props.label}
|
||||
style={{marginBottom: '10px'}}
|
||||
validateStatus={touched[field.name] && errors[field.name] && 'error'}
|
||||
help={touched[field.name] && errors[field.name]}
|
||||
>
|
||||
{
|
||||
multipleFileUpload ?
|
||||
(
|
||||
<Upload.Dragger
|
||||
{..._props} {..._field}
|
||||
//{...props_list_image}
|
||||
onChange={this.normFile}
|
||||
>
|
||||
<p className="ant-upload-drag-icon">
|
||||
<Icon type="inbox" />
|
||||
</p>
|
||||
<p className="ant-upload-text">Click or drag file to this area to upload</p>
|
||||
<p className="ant-upload-hint">Support for a single or bulk upload.</p>
|
||||
</Upload.Dragger>
|
||||
) :
|
||||
(
|
||||
<Upload
|
||||
style={{padding: '13px 22px'}}
|
||||
name="avatar"
|
||||
listType="picture-card"
|
||||
className="avatar-uploader"
|
||||
accept=".jpg , .png , .gif"
|
||||
showUploadList={false}
|
||||
beforeUpload={this.beforeUpload}
|
||||
onChange={this.normFile}
|
||||
className="upload-image"
|
||||
>
|
||||
{imageUrl ? <img src={imageUrl} alt="avatar" width={imgStyle ? imgStyle.width : "100%" } height={imgStyle ? imgStyle.height : "135"} /> : uploadButton}
|
||||
<div style={{width: imgWidth ? imgWidth : 'initial', margin: '0 auto'}}>
|
||||
<p
|
||||
style={{fontWeight: 'bold',marginTop:'3px'}}
|
||||
className="ant-upload-text"
|
||||
>Click or drag file to this area to upload</p>
|
||||
<p
|
||||
style={{fontSize: '13px'}}
|
||||
className="ant-upload-hint"
|
||||
>Support for a single upload only</p>
|
||||
{ isRatioMessage &&
|
||||
<div className="ant-upload-hint">
|
||||
{isRatioMessage.message ? isRatioMessage.message : "Aspect Ratio 4:3 (ex. 1024 x 768)"}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</Upload>
|
||||
)
|
||||
}
|
||||
|
||||
</FormItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default UploadImage;
|
|
@ -1,33 +0,0 @@
|
|||
import Checkbox from './Checkbox';
|
||||
import Inputs from './Inputs';
|
||||
import Select from './Select';
|
||||
import Cascader from './Cascader';
|
||||
import DatePicker from './DatePicker';
|
||||
import Radio from './Radio';
|
||||
import InputPassword from './InputPassword';
|
||||
import InputTextArea from './InputTextArea';
|
||||
import UploadImage from './UploadImage';
|
||||
import MultiSelectOptions from './MultiSelectOptions';
|
||||
import InputMaskNumber from './InputMaskNumber';
|
||||
import TimePickerForm from './TimePicker'
|
||||
import InputNumberAntD from './InputNumberAntD'
|
||||
import SingleUploadImage from './SingleUploadImage'
|
||||
import MultiSelect from './MultiSelect'
|
||||
|
||||
export {
|
||||
Checkbox,
|
||||
Inputs,
|
||||
Select,
|
||||
Cascader,
|
||||
DatePicker,
|
||||
Radio,
|
||||
InputPassword,
|
||||
InputTextArea,
|
||||
UploadImage,
|
||||
MultiSelectOptions,
|
||||
MultiSelect,
|
||||
InputMaskNumber,
|
||||
TimePickerForm,
|
||||
InputNumberAntD,
|
||||
SingleUploadImage
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
|
||||
import { Icon } from 'antd';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
const Loading = () => {
|
||||
return (
|
||||
<div style={{padding: 20, display: 'flex' , justifyContent: 'center' , marginLeft: '-144px'}}>
|
||||
<div>
|
||||
<Icon type="sync" spin /> Loading Data Please wait...
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Loading;
|
|
@ -1,23 +0,0 @@
|
|||
|
||||
import React from 'react'
|
||||
import { Layout } from 'antd';
|
||||
const { Header, Footer, Content, Sider } = Layout;
|
||||
|
||||
|
||||
function LoginLayout({children, ...rest}) {
|
||||
return (
|
||||
<Layout style={{height: "100%"}}>
|
||||
<Sider width='50%' style={{ background: `url(${require("assets/img/bg_cms.png")}) center`, backgroundSize: 'cover' } }></Sider>
|
||||
<Layout>
|
||||
<Content style={{padding: 16}} >{children}</Content>
|
||||
<Footer style={{textAlign: 'center', fontSize: '12px'}}>
|
||||
<div style={{margin: '25px auto', padding: '17px 0', width: '325px', borderTop: '1px solid #e0e0e0', textAlign: 'left', color: '#8E8E93' }}>
|
||||
By logging in you agree to Unioil's Terms of Service, <br/>Privacy Policy and Content Policies.
|
||||
</div>
|
||||
</Footer>
|
||||
</Layout>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
export default LoginLayout
|
|
@ -1,16 +0,0 @@
|
|||
import React from 'react';
|
||||
import LoginLayout from '../Layout'
|
||||
import { Route } from 'react-router-dom'
|
||||
const LoginLayoutRoute = ({component: Component, ...rest}) => {
|
||||
return (
|
||||
<Route {...rest} render={matchProps => (
|
||||
<LoginLayout>
|
||||
<Component {...matchProps} />
|
||||
</LoginLayout>
|
||||
)} />
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default LoginLayoutRoute
|
|
@ -1,84 +0,0 @@
|
|||
import React, { Component } from "react";
|
||||
|
||||
import { Modal, Button } from "antd";
|
||||
import { Link } from 'react-router-dom';
|
||||
class ModalCancel extends React.Component {
|
||||
state = { visible: false };
|
||||
|
||||
showModal = () => {
|
||||
this.setState({
|
||||
visible: true
|
||||
});
|
||||
};
|
||||
|
||||
handleOk = e => {
|
||||
console.log(e);
|
||||
|
||||
|
||||
this.setState({
|
||||
visible: false
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
handleCancel = e => {
|
||||
console.log(e);
|
||||
this.setState({
|
||||
visible: false
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
const {
|
||||
path,
|
||||
title,
|
||||
message,
|
||||
id,
|
||||
dirty,
|
||||
name,
|
||||
loading
|
||||
} = this.props
|
||||
|
||||
if (dirty) {
|
||||
return [
|
||||
<Button
|
||||
key="button"
|
||||
disabled={loading}
|
||||
onClick={this.showModal}>
|
||||
{name}
|
||||
</Button>,
|
||||
<Modal
|
||||
getContainer={() => document.getElementById(id)}
|
||||
key="modal"
|
||||
width={300}
|
||||
title={title ? title : "Your Title"}
|
||||
visible={this.state.visible}
|
||||
onOk={this.handleOk}
|
||||
onCancel={this.handleCancel}
|
||||
footer={[
|
||||
<Button key={1} type="primary" onClick={this.handleCancel}>No</Button>,
|
||||
<Link key={2} to={path} style={{marginLeft: 10}}>
|
||||
<Button >
|
||||
Yes
|
||||
</Button>
|
||||
</Link>
|
||||
]}
|
||||
>
|
||||
{message ? message : "Your Message"}
|
||||
</Modal>
|
||||
];
|
||||
} else {
|
||||
return <Link to={path} disabled={loading}>
|
||||
<Button key="back" disabled={loading}>
|
||||
{name}
|
||||
</Button>
|
||||
</Link>
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default ModalCancel;
|
|
@ -1,429 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import queryString from 'query-string';
|
||||
import { getCookie } from '../../utils/cookie';
|
||||
|
||||
import _ from 'lodash';
|
||||
import {
|
||||
Table,
|
||||
Button,
|
||||
Row,
|
||||
Col,
|
||||
Input,
|
||||
Icon,
|
||||
Pagination,
|
||||
Tooltip,
|
||||
notification,
|
||||
Popconfirm,
|
||||
message,
|
||||
DatePicker,
|
||||
} from 'antd';
|
||||
|
||||
import { DropdownExport } from 'components/Dropdown/index';
|
||||
import { fnQueryParams } from 'utils/helper';
|
||||
import { API_UNI_OIL, API_GET, API_DELETE } from 'utils/Api';
|
||||
import { API_GET_NOTIF } from 'utils/NotificationApi';
|
||||
import '../Tables/index.css';
|
||||
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
class Index extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
data: null,
|
||||
total: null,
|
||||
loading: false,
|
||||
selectedRowKeys: [],
|
||||
columns: [],
|
||||
search_filter: '',
|
||||
visible: false,
|
||||
mounted: false,
|
||||
test: true,
|
||||
updating: false,
|
||||
};
|
||||
|
||||
this.delayFetchRequest = _.debounce(this.fetch, 500);
|
||||
this.handleSearchChangeDebounce = _.debounce(this.handleSearchStateChange, 1000);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({ mounted: true });
|
||||
this.handleFilterChange({});
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState, snapshot) {
|
||||
if (prevState.updating !== prevProps.updating) {
|
||||
this.setState({ updating: prevProps.updating });
|
||||
}
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
if (nextProps.updating !== nextState.updating) {
|
||||
this.handleFilterChange({});
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.delayFetchRequest.cancel();
|
||||
this.handleSearchChangeDebounce.cancel();
|
||||
}
|
||||
|
||||
handleTableChange = (pagination, filters, sorter) => {
|
||||
let _sort_order;
|
||||
if (sorter.order) _sort_order = sorter.order === 'ascend' ? 'asc' : 'desc';
|
||||
|
||||
if (sorter.column) {
|
||||
if (sorter.column.sortByValue) sorter.field = sorter.column.sortByValue;
|
||||
}
|
||||
|
||||
this.handleFilterChange({
|
||||
...filters,
|
||||
_sort_by: sorter.field,
|
||||
_sort_order,
|
||||
});
|
||||
};
|
||||
|
||||
handleSearchChange = (e) => {
|
||||
this.setState({ search_filter: e.target.value });
|
||||
this.handleSearchChangeDebounce(e.target.value);
|
||||
};
|
||||
|
||||
handleSearchStateChange = (search_filter) => {
|
||||
this.setState({ search_filter });
|
||||
this.handleFilterChange({ search: this.state.search_filter });
|
||||
};
|
||||
|
||||
onPaginationChange = (page, page_size) => {
|
||||
console.log("page")
|
||||
console.log(page)
|
||||
this.handleFilterChange({ page });
|
||||
};
|
||||
|
||||
handleFilterChange = (props, isClearFilter) => {
|
||||
console.log(props)
|
||||
this.setState({ loading: true });
|
||||
|
||||
let { history, location } = this.props;
|
||||
let { search, pathname } = location;
|
||||
let urlParamsObject = isClearFilter ? props : queryString.parse(search);
|
||||
urlParamsObject = props ? { ...urlParamsObject,page: 1, ...props } : {};
|
||||
urlParamsObject = fnQueryParams(urlParamsObject);
|
||||
urlParamsObject = queryString.parse(urlParamsObject);
|
||||
history.push({ pathname, search: fnQueryParams(urlParamsObject) });
|
||||
console.log({ pathname, search: fnQueryParams(urlParamsObject) })
|
||||
this.delayFetchRequest(urlParamsObject);
|
||||
};
|
||||
|
||||
clearFilters = () => {
|
||||
let { history, location } = this.props;
|
||||
let { search, pathname } = location;
|
||||
let urlParamsObject = queryString.parse(search);
|
||||
delete urlParamsObject['search'];
|
||||
Object.keys(urlParamsObject).map((key, index) => {
|
||||
if (this.props.filterValues.includes(key)) delete urlParamsObject[key];
|
||||
});
|
||||
|
||||
history.push({ pathname, search: fnQueryParams(urlParamsObject) });
|
||||
this.handleFilterChange(urlParamsObject, true);
|
||||
};
|
||||
|
||||
clearAll = () => {
|
||||
this.setState({ search_filter: '' });
|
||||
this.handleFilterChange();
|
||||
};
|
||||
|
||||
fetch = async (params = {}) => {
|
||||
let defaulUrl;
|
||||
|
||||
if (this.props.defaultFilter) {
|
||||
params = {
|
||||
...params,
|
||||
...this.props.defaultFilter,
|
||||
};
|
||||
}
|
||||
|
||||
if (this.props.url.defaultWithFilter) {
|
||||
defaulUrl = this.props.url.defaultWithFilter;
|
||||
} else {
|
||||
defaulUrl = this.props.url.default;
|
||||
}
|
||||
|
||||
try {
|
||||
let response, data, total;
|
||||
if(defaulUrl == 'notification'){
|
||||
console.log(defaulUrl, params)
|
||||
response = await API_GET_NOTIF('notification', params);
|
||||
console.log(response.data, params, 'response');
|
||||
console.log(getCookie('TOKEN').token);
|
||||
data = response.data.data.length > 0 ? response.data.data : null;
|
||||
total = response.data.total
|
||||
}
|
||||
console.table(data, 'data');
|
||||
this.setState({ data, total, loading: false });
|
||||
if (data == null && this.props.isEmptyMessagePopUp) {
|
||||
message.info('No records found.');
|
||||
}
|
||||
if (this.props.dataResponse) {
|
||||
this.props.dataResponse(data.length);
|
||||
}
|
||||
} catch (error) {
|
||||
this.setState({ loading: false, total: 0 });
|
||||
console.log('An error encountered: ' + error);
|
||||
}
|
||||
};
|
||||
|
||||
update = async (params = {}) => {
|
||||
notification.success({
|
||||
message: 'Success',
|
||||
description: `Delete Successful.`,
|
||||
});
|
||||
};
|
||||
|
||||
remove = async (params = {}) => {
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: `Error message.`,
|
||||
});
|
||||
};
|
||||
|
||||
delete = async (uuid) => {
|
||||
console.log(uuid)
|
||||
let search = this.props.location;
|
||||
console.log(search.pathname)
|
||||
let api = process.env.REACT_APP_STATION_API
|
||||
let path = search.pathname.substring(1)
|
||||
try {
|
||||
await API_UNI_OIL.delete(`${api}${path}/${uuid}`);
|
||||
this.handleFilterChange({});
|
||||
message.success('Record was successfully deleted.');
|
||||
} catch ({ response: error }) {
|
||||
this.handleFilterChange({});
|
||||
notification.error({
|
||||
message: 'Something went wrong deleting record!',
|
||||
description: (
|
||||
<div>
|
||||
<h3>
|
||||
{error && error.data && error.data.message}
|
||||
</h3>
|
||||
</div>
|
||||
),
|
||||
duration: 4,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleBatchDelete = async () => {
|
||||
const data = { [this.props.keyValue]: this.state.selectedRowKeys };
|
||||
this.setState({ selectedRowKeys: [] });
|
||||
|
||||
try {
|
||||
// await API_UNI_OIL.delete(this.props.url.apiDelete, { data });
|
||||
// this.handleFilterChange({});
|
||||
// message.success('Record was successfully deleted.');
|
||||
console.log(this.props.url.apiDelete)
|
||||
} catch ({ response: error }) {
|
||||
this.handleFilterChange({});
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: (
|
||||
<div>
|
||||
<div>Something went wrong deleting records.</div>
|
||||
- {error && error.data && error.data.message}
|
||||
</div>
|
||||
),
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onSelectChange = (selectedRowKeys) => {
|
||||
this.setState({ selectedRowKeys });
|
||||
};
|
||||
|
||||
handleDateRangePicker = async (date, dateString) => {
|
||||
this.handleFilterChange({
|
||||
date_start: dateString[0],
|
||||
date_end: dateString[1],
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
if (!this.state.mounted) return null;
|
||||
const { loading, selectedRowKeys } = this.state;
|
||||
const rowSelection = {
|
||||
selectedRowKeys,
|
||||
onChange: this.onSelectChange,
|
||||
getCheckboxProps: (record) => ({
|
||||
disabled: record.editable == false, // Column configuration not to be checked
|
||||
//name: record.name,
|
||||
}),
|
||||
};
|
||||
const hasSelected = selectedRowKeys.length > 0;
|
||||
|
||||
let { history, keyValue, location, url: { apiDelete } } = this.props;
|
||||
|
||||
let { search } = this.props.location;
|
||||
let urlParamsObject = queryString.parse(search);
|
||||
let { _sort_order } = urlParamsObject;
|
||||
if (_sort_order) _sort_order = _sort_order === 'asc' ? 'ascend' : 'descend';
|
||||
|
||||
const columns = this.props.columns.map((data) => {
|
||||
if (data.dataIndex === 'action') {
|
||||
return {
|
||||
...data,
|
||||
render: (text, record) =>
|
||||
data.buttons.map((action) => {
|
||||
let actionBtn;
|
||||
if(action.key == 'location'){
|
||||
actionBtn = () => this.props.locationData(record)
|
||||
}
|
||||
if(action.key == 'edit'){
|
||||
actionBtn = () => history.push({ pathname: `${location.pathname}/view/${record.id}` });
|
||||
}
|
||||
if (action.key == 'delete') {
|
||||
actionBtn = action.action;
|
||||
if (record.editable == false) {
|
||||
return;
|
||||
} else {
|
||||
return (
|
||||
<Popconfirm
|
||||
placement='bottomRight'
|
||||
key={action.key}
|
||||
title={'Are you sure you want to delete this record?'}
|
||||
onConfirm={() => this.delete(record.id)}
|
||||
okText='Yes'
|
||||
cancelText='No'
|
||||
icon={<Icon type='close-circle' />}
|
||||
>
|
||||
<Tooltip key={action.key} placement='top' title={action.title}>
|
||||
<Icon
|
||||
type={action.icon}
|
||||
style={{
|
||||
padding: '5px 14px 5px 0',
|
||||
color: 'rgb(231, 70, 16)',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Popconfirm>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip key={action.key} placement='top' title={action.title}>
|
||||
<Icon
|
||||
type={action.icon}
|
||||
style={{
|
||||
padding: '5px 14px 5px 0',
|
||||
color: 'rgb(231, 70, 16)',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={actionBtn}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
}),
|
||||
};
|
||||
}
|
||||
let filteredValue = null;
|
||||
if (Array.isArray(urlParamsObject[data.dataIndex])) {
|
||||
filteredValue = urlParamsObject[data.dataIndex];
|
||||
} else if (urlParamsObject[data.dataIndex]) {
|
||||
filteredValue = [ urlParamsObject[data.dataIndex] ];
|
||||
}
|
||||
|
||||
return {
|
||||
...data,
|
||||
filteredValue,
|
||||
sortOrder: data.sorter ? urlParamsObject._sort_by === data.dataIndex && _sort_order : null,
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<div style={{ margin: '0 24px', padding: '24px 0' }}>
|
||||
<Row type='flex' justify='space-between' align='bottom' style={{ paddingBottom: 25 }}>
|
||||
<Col>
|
||||
{this.props.url.csv ? (
|
||||
<RangePicker onChange={this.handleDateRangePicker} />
|
||||
) : (
|
||||
<Input
|
||||
onChange={this.handleSearchChange}
|
||||
style={{ width: 300 }}
|
||||
value={this.state.search_filter}
|
||||
prefix={<Icon type='search' style={{ color: 'rgba(0,0,0,.25)' }} />}
|
||||
type='text'
|
||||
placeholder='Search'
|
||||
/>
|
||||
)}
|
||||
</Col>
|
||||
<Col className='table-operations'>
|
||||
{/* <Button onClick = {this.clearFilters}><b>Clear filters</b></Button>*/}
|
||||
<Button onClick={this.clearAll}>Clear filters</Button>
|
||||
{this.props.url.csv && <DropdownExport defaultFilter={this.props.defaultFilter} url={this.props.url.csv} />}
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Table
|
||||
size='middle'
|
||||
rowSelection={apiDelete && rowSelection}
|
||||
columns={columns}
|
||||
dataSource={this.state.data ? this.state.data : null}
|
||||
pagination={false}
|
||||
rowKey={(record) => record[this.props.keyValue]}
|
||||
onChange={this.handleTableChange}
|
||||
loading={loading}
|
||||
/>
|
||||
|
||||
<Row type='flex' justify='space-between' style={{ marginTop: 20 }}>
|
||||
<Col>
|
||||
{apiDelete && (
|
||||
<div>
|
||||
<Popconfirm
|
||||
placement='top'
|
||||
title={'Are you sure you want to delete this record?'}
|
||||
onConfirm={this.handleBatchDelete}
|
||||
okText='Yes'
|
||||
cancelText='No'
|
||||
icon={<Icon type='close-circle' />}
|
||||
>
|
||||
<Button type='danger' disabled={!hasSelected} icon='delete' loading={loading}>
|
||||
Delete
|
||||
</Button>
|
||||
<span style={{ marginLeft: 8 }}>
|
||||
{hasSelected ? `Selected ${selectedRowKeys.length} item(s)` : ''}
|
||||
</span>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
)}
|
||||
</Col>
|
||||
|
||||
<Col>
|
||||
{this.state.total > 0 ? (
|
||||
<Pagination
|
||||
style={{ float: 'right' }}
|
||||
showSizeChanger
|
||||
defaultCurrent={parseInt(urlParamsObject.page, 10) || 1}
|
||||
defaultPageSize={parseInt(urlParamsObject.page_size, 10) || 10}
|
||||
pageSizeOptions={[ '10','20']}
|
||||
total={this.state.total}
|
||||
showTotal={(total, range) =>
|
||||
`Showing ${this.state.total > 0 ? range[0] : 0}-${this.state.total > 0 ? range[1] : 0} of ${this.state
|
||||
.total > 0
|
||||
? total
|
||||
: 0}`}
|
||||
onChange={this.onPaginationChange}
|
||||
onShowSizeChange={this.onPaginationChange}
|
||||
/>
|
||||
) : null}
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(Index);
|
|
@ -1,17 +0,0 @@
|
|||
import React, { Fragment } from 'react';
|
||||
import { withRouter} from 'react-router-dom'
|
||||
|
||||
function Page404(){
|
||||
const error = "Page not found";
|
||||
const errorMessage = "Sorry, but the page you are looking for doesn't exist";
|
||||
|
||||
return <Fragment>
|
||||
<div align="center" style={{ marginTop: "10%" }}>
|
||||
<h1 style={{ fontSize: 150, fontWeight: 'bold', margin: 0 }}>404</h1>
|
||||
<p style={{ fontSize: 30, fontWeight: 'bold', margin: 0 }}>{error}</p>
|
||||
<p>{errorMessage}</p>
|
||||
</div>
|
||||
</Fragment>
|
||||
}
|
||||
|
||||
export default withRouter(Page404);
|
|
@ -1,18 +0,0 @@
|
|||
import React, { Fragment } from 'react';
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
function PageError(){
|
||||
const error = "Forbidden";
|
||||
const errorMessage = "Access to this resources on the server is denied!"
|
||||
|
||||
return <Fragment>
|
||||
<div align="center" style={{ marginTop: "10%" }}>
|
||||
<h1 style={{ fontSize: 150, fontWeight: 'bold', margin: 0 }}>403</h1>
|
||||
<p style={{ fontSize: 30, fontWeight: 'bold', margin: 0 }}>{error}</p>
|
||||
<p>{errorMessage}</p>
|
||||
<Link to={'/locations'}>Go Back</Link>
|
||||
</div>
|
||||
</Fragment>
|
||||
}
|
||||
|
||||
export default PageError;
|
|
@ -1,17 +0,0 @@
|
|||
import React, { Fragment } from 'react';
|
||||
import { withRouter} from 'react-router-dom'
|
||||
|
||||
function Page404(){
|
||||
const error = "Page not found";
|
||||
const errorMessage = "Sorry, but the page you are looking for doesn't exist";
|
||||
|
||||
return <Fragment>
|
||||
<div align="center">
|
||||
<h1 style={{ fontSize: 150, fontWeight: 'bold', margin: 0 }}>404</h1>
|
||||
<p style={{ fontSize: 30, fontWeight: 'bold', margin: 0 }}>{error}</p>
|
||||
<p>{errorMessage}</p>
|
||||
</div>
|
||||
</Fragment>
|
||||
}
|
||||
|
||||
export default withRouter(Page404);
|
|
@ -1,2 +0,0 @@
|
|||
export { default as PAGE403 } from "./403";
|
||||
export { default as PAGE404 } from "./404";
|
|
@ -1,445 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import queryString from 'query-string';
|
||||
import { getCookie } from '../../utils/cookie';
|
||||
|
||||
import _ from 'lodash';
|
||||
import {
|
||||
Table,
|
||||
Button,
|
||||
Row,
|
||||
Col,
|
||||
Input,
|
||||
Icon,
|
||||
Pagination,
|
||||
Tooltip,
|
||||
notification,
|
||||
Popconfirm,
|
||||
message,
|
||||
DatePicker,
|
||||
} from 'antd';
|
||||
|
||||
import { DropdownExport } from 'components/Dropdown/index';
|
||||
import { fnQueryParams } from 'utils/helper';
|
||||
import { API_UNI_OIL, API_GET, API_DELETE } from 'utils/Api';
|
||||
import { API_GET_BRANCH, API_GET_FUELS } from 'utils/StationApi';
|
||||
import '../Tables/index.css';
|
||||
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
class Index extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
data: null,
|
||||
total: null,
|
||||
loading: false,
|
||||
selectedRowKeys: [],
|
||||
columns: [],
|
||||
search_filter: '',
|
||||
visible: false,
|
||||
mounted: false,
|
||||
test: true,
|
||||
updating: false,
|
||||
};
|
||||
|
||||
this.delayFetchRequest = _.debounce(this.fetch, 500);
|
||||
this.handleSearchChangeDebounce = _.debounce(this.handleSearchStateChange, 1000);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({ mounted: true });
|
||||
this.handleFilterChange({});
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState, snapshot) {
|
||||
if (prevState.updating !== prevProps.updating) {
|
||||
this.setState({ updating: prevProps.updating });
|
||||
}
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
if (nextProps.updating !== nextState.updating) {
|
||||
this.handleFilterChange({});
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.delayFetchRequest.cancel();
|
||||
this.handleSearchChangeDebounce.cancel();
|
||||
}
|
||||
|
||||
handleTableChange = (pagination, filters, sorter) => {
|
||||
let _sort_order;
|
||||
if (sorter.order) _sort_order = sorter.order === 'ascend' ? 'asc' : 'desc';
|
||||
|
||||
if (sorter.column) {
|
||||
if (sorter.column.sortByValue) sorter.field = sorter.column.sortByValue;
|
||||
}
|
||||
|
||||
this.handleFilterChange({
|
||||
...filters,
|
||||
_sort_by: sorter.field,
|
||||
_sort_order,
|
||||
});
|
||||
};
|
||||
|
||||
handleSearchChange = (e) => {
|
||||
this.setState({ search_filter: e.target.value });
|
||||
this.handleSearchChangeDebounce(e.target.value);
|
||||
};
|
||||
|
||||
handleSearchStateChange = (search_filter) => {
|
||||
this.setState({ search_filter });
|
||||
this.handleFilterChange({ search: this.state.search_filter });
|
||||
};
|
||||
|
||||
onPaginationChange = (page, page_size) => {
|
||||
console.log(page)
|
||||
this.handleFilterChange({ page });
|
||||
};
|
||||
|
||||
handleFilterChange = (props, isClearFilter) => {
|
||||
console.log(props)
|
||||
this.setState({ loading: true });
|
||||
|
||||
let { history, location } = this.props;
|
||||
let { search, pathname } = location;
|
||||
let urlParamsObject = isClearFilter ? props : queryString.parse(search);
|
||||
urlParamsObject = props ? { ...urlParamsObject,page: 1, ...props } : {};
|
||||
urlParamsObject = fnQueryParams(urlParamsObject);
|
||||
urlParamsObject = queryString.parse(urlParamsObject);
|
||||
history.push({ pathname, search: fnQueryParams(urlParamsObject) });
|
||||
console.log({ pathname, search: fnQueryParams(urlParamsObject) })
|
||||
this.delayFetchRequest(urlParamsObject);
|
||||
};
|
||||
|
||||
clearFilters = () => {
|
||||
let { history, location } = this.props;
|
||||
let { search, pathname } = location;
|
||||
let urlParamsObject = queryString.parse(search);
|
||||
delete urlParamsObject['search'];
|
||||
Object.keys(urlParamsObject).map((key, index) => {
|
||||
if (this.props.filterValues.includes(key)) delete urlParamsObject[key];
|
||||
});
|
||||
|
||||
history.push({ pathname, search: fnQueryParams(urlParamsObject) });
|
||||
this.handleFilterChange(urlParamsObject, true);
|
||||
};
|
||||
|
||||
clearAll = () => {
|
||||
this.setState({ search_filter: '' });
|
||||
this.handleFilterChange();
|
||||
};
|
||||
|
||||
fetch = async (params = {}) => {
|
||||
let defaulUrl;
|
||||
|
||||
if (this.props.defaultFilter) {
|
||||
params = {
|
||||
...params,
|
||||
...this.props.defaultFilter,
|
||||
};
|
||||
}
|
||||
|
||||
if (this.props.url.defaultWithFilter) {
|
||||
defaulUrl = this.props.url.defaultWithFilter;
|
||||
} else {
|
||||
defaulUrl = this.props.url.default;
|
||||
}
|
||||
|
||||
try {
|
||||
let response, data, total;
|
||||
if(defaulUrl == 'branches'){
|
||||
console.log(defaulUrl, params)
|
||||
response = await API_GET_BRANCH('branches', params);
|
||||
console.log(response.data, params, 'response ng branches');
|
||||
console.log(getCookie('TOKEN').token);
|
||||
data = response.data.data.length > 0 ? response.data.data : null;
|
||||
total = response.data.total
|
||||
}
|
||||
if(defaulUrl == 'fuels'){
|
||||
console.log(defaulUrl, params)
|
||||
response = await API_GET_FUELS('fuels', params)
|
||||
console.log(response, 'fuels');
|
||||
console.log(getCookie('TOKEN').token);
|
||||
data = response.data.data.length > 0 ? response.data.data : null;
|
||||
total = response.data.total
|
||||
console.log(data, 'fuel data')
|
||||
}
|
||||
if(defaulUrl == 'location'){
|
||||
console.log(defaulUrl, params)
|
||||
response = await API_GET_BRANCH('stations', params);
|
||||
console.log(response);
|
||||
console.log(getCookie('TOKEN').token);
|
||||
data = response.data.data.length > 0 ? response.data.data : null;
|
||||
total = response.data.total
|
||||
}
|
||||
console.table(data, 'data');
|
||||
this.setState({ data, total, loading: false });
|
||||
if (data == null && this.props.isEmptyMessagePopUp) {
|
||||
message.info('No records found.');
|
||||
}
|
||||
if (this.props.dataResponse) {
|
||||
this.props.dataResponse(data.length);
|
||||
}
|
||||
} catch (error) {
|
||||
this.setState({ loading: false, total: 0 });
|
||||
console.log('An error encountered: ' + error);
|
||||
}
|
||||
};
|
||||
|
||||
update = async (params = {}) => {
|
||||
notification.success({
|
||||
message: 'Success',
|
||||
description: `Delete Successful.`,
|
||||
});
|
||||
};
|
||||
|
||||
remove = async (params = {}) => {
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: `Error message.`,
|
||||
});
|
||||
};
|
||||
|
||||
delete = async (uuid) => {
|
||||
console.log(uuid)
|
||||
let search = this.props.location;
|
||||
console.log(search.pathname)
|
||||
let api = process.env.REACT_APP_STATION_API
|
||||
let path = search.pathname.substring(1)
|
||||
try {
|
||||
await API_UNI_OIL.delete(`${api}${path}/${uuid}`);
|
||||
this.handleFilterChange({});
|
||||
message.success('Record was successfully deleted.');
|
||||
} catch ({ response: error }) {
|
||||
this.handleFilterChange({});
|
||||
notification.error({
|
||||
message: 'Something went wrong deleting record!',
|
||||
description: (
|
||||
<div>
|
||||
<h3>
|
||||
{error && error.data && error.data.message}
|
||||
</h3>
|
||||
</div>
|
||||
),
|
||||
duration: 4,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleBatchDelete = async () => {
|
||||
const data = { [this.props.keyValue]: this.state.selectedRowKeys };
|
||||
this.setState({ selectedRowKeys: [] });
|
||||
|
||||
try {
|
||||
// await API_UNI_OIL.delete(this.props.url.apiDelete, { data });
|
||||
// this.handleFilterChange({});
|
||||
// message.success('Record was successfully deleted.');
|
||||
console.log(this.props.url.apiDelete)
|
||||
} catch ({ response: error }) {
|
||||
this.handleFilterChange({});
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: (
|
||||
<div>
|
||||
<div>Something went wrong deleting records.</div>
|
||||
- {error && error.data && error.data.message}
|
||||
</div>
|
||||
),
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onSelectChange = (selectedRowKeys) => {
|
||||
this.setState({ selectedRowKeys });
|
||||
};
|
||||
|
||||
handleDateRangePicker = async (date, dateString) => {
|
||||
this.handleFilterChange({
|
||||
date_start: dateString[0],
|
||||
date_end: dateString[1],
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
if (!this.state.mounted) return null;
|
||||
const { loading, selectedRowKeys } = this.state;
|
||||
const rowSelection = {
|
||||
selectedRowKeys,
|
||||
onChange: this.onSelectChange,
|
||||
getCheckboxProps: (record) => ({
|
||||
disabled: record.editable == false, // Column configuration not to be checked
|
||||
//name: record.name,
|
||||
}),
|
||||
};
|
||||
const hasSelected = selectedRowKeys.length > 0;
|
||||
|
||||
let { history, keyValue, location, url: { apiDelete } } = this.props;
|
||||
|
||||
let { search } = this.props.location;
|
||||
let urlParamsObject = queryString.parse(search);
|
||||
let { _sort_order } = urlParamsObject;
|
||||
if (_sort_order) _sort_order = _sort_order === 'asc' ? 'ascend' : 'descend';
|
||||
|
||||
const columns = this.props.columns.map((data) => {
|
||||
if (data.dataIndex === 'action') {
|
||||
return {
|
||||
...data,
|
||||
render: (text, record) =>
|
||||
data.buttons.map((action) => {
|
||||
let actionBtn;
|
||||
if(action.key == 'location'){
|
||||
actionBtn = () => this.props.locationData(record)
|
||||
}
|
||||
if(action.key == 'edit'){
|
||||
actionBtn = () => history.push({ pathname: `${location.pathname}/view/${record.id}` });
|
||||
}
|
||||
if (action.key == 'delete') {
|
||||
actionBtn = action.action;
|
||||
if (record.editable == false) {
|
||||
return;
|
||||
} else {
|
||||
return (
|
||||
<Popconfirm
|
||||
placement='bottomRight'
|
||||
key={action.key}
|
||||
title={'Are you sure you want to delete this record?'}
|
||||
onConfirm={() => this.delete(record.id)}
|
||||
okText='Yes'
|
||||
cancelText='No'
|
||||
icon={<Icon type='close-circle' />}
|
||||
>
|
||||
<Tooltip key={action.key} placement='top' title={action.title}>
|
||||
<Icon
|
||||
type={action.icon}
|
||||
style={{
|
||||
padding: '5px 14px 5px 0',
|
||||
color: 'rgb(231, 70, 16)',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Popconfirm>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip key={action.key} placement='top' title={action.title}>
|
||||
<Icon
|
||||
type={action.icon}
|
||||
style={{
|
||||
padding: '5px 14px 5px 0',
|
||||
color: 'rgb(231, 70, 16)',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
onClick={actionBtn}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
}),
|
||||
};
|
||||
}
|
||||
let filteredValue = null;
|
||||
if (Array.isArray(urlParamsObject[data.dataIndex])) {
|
||||
filteredValue = urlParamsObject[data.dataIndex];
|
||||
} else if (urlParamsObject[data.dataIndex]) {
|
||||
filteredValue = [ urlParamsObject[data.dataIndex] ];
|
||||
}
|
||||
|
||||
return {
|
||||
...data,
|
||||
filteredValue,
|
||||
sortOrder: data.sorter ? urlParamsObject._sort_by === data.dataIndex && _sort_order : null,
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<div style={{ margin: '0 24px', padding: '24px 0' }}>
|
||||
<Row type='flex' justify='space-between' align='bottom' style={{ paddingBottom: 25 }}>
|
||||
<Col>
|
||||
{this.props.url.csv ? (
|
||||
<RangePicker onChange={this.handleDateRangePicker} />
|
||||
) : (
|
||||
<Input
|
||||
onChange={this.handleSearchChange}
|
||||
style={{ width: 300 }}
|
||||
value={this.state.search_filter}
|
||||
prefix={<Icon type='search' style={{ color: 'rgba(0,0,0,.25)' }} />}
|
||||
type='text'
|
||||
placeholder='Search'
|
||||
/>
|
||||
)}
|
||||
</Col>
|
||||
<Col className='table-operations'>
|
||||
{/* <Button onClick = {this.clearFilters}><b>Clear filters</b></Button>*/}
|
||||
<Button onClick={this.clearAll}>Clear filters</Button>
|
||||
{this.props.url.csv && <DropdownExport defaultFilter={this.props.defaultFilter} url={this.props.url.csv} />}
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Table
|
||||
size='middle'
|
||||
rowSelection={apiDelete && rowSelection}
|
||||
columns={columns}
|
||||
dataSource={this.state.data ? this.state.data : null}
|
||||
pagination={false}
|
||||
rowKey={(record) => record[this.props.keyValue]}
|
||||
onChange={this.handleTableChange}
|
||||
loading={loading}
|
||||
/>
|
||||
|
||||
<Row type='flex' justify='space-between' style={{ marginTop: 20 }}>
|
||||
<Col>
|
||||
{apiDelete && (
|
||||
<div>
|
||||
<Popconfirm
|
||||
placement='top'
|
||||
title={'Are you sure you want to delete this record?'}
|
||||
onConfirm={this.handleBatchDelete}
|
||||
okText='Yes'
|
||||
cancelText='No'
|
||||
icon={<Icon type='close-circle' />}
|
||||
>
|
||||
<Button type='danger' disabled={!hasSelected} icon='delete' loading={loading}>
|
||||
Delete
|
||||
</Button>
|
||||
<span style={{ marginLeft: 8 }}>
|
||||
{hasSelected ? `Selected ${selectedRowKeys.length} item(s)` : ''}
|
||||
</span>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
)}
|
||||
</Col>
|
||||
|
||||
<Col>
|
||||
{this.state.total > 0 ? (
|
||||
<Pagination
|
||||
style={{ float: 'right' }}
|
||||
showSizeChanger
|
||||
defaultCurrent={parseInt(urlParamsObject.page, 10) || 1}
|
||||
defaultPageSize={parseInt(urlParamsObject.page_size, 10) || 10}
|
||||
pageSizeOptions={[ '10']}
|
||||
total={this.state.total}
|
||||
showTotal={(total, range) =>
|
||||
`Showing ${this.state.total > 0 ? range[0] : 0}-${this.state.total > 0 ? range[1] : 0} of ${this.state
|
||||
.total > 0
|
||||
? total
|
||||
: 0}`}
|
||||
onChange={this.onPaginationChange}
|
||||
onShowSizeChange={this.onPaginationChange}
|
||||
/>
|
||||
) : null}
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(Index);
|
|
@ -1,324 +0,0 @@
|
|||
import React, { Component, Fragment } from 'react';
|
||||
import moment from 'moment';
|
||||
import { Table, Button, Popconfirm, Popover, message,
|
||||
Pagination, Input ,Row, Col , Select, Form, Icon,
|
||||
DatePicker, Collapse, notification } from 'antd';
|
||||
import { withRouter } from "react-router-dom";
|
||||
import queryString from 'query-string';
|
||||
|
||||
//import { fetchAllItem , jsonServerApi } from 'utils/Api';
|
||||
import { fnQueryParams } from "utils/helper";
|
||||
const Search = Input.Search;
|
||||
const RangePicker = DatePicker.RangePicker;
|
||||
const Panel = Collapse.Panel;
|
||||
|
||||
class TableLayout extends Component {
|
||||
state = {
|
||||
data: [],
|
||||
total: 0,
|
||||
loading: false,
|
||||
columns: null,
|
||||
selectedRowKeys: []
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.renderColumns();
|
||||
this.fetch();
|
||||
}
|
||||
|
||||
onPaginationChange = (page, page_size) => {
|
||||
|
||||
let _page = page, _limit = page_size;
|
||||
this.fnFilterChange({_page, _limit});
|
||||
|
||||
this.fetch({_page, _limit});
|
||||
}
|
||||
|
||||
fnFilterChange = (props) => {
|
||||
let { location, history } = this.props;
|
||||
let { pathname, search } = location;
|
||||
let values = queryString.parse(search);
|
||||
let params = { ...values, ...props };
|
||||
history.push({ pathname, search:fnQueryParams(params) });
|
||||
|
||||
}
|
||||
|
||||
fetch = async (params = {}) => {
|
||||
let values = queryString.parse(this.props.location.search); //get parameters
|
||||
if(params) {
|
||||
if(params._page) values = params;
|
||||
}
|
||||
const { api } = this.props;
|
||||
this.setState({ loading: true });
|
||||
let url = api.default;
|
||||
// let asysnData = await fetchAllItem(url, {
|
||||
// ...values
|
||||
// });
|
||||
// if(asysnData) {
|
||||
// this.setState({
|
||||
// loading: false,
|
||||
// data: asysnData.data,
|
||||
// total: asysnData.headers['x-total-count'],
|
||||
// search: values.search
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
remove = async (params={}) => {
|
||||
let { path, uuid } = params
|
||||
|
||||
try {
|
||||
// const response = await jsonServerApi.delete(`${path}/${uuid}`);
|
||||
|
||||
// if(response) {
|
||||
|
||||
// this.fetch()
|
||||
|
||||
// notification.success({
|
||||
// message: 'Success',
|
||||
// description: `Delete Successfull.`,
|
||||
// })
|
||||
// }
|
||||
} catch (error) {
|
||||
|
||||
if(error) {
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: `Error response message here.`,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
actionHandler = props => {
|
||||
let { path, uuid, action, data } = props;
|
||||
|
||||
let { history, location } = this.props;
|
||||
let { search, pathname } = location;
|
||||
if(action === 'update') {
|
||||
history.push({
|
||||
pathname: `${path}/${uuid}`,
|
||||
state: {
|
||||
initialValues: data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(action === 'delete') {
|
||||
//this.remove({path, uuid});
|
||||
}
|
||||
|
||||
if(action === 'view') {
|
||||
history.push({
|
||||
pathname: `${path}/${uuid}`,
|
||||
state: {
|
||||
prevPath:`${pathname}${search}`,
|
||||
initialValues: data
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
confirm(items,id) {
|
||||
this.remove({path: items.path, uuid: id });
|
||||
}
|
||||
|
||||
cancel(e) {
|
||||
message.error('You Click Cancel.');
|
||||
}
|
||||
|
||||
onChange = (dates, dateStrings) => {
|
||||
console.log('From: ', dates[0], ', to: ', dates[1]);
|
||||
console.log('From: ', dateStrings[0], ', to: ', dateStrings[1]);
|
||||
}
|
||||
|
||||
renderColumns = () => {
|
||||
|
||||
const { headers,actions,keyValue } = this.props;
|
||||
|
||||
let columns = headers;
|
||||
|
||||
headers.map((item, index) => {
|
||||
if(item.renderActions) {
|
||||
item['render'] = (text, record) => {
|
||||
return item.renderActions.map((itemAction,key) => {
|
||||
if(itemAction.action_name) {
|
||||
return (
|
||||
<span key={key} style={{marginRight: '10px'}}>
|
||||
{
|
||||
(itemAction.action || itemAction.action_name == "delete")
|
||||
?
|
||||
<Popconfirm
|
||||
title="Are you sure you want to delete this record?"
|
||||
content={itemAction.message}
|
||||
onConfirm={
|
||||
()=> this.confirm(itemAction, record[keyValue])
|
||||
}
|
||||
onCancel={()=> this.cancel()} okText="Yes" cancelText="Cancel"
|
||||
>
|
||||
<Button
|
||||
icon={itemAction.icon}
|
||||
type="danger"
|
||||
>
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
:
|
||||
<Popover
|
||||
title={itemAction.action_name}
|
||||
content={itemAction.action_message}
|
||||
trigger="hover"
|
||||
>
|
||||
<Button
|
||||
onClick={
|
||||
()=> this.actionHandler({
|
||||
path: itemAction.path,
|
||||
uuid: record[keyValue],
|
||||
action: itemAction.action_name,
|
||||
data: record
|
||||
})
|
||||
}
|
||||
icon={itemAction.icon}
|
||||
type="primary"
|
||||
/>
|
||||
</Popover>
|
||||
}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return this.setState({ columns: columns })
|
||||
}
|
||||
|
||||
onDeleteHandler = () => {
|
||||
this.setState({ loading: true });
|
||||
// ajax request after empty completing
|
||||
|
||||
setTimeout(() => {
|
||||
|
||||
this.setState((prevState, props) => ({
|
||||
selectedRowKeys: [],
|
||||
loading: false,
|
||||
}));
|
||||
|
||||
this.fetch();
|
||||
|
||||
}, 1000);
|
||||
|
||||
|
||||
}
|
||||
|
||||
onSelectChange = (selectedRowKeys) => {
|
||||
this.setState({ selectedRowKeys });
|
||||
}
|
||||
|
||||
onFilterSearch = (val) => {
|
||||
console.log('Received values of form: ', val);
|
||||
this.fnFilterChange(val);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { keyValue,scrollbale, advanceFilter:AdvancedSearchForm } = this.props;
|
||||
const { loading,selectedRowKeys } = this.state;
|
||||
|
||||
const rowSelection = { selectedRowKeys, onChange: this.onSelectChange };
|
||||
const hasSelected = selectedRowKeys.length > 0;
|
||||
// VALUES FROM PARAMS URL
|
||||
let values = queryString.parse(this.props.location.search);
|
||||
return (
|
||||
|
||||
<Fragment>
|
||||
|
||||
<Collapse style={{marginBottom: 16}}>
|
||||
<Panel header="Advance Filter" key="1">
|
||||
<Collapse defaultActiveKey="1" style={{padding: 16}}>
|
||||
<AdvancedSearchForm onSubmit={this.onFilterSearch}/>
|
||||
</Collapse>
|
||||
</Panel>
|
||||
</Collapse>
|
||||
|
||||
<Row gutter={16}>
|
||||
|
||||
<Col span={8} >
|
||||
<h5>Date Range :</h5>
|
||||
<RangePicker
|
||||
ranges={{ Today: [moment(), moment()], 'This Month': [moment(), moment().endOf('month')] }}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={8} >
|
||||
<h5>Date</h5>
|
||||
<DatePicker onChange={this.onChange} />
|
||||
</Col>
|
||||
|
||||
|
||||
|
||||
<Col span={8} offset={16} style={{marginBottom: 16}}>
|
||||
<span>Search :</span>
|
||||
<Search
|
||||
defaultValue={values.search}
|
||||
onSearch={(val)=> this.fnFilterChange({search: val})}
|
||||
placeholder="Input search text"
|
||||
enterButton="Search"
|
||||
label={'Search'}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<div style={{ marginBottom: 16, marginTop: 16 }}>
|
||||
<Button
|
||||
type="danger"
|
||||
onClick={this.onDeleteHandler}
|
||||
disabled={!hasSelected}
|
||||
icon="delete"
|
||||
loading={loading}
|
||||
>
|
||||
Delete All
|
||||
</Button>
|
||||
<span style={{ marginLeft: 8 }}>
|
||||
{hasSelected ? `Selected ${selectedRowKeys.length} items` : ''}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
columns={this.state.columns}
|
||||
dataSource={this.state.data}
|
||||
rowKey={record => record[keyValue]}
|
||||
pagination={false}
|
||||
loading={this.state.loading}
|
||||
rowSelection={rowSelection}
|
||||
scroll={scrollbale ? scrollbale : {x: 0, y: 0}}
|
||||
/>
|
||||
|
||||
{
|
||||
this.state.total > 0
|
||||
?
|
||||
<Pagination
|
||||
style={{float: 'right' , marginTop: 16}}
|
||||
showSizeChanger
|
||||
showQuickJumper
|
||||
defaultCurrent={parseInt(values._page) || 1}
|
||||
defaultPageSize={parseInt(values._limit) || 10}
|
||||
pageSizeOptions={['5','10','15','20']}
|
||||
total={parseInt(this.state.total)}
|
||||
showTotal={(total, range) => `${range[0]}-${range[1]} of ${total} items`}
|
||||
onChange={this.onPaginationChange}
|
||||
onShowSizeChange={this.onPaginationChange}
|
||||
/>
|
||||
: null
|
||||
}
|
||||
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default withRouter(TableLayout);
|
||||
|
|
@ -1,427 +0,0 @@
|
|||
import React, { Component } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import queryString from 'query-string';
|
||||
import { getCookie } from '../../utils/cookie';
|
||||
|
||||
import _ from 'lodash';
|
||||
import {
|
||||
Table,
|
||||
Button,
|
||||
Row,
|
||||
Col,
|
||||
Input,
|
||||
Icon,
|
||||
Pagination,
|
||||
Tooltip,
|
||||
notification,
|
||||
Popconfirm,
|
||||
message,
|
||||
DatePicker,
|
||||
} from 'antd';
|
||||
|
||||
import { DropdownExport } from 'components/Dropdown/index';
|
||||
import { fnQueryParams } from 'utils/helper';
|
||||
import { API_UNI_OIL, API_GET, API_DELETE } from 'utils/Api';
|
||||
import { API_GET_NOTIF, API_CREATE_NOTIF } from 'utils/NotificationApi';
|
||||
import './index.css';
|
||||
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
class AdvanceTable extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
data: null,
|
||||
total: null,
|
||||
loading: false,
|
||||
selectedRowKeys: [],
|
||||
columns: [],
|
||||
search_filter: '',
|
||||
mounted: false,
|
||||
test: true,
|
||||
updating: false,
|
||||
};
|
||||
|
||||
this.delayFetchRequest = _.debounce(this.fetch, 500);
|
||||
this.handleSearchChangeDebounce = _.debounce(this.handleSearchStateChange, 1000);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({ mounted: true });
|
||||
this.handleFilterChange({});
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState, snapshot) {
|
||||
if (prevState.updating !== prevProps.updating) {
|
||||
this.setState({ updating: prevProps.updating });
|
||||
}
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
if (nextProps.updating !== nextState.updating) {
|
||||
this.handleFilterChange({});
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.delayFetchRequest.cancel();
|
||||
this.handleSearchChangeDebounce.cancel();
|
||||
}
|
||||
|
||||
handleTableChange = (pagination, filters, sorter) => {
|
||||
let _sort_order;
|
||||
if (sorter.order) _sort_order = sorter.order === 'ascend' ? 'asc' : 'desc';
|
||||
|
||||
if (sorter.column) {
|
||||
if (sorter.column.sortByValue) sorter.field = sorter.column.sortByValue;
|
||||
}
|
||||
|
||||
this.handleFilterChange({
|
||||
...filters,
|
||||
_sort_by: sorter.field,
|
||||
_sort_order,
|
||||
});
|
||||
};
|
||||
|
||||
handleSearchChange = (e) => {
|
||||
this.setState({ search_filter: e.target.value });
|
||||
this.handleSearchChangeDebounce(e.target.value);
|
||||
};
|
||||
|
||||
handleSearchStateChange = (search_filter) => {
|
||||
this.setState({ search_filter });
|
||||
this.handleFilterChange({ _search: this.state.search_filter });
|
||||
};
|
||||
|
||||
onPaginationChange = (page, page_size) => {
|
||||
this.handleFilterChange({ page, page_size });
|
||||
};
|
||||
|
||||
handleFilterChange = (props, isClearFilter) => {
|
||||
this.setState({ loading: true });
|
||||
console.log(props)
|
||||
let { history, location } = this.props;
|
||||
let { search, pathname } = location;
|
||||
let urlParamsObject = isClearFilter ? props : queryString.parse(search);
|
||||
urlParamsObject = props ? { ...urlParamsObject, page: 1, ...props } : {};
|
||||
urlParamsObject = fnQueryParams(urlParamsObject);
|
||||
urlParamsObject = queryString.parse(urlParamsObject);
|
||||
history.push({ pathname, search: fnQueryParams(urlParamsObject) });
|
||||
this.delayFetchRequest(urlParamsObject);
|
||||
};
|
||||
|
||||
clearFilters = () => {
|
||||
let { history, location } = this.props;
|
||||
let { search, pathname } = location;
|
||||
let urlParamsObject = queryString.parse(search);
|
||||
delete urlParamsObject['_search'];
|
||||
Object.keys(urlParamsObject).map((key, index) => {
|
||||
if (this.props.filterValues.includes(key)) delete urlParamsObject[key];
|
||||
});
|
||||
|
||||
history.push({ pathname, search: fnQueryParams(urlParamsObject) });
|
||||
this.handleFilterChange(urlParamsObject, true);
|
||||
};
|
||||
|
||||
clearAll = () => {
|
||||
this.setState({ search_filter: '' });
|
||||
this.handleFilterChange();
|
||||
};
|
||||
|
||||
fetch = async (params = {}) => {
|
||||
let defaulUrl;
|
||||
|
||||
if (this.props.defaultFilter) {
|
||||
params = {
|
||||
...params,
|
||||
...this.props.defaultFilter,
|
||||
};
|
||||
}
|
||||
|
||||
if (this.props.url.defaultWithFilter) {
|
||||
defaulUrl = this.props.url.defaultWithFilter;
|
||||
} else {
|
||||
defaulUrl = this.props.url.default;
|
||||
}
|
||||
|
||||
try {
|
||||
let response, data, total;
|
||||
if(defaulUrl == 'notifications'){
|
||||
response = await API_GET_NOTIF(defaulUrl, params);
|
||||
console.log(response, 'response');
|
||||
console.log(getCookie('TOKEN').token);
|
||||
data = response.data.length > 0 ? response.data : null;
|
||||
total = response.data.length > 0 ? response.data.total : 0;
|
||||
}
|
||||
else {
|
||||
response = await API_GET(defaulUrl, params);
|
||||
console.log(response, 'response');
|
||||
console.log(getCookie('TOKEN').token);
|
||||
data = response.data.data.length > 0 ? response.data.data : null;
|
||||
total = response.data.data.length > 0 ? response.data.data.total : 0;
|
||||
}
|
||||
|
||||
|
||||
console.table(data, 'data');
|
||||
// console.table(total, 'total');
|
||||
this.setState({ data, total, loading: false });
|
||||
if (data == null && this.props.isEmptyMessagePopUp) {
|
||||
message.info('No records found.');
|
||||
}
|
||||
if (this.props.dataResponse) {
|
||||
this.props.dataResponse(data.length);
|
||||
}
|
||||
} catch (error) {
|
||||
this.setState({ loading: false, total: 0 });
|
||||
console.log('An error encountered: ' + error);
|
||||
}
|
||||
};
|
||||
|
||||
update = async (params = {}) => {
|
||||
notification.success({
|
||||
message: 'Success',
|
||||
description: `Delete Successful.`,
|
||||
});
|
||||
};
|
||||
|
||||
remove = async (params = {}) => {
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: `Error message.`,
|
||||
});
|
||||
};
|
||||
|
||||
delete = async (uuid) => {
|
||||
try {
|
||||
await API_UNI_OIL.delete(`${this.props.url.default}/${uuid}`);
|
||||
this.handleFilterChange({});
|
||||
message.success('Record was successfully deleted.');
|
||||
} catch ({ response: error }) {
|
||||
this.handleFilterChange({});
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: (
|
||||
<div>
|
||||
<div>Something went wrong deleting record.</div>
|
||||
- {error && error.data && error.data.message}
|
||||
</div>
|
||||
),
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleBatchDelete = async () => {
|
||||
const data = { [this.props.keyValue]: this.state.selectedRowKeys };
|
||||
this.setState({ selectedRowKeys: [] });
|
||||
|
||||
try {
|
||||
await API_UNI_OIL.delete(this.props.url.apiDelete, { data });
|
||||
this.handleFilterChange({});
|
||||
message.success('Record was successfully deleted.');
|
||||
} catch ({ response: error }) {
|
||||
this.handleFilterChange({});
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: (
|
||||
<div>
|
||||
<div>Something went wrong deleting records.</div>
|
||||
- {error && error.data && error.data.message}
|
||||
</div>
|
||||
),
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onSelectChange = (selectedRowKeys) => {
|
||||
this.setState({ selectedRowKeys });
|
||||
};
|
||||
|
||||
handleDateRangePicker = async (date, dateString) => {
|
||||
this.handleFilterChange({
|
||||
date_start: dateString[0],
|
||||
date_end: dateString[1],
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
if (!this.state.mounted) return null;
|
||||
const { loading, selectedRowKeys } = this.state;
|
||||
const rowSelection = {
|
||||
selectedRowKeys,
|
||||
onChange: this.onSelectChange,
|
||||
getCheckboxProps: (record) => ({
|
||||
disabled: record.editable == false, // Column configuration not to be checked
|
||||
//name: record.name,
|
||||
}),
|
||||
};
|
||||
const hasSelected = selectedRowKeys.length > 0;
|
||||
|
||||
let { history, keyValue, location, url: { apiDelete } } = this.props;
|
||||
|
||||
let { search } = this.props.location;
|
||||
let urlParamsObject = queryString.parse(search);
|
||||
let { _sort_order } = urlParamsObject;
|
||||
if (_sort_order) _sort_order = _sort_order === 'asc' ? 'ascend' : 'descend';
|
||||
|
||||
const columns = this.props.columns.map((data) => {
|
||||
if (data.dataIndex === 'action') {
|
||||
return {
|
||||
...data,
|
||||
render: (text, record) =>
|
||||
data.buttons.map((action) => {
|
||||
let actionBtn;
|
||||
|
||||
if (action.key == 'edit')
|
||||
actionBtn = () => history.push({ pathname: `${location.pathname}/edit/${record[keyValue]}` });
|
||||
if (action.key == 'view')
|
||||
actionBtn = () => history.push({ pathname: `${location.pathname}/view/${record[keyValue]}` });
|
||||
if (action.key == 'delete') {
|
||||
actionBtn = action.action;
|
||||
|
||||
if (record.editable == false) {
|
||||
return;
|
||||
} else {
|
||||
return (
|
||||
<Popconfirm
|
||||
placement='bottomRight'
|
||||
key={action.key}
|
||||
title={'Are you sure you want to delete this record?'}
|
||||
onConfirm={() => this.delete(record[keyValue])}
|
||||
okText='Yes'
|
||||
cancelText='No'
|
||||
icon={<Icon type='close-circle' />}
|
||||
>
|
||||
<Tooltip key={action.key} placement='top' title={action.title}>
|
||||
<Icon
|
||||
type={action.icon}
|
||||
style={{
|
||||
padding: '5px 14px 5px 0',
|
||||
color: 'rgb(231, 70, 16)',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Popconfirm>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip key={action.key} placement='top' title={action.title}>
|
||||
<Icon
|
||||
type={action.icon}
|
||||
style={{
|
||||
padding: '5px 14px 5px 0',
|
||||
color: 'rgb(231, 70, 16)',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
//onClick={ this.update }
|
||||
onClick={actionBtn}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
}),
|
||||
};
|
||||
}
|
||||
let filteredValue = null;
|
||||
if (Array.isArray(urlParamsObject[data.dataIndex])) {
|
||||
filteredValue = urlParamsObject[data.dataIndex];
|
||||
} else if (urlParamsObject[data.dataIndex]) {
|
||||
filteredValue = [ urlParamsObject[data.dataIndex] ];
|
||||
}
|
||||
|
||||
return {
|
||||
...data,
|
||||
filteredValue,
|
||||
sortOrder: data.sorter ? urlParamsObject._sort_by === data.dataIndex && _sort_order : null,
|
||||
};
|
||||
});
|
||||
|
||||
return (
|
||||
<div style={{ margin: '0 24px', padding: '24px 0' }}>
|
||||
<Row type='flex' justify='space-between' align='bottom' style={{ paddingBottom: 25 }}>
|
||||
<Col>
|
||||
{this.props.url.csv ? (
|
||||
<RangePicker onChange={this.handleDateRangePicker} />
|
||||
) : (
|
||||
<Input
|
||||
onChange={this.handleSearchChange}
|
||||
style={{ width: 300 }}
|
||||
value={this.state.search_filter}
|
||||
prefix={<Icon type='search' style={{ color: 'rgba(0,0,0,.25)' }} />}
|
||||
type='text'
|
||||
placeholder='Search'
|
||||
/>
|
||||
)}
|
||||
</Col>
|
||||
<Col className='table-operations'>
|
||||
{/* <Button onClick = {this.clearFilters}><b>Clear filters</b></Button>*/}
|
||||
<Button onClick={this.clearAll}>Clear filters</Button>
|
||||
{this.props.url.csv && <DropdownExport defaultFilter={this.props.defaultFilter} url={this.props.url.csv} />}
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Table
|
||||
size='middle'
|
||||
rowSelection={apiDelete && rowSelection}
|
||||
columns={columns}
|
||||
dataSource={this.state.data ? this.state.data : null}
|
||||
pagination={false}
|
||||
rowKey={(record) => record[this.props.keyValue]}
|
||||
onChange={this.handleTableChange}
|
||||
loading={loading}
|
||||
/>
|
||||
|
||||
<Row type='flex' justify='space-between' style={{ marginTop: 20 }}>
|
||||
<Col>
|
||||
{apiDelete && (
|
||||
<div>
|
||||
<Popconfirm
|
||||
placement='top'
|
||||
title={'Are you sure you want to delete this record?'}
|
||||
onConfirm={this.handleBatchDelete}
|
||||
okText='Yes'
|
||||
cancelText='No'
|
||||
icon={<Icon type='close-circle' />}
|
||||
>
|
||||
<Button type='danger' disabled={!hasSelected} icon='delete' loading={loading}>
|
||||
Delete
|
||||
</Button>
|
||||
<span style={{ marginLeft: 8 }}>
|
||||
{hasSelected ? `Selected ${selectedRowKeys.length} item(s)` : ''}
|
||||
</span>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
)}
|
||||
</Col>
|
||||
|
||||
<Col>
|
||||
{this.state.total > 0 ? (
|
||||
<Pagination
|
||||
style={{ float: 'right' }}
|
||||
showSizeChanger
|
||||
defaultCurrent={parseInt(urlParamsObject.page, 10) || 1}
|
||||
defaultPageSize={parseInt(urlParamsObject.page_size, 10) || 10}
|
||||
pageSizeOptions={[ '10', '50', '100' ]}
|
||||
total={this.state.total}
|
||||
showTotal={(total, range) =>
|
||||
`Showing ${this.state.total > 0 ? range[0] : 0}-${this.state.total > 0 ? range[1] : 0} of ${this.state
|
||||
.total > 0
|
||||
? total
|
||||
: 0}`}
|
||||
onChange={this.onPaginationChange}
|
||||
onShowSizeChange={this.onPaginationChange}
|
||||
/>
|
||||
) : null}
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(AdvanceTable);
|
|
@ -1,4 +0,0 @@
|
|||
.table-operations > button {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
const RESPONSE = {
|
||||
HTTP_CONTINUE: 100,
|
||||
HTTP_SWITCHING_PROTOCOLS: 101,
|
||||
HTTP_PROCESSING: 102,
|
||||
HTTP_EARLY_HINTS: 103,
|
||||
HTTP_OK: 200,
|
||||
HTTP_CREATED: 201,
|
||||
HTTP_ACCEPTED: 202,
|
||||
HTTP_NON_AUTHORITATIVE_INFORMATION: 203,
|
||||
HTTP_NO_CONTENT: 204,
|
||||
HTTP_RESET_CONTENT: 205,
|
||||
HTTP_PARTIAL_CONTENT: 206,
|
||||
HTTP_MULTI_STATUS: 207,
|
||||
HTTP_ALREADY_REPORTED: 208,
|
||||
HTTP_IM_USED: 226,
|
||||
HTTP_MULTIPLE_CHOICES: 300,
|
||||
HTTP_MOVED_PERMANENTLY: 301,
|
||||
HTTP_FOUND: 302,
|
||||
HTTP_SEE_OTHER: 303,
|
||||
HTTP_NOT_MODIFIED: 304,
|
||||
HTTP_USE_PROXY: 305,
|
||||
HTTP_RESERVED: 306,
|
||||
HTTP_TEMPORARY_REDIRECT: 307,
|
||||
HTTP_PERMANENTLY_REDIRECT: 308,
|
||||
HTTP_BAD_REQUEST: 400,
|
||||
HTTP_UNAUTHORIZED: 401,
|
||||
HTTP_PAYMENT_REQUIRED: 402,
|
||||
HTTP_FORBIDDEN: 403,
|
||||
HTTP_NOT_FOUND: 404,
|
||||
HTTP_METHOD_NOT_ALLOWED: 405,
|
||||
HTTP_NOT_ACCEPTABLE: 406,
|
||||
HTTP_PROXY_AUTHENTICATION_REQUIRED: 407,
|
||||
HTTP_REQUEST_TIMEOUT: 408,
|
||||
HTTP_CONFLICT: 409,
|
||||
HTTP_GONE: 410,
|
||||
HTTP_LENGTH_REQUIRED: 411,
|
||||
HTTP_PRECONDITION_FAILED: 412,
|
||||
HTTP_REQUEST_ENTITY_TOO_LARGE: 413,
|
||||
HTTP_REQUEST_URI_TOO_LONG: 414,
|
||||
HTTP_UNSUPPORTED_MEDIA_TYPE: 415,
|
||||
HTTP_REQUESTED_RANGE_NOT_SATISFIABLE: 416,
|
||||
HTTP_EXPECTATION_FAILED: 417,
|
||||
HTTP_I_AM_A_TEAPOT: 418,
|
||||
HTTP_MISDIRECTED_REQUEST: 421,
|
||||
HTTP_UNPROCESSABLE_ENTITY: 422,
|
||||
HTTP_LOCKED: 423,
|
||||
HTTP_FAILED_DEPENDENCY: 424,
|
||||
HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL: 425,
|
||||
HTTP_UPGRADE_REQUIRED: 426,
|
||||
HTTP_PRECONDITION_REQUIRED: 428,
|
||||
HTTP_TOO_MANY_REQUESTS: 429,
|
||||
HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
|
||||
HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: 451,
|
||||
HTTP_INTERNAL_SERVER_ERROR: 500,
|
||||
HTTP_NOT_IMPLEMENTED: 501,
|
||||
HTTP_BAD_GATEWAY: 502,
|
||||
HTTP_SERVICE_UNAVAILABLE: 503,
|
||||
HTTP_GATEWAY_TIMEOUT: 504,
|
||||
HTTP_VERSION_NOT_SUPPORTED: 505,
|
||||
HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL: 506,
|
||||
HTTP_INSUFFICIENT_STORAGE: 507,
|
||||
HTTP_LOOP_DETECTED: 508,
|
||||
HTTP_NOT_EXTENDED: 510,
|
||||
HTTP_NETWORK_AUTHENTICATION_REQUIRED: 511,
|
||||
}
|
||||
|
||||
export default RESPONSE;
|
|
@ -1,8 +0,0 @@
|
|||
export const LOGOUT = 'LOGOUT'
|
||||
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS'
|
||||
export const LOGOUT_RESET = 'LOGOUT_RESET'
|
||||
|
||||
export const FETCH_DATA = 'FETCH_DATA'
|
||||
export const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS'
|
||||
export const FETCH_DATA_ERROR = 'FETCH_DATA_ERROR'
|
||||
export const FETCH_DATA_RESET = 'FETCH_DATA_RESET'
|
|
@ -1,5 +0,0 @@
|
|||
const global = {
|
||||
loadingTime: 3000
|
||||
}
|
||||
|
||||
export default global;
|
|
@ -1,71 +0,0 @@
|
|||
export const required = value => (value ? undefined : 'This is a required field.');
|
||||
export const dropdownRequired = value =>
|
||||
value === null || value === undefined
|
||||
? 'This is a required field.'
|
||||
: undefined;
|
||||
export const requiredAtleastOne = value => (value ? undefined : 'At least one must be selected.');
|
||||
export const arrayChecker = value => (value && value.length > 0 ? undefined : 'This is a required field.');
|
||||
export const email = value =>
|
||||
value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)
|
||||
? 'Please provide a valid email address.'
|
||||
: undefined;
|
||||
|
||||
export const alphaNumeric = value =>
|
||||
value && /[^a-zA-Z0-9 ]/i.test(value)
|
||||
? 'Only alphanumeric characters'
|
||||
: undefined;
|
||||
|
||||
const length = size => value =>
|
||||
value && value.length !== size
|
||||
? `Must be ${size} characters.`
|
||||
: undefined;
|
||||
export const length4 = length(4);
|
||||
export const length10 = length(10);
|
||||
export const length11 = length(11);
|
||||
export const length12 = length(12);
|
||||
export const length13 = length(13);
|
||||
|
||||
const minLength = min => value =>
|
||||
value && value.length < min
|
||||
? `Must be ${min} characters or more`
|
||||
: undefined;
|
||||
export const minLength2 = minLength(2)
|
||||
|
||||
const maxLength = max => value =>
|
||||
value && value.length > max
|
||||
? `Must be ${max} characters or less.`
|
||||
: undefined;
|
||||
export const maxLength5 = maxLength(5);
|
||||
export const maxLength10 = maxLength(10);
|
||||
export const maxLength15 = maxLength(15);
|
||||
|
||||
export const numbers = value =>
|
||||
value && !/^[0-9]*$/i.test(value)
|
||||
? 'Must be whole numbers only.'
|
||||
: undefined;
|
||||
|
||||
export const numbersWithDecimals = value =>
|
||||
value && !/^\d+(\.\d{1,2})?$/i.test(value)
|
||||
? 'Must be a valid number with two (2) decimals only.'
|
||||
: undefined;
|
||||
|
||||
const minValue = min => value =>
|
||||
value && parseFloat(value.toString().replace(/,/g, '')) <= min
|
||||
? `Must be greater than ${min}.`
|
||||
: undefined;
|
||||
export const minValue0 = minValue(0);
|
||||
|
||||
const minAllowableValue = min => value =>
|
||||
value && parseFloat(value.toString().replace(/,/g, '')) < min
|
||||
? `Must be greater than ${min}.`
|
||||
: undefined;
|
||||
|
||||
export const minAllowableValue0 = minAllowableValue(0)
|
||||
|
||||
const maxValue = max => value =>
|
||||
value && parseFloat(value.toString().replace(/,/g, '')) >= max
|
||||
? `Must be less than ${max}.`
|
||||
: undefined;
|
||||
|
||||
export const maxValue1M = maxValue(1000000)
|
||||
export const maxValue100 = maxValue(100)
|
|
@ -1,205 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React from 'react';
|
||||
import { Row, Button, Col } from 'antd';
|
||||
import { Form, Field } from 'formik';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
import { Inputs, Checkbox, Radio, UploadImage, InputTextArea, SingleUploadImage } from 'components/Forms';
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 10 },
|
||||
},
|
||||
};
|
||||
|
||||
function AddCardForm(props) {
|
||||
const {
|
||||
isSubmitting,
|
||||
handleSubmit,
|
||||
loading,
|
||||
handleFileUpload,
|
||||
handleFileUploadBackground,
|
||||
history
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Form noValidate>
|
||||
<HeaderForm
|
||||
isInsideForm
|
||||
loading={loading}
|
||||
disabled={props.isValid == false ? true : false}
|
||||
title="Card Types"
|
||||
action={handleSubmit}
|
||||
actionBtnName="Submit"
|
||||
withCancelConfirm={{ message: 'Are you sure you want to discard changes?'}}
|
||||
cancel={()=> {history.push("/about-us/card-types")}}
|
||||
cancelBtnName="Cancel"
|
||||
/>
|
||||
<Field
|
||||
name="code"
|
||||
type="text"
|
||||
//icon="user"
|
||||
layout={formItemLayout}
|
||||
label="Card Code"
|
||||
placeholder="Card Code"
|
||||
component={Inputs}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="type"
|
||||
type="text"
|
||||
//icon="user"
|
||||
layout={formItemLayout}
|
||||
label="Card Type Description"
|
||||
placeholder="Card Type Description"
|
||||
component={Inputs}
|
||||
/>
|
||||
|
||||
<Field
|
||||
onCountText
|
||||
charsperpage={140}
|
||||
maxLength="140"
|
||||
style={{marginBottom: '10px'}}
|
||||
name="description"
|
||||
type="text"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
label="Card Type Short Description"
|
||||
placeholder="Card Type Short Description"
|
||||
rows={4}
|
||||
component={InputTextArea}
|
||||
/>
|
||||
|
||||
<Field
|
||||
limit100kb
|
||||
name="image"
|
||||
type="file"
|
||||
accept=".jpg , .png, .gif"
|
||||
notAcceptedImg={["image/gif"]}
|
||||
multiple={false}
|
||||
imageUrl={props.values.image && `${props.values.image}`}
|
||||
className="upload-list-inline"
|
||||
icon="user"
|
||||
layout={formItemLayout}
|
||||
label="Upload Card Type Image"
|
||||
placeholder="Upload Card Type Image"
|
||||
component={SingleUploadImage}
|
||||
imgWidth="294px"
|
||||
handleFileUpload={handleFileUpload}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="virtual_card_font_color"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
optionsList={[
|
||||
{
|
||||
label: "White",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: "Black",
|
||||
value: 2,
|
||||
}
|
||||
]}
|
||||
label="Virtual Card Font Color"
|
||||
component={Radio}
|
||||
/>
|
||||
|
||||
<Field
|
||||
limit100kb
|
||||
name="bg_image"
|
||||
type="file"
|
||||
multiple={false}
|
||||
notAcceptedImg={["image/gif"]}
|
||||
isRatioMessage={{isRatioMessage: 'Image Size (ex. 375 x 260).'}}
|
||||
imageUrl={props.values.image && `${props.values.bg_image}`}
|
||||
className="upload-list-inline"
|
||||
icon="user"
|
||||
layout={formItemLayout}
|
||||
label="Upload Card Type Cover Image"
|
||||
placeholder="Upload Card Type Cover Image"
|
||||
component={SingleUploadImage}
|
||||
imgWidth="294px"
|
||||
handleFileUpload={handleFileUploadBackground}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="id_number"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
optionsList={[
|
||||
{
|
||||
label: "Yes",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: "No",
|
||||
value: 2,
|
||||
}
|
||||
]}
|
||||
label="ID Number Required?"
|
||||
component={Radio}
|
||||
/>
|
||||
|
||||
<Field
|
||||
onCountText
|
||||
charsperpage={40}
|
||||
maxLength="40"
|
||||
style={{marginBottom: '10px'}}
|
||||
disabled={props.values.id_number && props.values.id_number == 2 ? true: false}
|
||||
name="id_number_description"
|
||||
type="text"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
label="ID Number Description"
|
||||
placeholder="ID Number Description"
|
||||
rows={2}
|
||||
component={InputTextArea}
|
||||
/>
|
||||
|
||||
<h4 style={{marginLeft: '190px'}}>DATA PRIVACY</h4>
|
||||
<Field
|
||||
name="terms_and_conditions"
|
||||
type="text"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
label={`Terms & Conditions`}
|
||||
placeholder={`Terms & Conditions`}
|
||||
rows={10}
|
||||
component={InputTextArea}
|
||||
/>
|
||||
<Field
|
||||
name="faqs"
|
||||
type="text"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
label="FAQs"
|
||||
placeholder="FAQs"
|
||||
rows={10}
|
||||
component={InputTextArea}
|
||||
/>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
AddCardForm = connect(
|
||||
state => ({
|
||||
|
||||
}),
|
||||
)(AddCardForm);
|
||||
|
||||
|
||||
export default AddCardForm;
|
||||
|
|
@ -1,191 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React, { Component } from 'react'
|
||||
import { connect } from "react-redux"
|
||||
import { Formik } from 'formik'
|
||||
import { message,notification } from 'antd';
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
import AddCardForm from './components/AddCardForm'
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
import { userDetailsSchema } from './validationSchema'
|
||||
import { customAction } from "actions";
|
||||
import { API_GET, API_POST, API_UNI_OIL } from "utils/Api";
|
||||
import { apiFormValidation } from "utils/helper";
|
||||
|
||||
|
||||
class CardTypeCreate extends Component {
|
||||
state = {
|
||||
generated_password: null,
|
||||
userInfo: null,
|
||||
loading: false,
|
||||
fileUpload: null,
|
||||
fileUploadBackground: null
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
handleSubmit = async (values, actions) => {
|
||||
|
||||
const { fileUpload, fileUploadBackground } = this.state;
|
||||
const { history } = this.props;
|
||||
const { setErrors } = actions;
|
||||
|
||||
this.setState({loading: true})
|
||||
try {
|
||||
const headers = {
|
||||
'ContentType': 'multipart/form-data',
|
||||
};
|
||||
const formData = new FormData();
|
||||
|
||||
if(fileUpload) {
|
||||
fileUpload.forEach((t, i) => {
|
||||
formData.append( `image`, t.originFileObj);
|
||||
});
|
||||
}
|
||||
if(fileUploadBackground) {
|
||||
fileUploadBackground.forEach((t, i) => {
|
||||
formData.append( `bg_image`, t.originFileObj);
|
||||
});
|
||||
}
|
||||
|
||||
if(values.id_number == 1) {
|
||||
values.id_number = 1;
|
||||
if(!values.id_number_description) {
|
||||
setErrors({id_number_description: "ID Number Description is required!"})
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: <div>
|
||||
Something went wrong creating new record.
|
||||
<div>- ID Number Description is required!</div>
|
||||
</div>
|
||||
});
|
||||
return this.setState({loading: false})
|
||||
}
|
||||
} else {
|
||||
values.id_number = 0;
|
||||
}
|
||||
|
||||
if(values.virtual_card_font_color == 2) {
|
||||
values.virtual_card_font_color = 1
|
||||
} else {
|
||||
values.virtual_card_font_color = 0
|
||||
}
|
||||
|
||||
values.code && (formData.append('code', values.code));
|
||||
values.type && (formData.append('type', values.type));
|
||||
values.description && (formData.append('description', values.description));
|
||||
values.terms_and_conditions && (formData.append('terms_and_conditions', values.terms_and_conditions));
|
||||
values.faqs && (formData.append('faqs', values.faqs));
|
||||
formData.append('id_number', values.id_number);
|
||||
formData.append('id_number_description', values.id_number_description);
|
||||
formData.append('virtual_card_font_color', values.virtual_card_font_color);
|
||||
let response = await API_UNI_OIL.post('cardType', formData , headers)
|
||||
|
||||
if(response) {
|
||||
message.success('New record added.');
|
||||
this.setState({loading: false})
|
||||
history.push({ pathname: "/about-us/card-types" })
|
||||
}
|
||||
|
||||
} catch ({response: error}) {
|
||||
if (error.status === 422) {
|
||||
apiFormValidation({ data: error.data.data, setErrors });
|
||||
}
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: <div>
|
||||
Something went wrong creating new record.
|
||||
{ error && error.data && error.data.data && error.data.data.image
|
||||
&& (<div>- {error.data.data.image[0]} </div>) }
|
||||
</div>
|
||||
});
|
||||
this.setState({loading: false})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
handleAddCardTypes =()=> {
|
||||
this.form.submitForm()
|
||||
}
|
||||
|
||||
handleFileUpload =(e)=> {
|
||||
if (Array.isArray(e)) {
|
||||
return this.setState({fileUpload: e});
|
||||
}
|
||||
return e && this.setState({fileUpload: e.fileList});
|
||||
}
|
||||
|
||||
handleFileUploadBackground =(e)=> {
|
||||
if (Array.isArray(e)) {
|
||||
return this.setState({fileUploadBackground: e});
|
||||
}
|
||||
return e && this.setState({fileUploadBackground: e.fileList});
|
||||
}
|
||||
|
||||
|
||||
|
||||
render() {
|
||||
const { userManagement } = this.props
|
||||
const { loading, isGenerated } = this.state;
|
||||
|
||||
return (
|
||||
<div style={{ border:'1px solid #E6ECF5' , paddingBottom: '10px'}}>
|
||||
{/* <HeaderForm
|
||||
loading={loading}
|
||||
title="Card Types"
|
||||
action={this.handleAddCardTypes}
|
||||
actionBtnName="Submit"
|
||||
withCancelConfirm={{ message: 'Are you sure you want to discard changes?'}}
|
||||
cancel={()=> {this.props.history.push("/about-us/card-types")}}
|
||||
cancelBtnName="Cancel"
|
||||
/> */}
|
||||
<div>
|
||||
<h2 style={{margin: '25px 35px'}}>Card Type Details</h2>
|
||||
<Formik
|
||||
initialValues={{
|
||||
code: '',
|
||||
type: '',
|
||||
description: '',
|
||||
image: '',
|
||||
terms_and_conditions: '',
|
||||
faqs: '',
|
||||
virtual_card_font_color: 1,
|
||||
bg_image: '',
|
||||
id_number: 2,
|
||||
id_number_description: '',
|
||||
}}
|
||||
ref={node => (this.form = node)}
|
||||
enableReinitialize={true}
|
||||
validationSchema={userDetailsSchema}
|
||||
onSubmit={this.handleSubmit }
|
||||
render = {(props)=>
|
||||
<AddCardForm
|
||||
{...props}
|
||||
loading={loading}
|
||||
history={this.props.history}
|
||||
handleFileUpload={this.handleFileUpload}
|
||||
handleFileUploadBackground={this.handleFileUploadBackground}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CardTypeCreate = connect(
|
||||
state => ({
|
||||
//userInfo: state
|
||||
userManagement: state.userManagement,
|
||||
}),
|
||||
{ customAction }
|
||||
)(CardTypeCreate);
|
||||
|
||||
export default CardTypeCreate;
|
|
@ -1,39 +0,0 @@
|
|||
|
||||
import * as Yup from 'yup'
|
||||
|
||||
export const userDetailsSchema = Yup.object().shape({
|
||||
code: Yup.string()
|
||||
.trim()
|
||||
.max(128, "Maximum character is 128.")
|
||||
//.max(12,"Card Code must be 20 characters only. "),
|
||||
.required('Card Code is required!'),
|
||||
type: Yup.string()
|
||||
.trim()
|
||||
.max(128, "Maximum character is 128.")
|
||||
.required('Card Type Description is required!'),
|
||||
description: Yup.string()
|
||||
.trim()
|
||||
.max(140, "Maximum character is 140.")
|
||||
.required('Card Type Short Description is required!'),
|
||||
image: Yup.string()
|
||||
.required('Upload Card Type Image is required!'),
|
||||
virtual_card_font_color: Yup.string()
|
||||
.required('Virtual Card Font Color is required!'),
|
||||
bg_image: Yup.string()
|
||||
.required('Upload Card Type Cover Image is required!'),
|
||||
terms_and_conditions: Yup.string()
|
||||
.trim()
|
||||
.max(32000, "Maximum character is 32,000.")
|
||||
.required('Terms and Condition is required!'),
|
||||
faqs: Yup.string()
|
||||
.trim()
|
||||
.max(32000, "Maximum character is 32,000.")
|
||||
.required('FAQs is required!'),
|
||||
id_number: Yup.string()
|
||||
.required('ID Number is required!'),
|
||||
id_number_description: Yup.string()
|
||||
.trim()
|
||||
.max(40, "Maximum character is 40."),
|
||||
//.required('ID Number Description is required!'),
|
||||
|
||||
})
|
|
@ -1,204 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React from 'react';
|
||||
import { Row, Button, Col } from 'antd';
|
||||
import { Form, Field } from 'formik';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
import { Inputs, Radio, InputTextArea, UploadImage,SingleUploadImage } from 'components/Forms';
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 10 },
|
||||
},
|
||||
};
|
||||
|
||||
function EditCardForm(props) {
|
||||
const {
|
||||
isSubmitting,
|
||||
loading,
|
||||
handleSubmit,
|
||||
handleFileUpload,
|
||||
history,
|
||||
handleFileUploadBackground
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Form noValidate>
|
||||
<HeaderForm
|
||||
isInsideForm
|
||||
loading={loading}
|
||||
disabled={props.isValid == false ? true : false}
|
||||
title="Update Card Type"
|
||||
action={handleSubmit}
|
||||
actionBtnName="Submit"
|
||||
withConfirm={{message: "Save changes to this record?"}}
|
||||
withCancelConfirm={{ message: 'Are you sure you want to discard changes?'}}
|
||||
cancel={()=> { history.push("/about-us/card-types")}}
|
||||
cancelBtnName="Cancel"
|
||||
/>
|
||||
<Field
|
||||
name="code"
|
||||
type="text"
|
||||
//icon="user"
|
||||
layout={formItemLayout}
|
||||
label="Card Code"
|
||||
placeholder="Card Code"
|
||||
component={Inputs}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="type"
|
||||
type="text"
|
||||
//icon="user"
|
||||
layout={formItemLayout}
|
||||
label="Card Type Description"
|
||||
placeholder="Card Type Description"
|
||||
component={Inputs}
|
||||
/>
|
||||
|
||||
<Field
|
||||
onCountText
|
||||
charsperpage={140}
|
||||
maxLength="140"
|
||||
style={{marginBottom: '10px'}}
|
||||
name="description"
|
||||
type="text"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
label="Card Type Short Description"
|
||||
placeholder="Card Type Short Description"
|
||||
rows={4}
|
||||
component={InputTextArea}
|
||||
/>
|
||||
|
||||
<Field
|
||||
limit100kb
|
||||
name="image"
|
||||
type="file"
|
||||
accept=".jpg , .png, .gif"
|
||||
notAcceptedImg={["image/gif"]}
|
||||
multiple={false}
|
||||
imageUrl={props.values.image && `${props.values.image}`}
|
||||
className="upload-list-inline"
|
||||
icon="user"
|
||||
layout={formItemLayout}
|
||||
label="Upload Card Type Image"
|
||||
placeholder="Upload Card Type Image"
|
||||
component={SingleUploadImage}
|
||||
imgWidth="294px"
|
||||
handleFileUpload={handleFileUpload}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="virtual_card_font_color"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
optionsList={[
|
||||
{
|
||||
label: "White",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: "Black",
|
||||
value: 2,
|
||||
}
|
||||
]}
|
||||
label="Virtual Card Font Color"
|
||||
component={Radio}
|
||||
/>
|
||||
|
||||
<Field
|
||||
limit100kb
|
||||
name="bg_image"
|
||||
type="file"
|
||||
multiple={false}
|
||||
notAcceptedImg={["image/gif"]}
|
||||
isRatioMessage={{isRatioMessage: 'Image Size (ex. 375 x 260).'}}
|
||||
imageUrl={props.values.image && `${props.values.bg_image}`}
|
||||
className="upload-list-inline"
|
||||
icon="user"
|
||||
layout={formItemLayout}
|
||||
label="Upload Card Type Cover Image"
|
||||
placeholder="Upload Card Type Cover Image"
|
||||
component={SingleUploadImage}
|
||||
imgWidth="294px"
|
||||
handleFileUpload={handleFileUploadBackground}
|
||||
/>
|
||||
<Field
|
||||
name="id_number"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
optionsList={[
|
||||
{
|
||||
label: "Yes",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: "No",
|
||||
value: 2,
|
||||
}
|
||||
]}
|
||||
label="ID Number Required?"
|
||||
component={Radio}
|
||||
/>
|
||||
|
||||
<Field
|
||||
onCountText
|
||||
charsperpage={40}
|
||||
maxLength="40"
|
||||
style={{marginBottom: '10px'}}
|
||||
disabled={props.values.id_number && props.values.id_number == 2 ? true: false}
|
||||
name="id_number_description"
|
||||
type="text"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
label="ID Number Description"
|
||||
placeholder="ID Number Description"
|
||||
rows={2}
|
||||
component={InputTextArea}
|
||||
/>
|
||||
|
||||
<h4 style={{marginLeft: '190px'}}>DATA PRIVACY</h4>
|
||||
<Field
|
||||
name="terms_and_conditions"
|
||||
type="text"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
label={`Terms & Conditions`}
|
||||
placeholder={`Terms & Conditions`}
|
||||
rows={10}
|
||||
component={InputTextArea}
|
||||
/>
|
||||
<Field
|
||||
name="faqs"
|
||||
type="text"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
label="FAQs"
|
||||
placeholder="FAQs"
|
||||
rows={10}
|
||||
component={InputTextArea}
|
||||
/>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
EditCardForm = connect(
|
||||
state => ({
|
||||
|
||||
}),
|
||||
)(EditCardForm);
|
||||
|
||||
|
||||
export default EditCardForm;
|
||||
|
|
@ -1,196 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React, { Component } from 'react'
|
||||
import { Formik } from 'formik'
|
||||
import { withRouter } from "react-router-dom"
|
||||
import { notification, message } from "antd"
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
import EditCardForm from './components/EditCardForm'
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
import { userDetailsSchema } from './validationSchema'
|
||||
import { API_GET, API_PUT, API_POST } from "utils/Api";
|
||||
import { API_UNI_OIL } from "utils/Api";
|
||||
import { apiFormValidation } from "utils/helper";
|
||||
|
||||
class CardTypeEdit extends Component {
|
||||
state = {
|
||||
loading: false,
|
||||
userInfo: null,
|
||||
mounted: false,
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
|
||||
const { match } = this.props;
|
||||
|
||||
try {
|
||||
let response = await API_UNI_OIL.get(`cardType/${match.params.id}`);
|
||||
this.setState({
|
||||
userInfo: {...response.data.data},
|
||||
mounted: true
|
||||
})
|
||||
} catch ({response: error}) {
|
||||
notification.error({
|
||||
message: "Error",
|
||||
description: <div>
|
||||
<div>Something went wrong loading data.</div>
|
||||
- {error && error.data && error.data.message}
|
||||
</div> ,
|
||||
duration: 3,
|
||||
});
|
||||
if(error.status == 404) {
|
||||
if(this.props.location.pathname)
|
||||
this.props.history.push(`${this.props.location.pathname}/404`); return
|
||||
}
|
||||
this.setState({ mounted: false })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handleSubmit = async (values, actions) => {
|
||||
|
||||
const { fileUpload, userInfo, fileUploadBackground } = this.state;
|
||||
const { history } = this.props;
|
||||
const { setErrors } = actions;
|
||||
|
||||
this.setState({loading: true})
|
||||
try {
|
||||
const headers = {
|
||||
'ContentType': 'multipart/form-data',
|
||||
};
|
||||
const formData = new FormData();
|
||||
|
||||
if(fileUpload) {
|
||||
fileUpload.forEach((t, i) => {
|
||||
formData.append( `image`, t.originFileObj);
|
||||
});
|
||||
}
|
||||
if(fileUploadBackground) {
|
||||
fileUploadBackground.forEach((t, i) => {
|
||||
formData.append( `bg_image`, t.originFileObj);
|
||||
});
|
||||
}
|
||||
|
||||
if(values.id_number == 1) {
|
||||
values.id_number = 1;
|
||||
if(!values.id_number_description) {
|
||||
setErrors({id_number_description: "ID Number Description is required!"})
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: <div>
|
||||
Something went wrong.
|
||||
<div>- ID Number Description is required!</div>
|
||||
</div>
|
||||
});
|
||||
return this.setState({loading: false})
|
||||
}
|
||||
} else {
|
||||
values.id_number = 0;
|
||||
}
|
||||
|
||||
if(values.virtual_card_font_color == 2) {
|
||||
values.virtual_card_font_color = 1
|
||||
} else {
|
||||
values.virtual_card_font_color = 0
|
||||
}
|
||||
|
||||
values.code && (formData.append('code', values.code));
|
||||
values.type && (formData.append('type', values.type));
|
||||
values.description && (formData.append('description', values.description));
|
||||
values.terms_and_conditions && (formData.append('terms_and_conditions', values.terms_and_conditions));
|
||||
values.faqs && (formData.append('faqs', values.faqs));
|
||||
formData.append('id_number', values.id_number);
|
||||
formData.append('id_number_description', values.id_number_description);
|
||||
formData.append('virtual_card_font_color', values.virtual_card_font_color);
|
||||
|
||||
let response = await API_UNI_OIL.post(`cardTypeUpdate/${userInfo.cardtype_uuid}`, formData , headers)
|
||||
|
||||
if(response) {
|
||||
message.success('Record was successfully update.');
|
||||
this.setState({loading: false})
|
||||
history.push({ pathname: "/about-us/card-types" })
|
||||
}
|
||||
|
||||
|
||||
} catch ({response: error}) {
|
||||
if (error.status === 422) {
|
||||
apiFormValidation({ data: error.data.data, setErrors });
|
||||
}
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: <div>
|
||||
Something went wrong creating new record.
|
||||
{ error && error.data && error.data.data && error.data.data.image
|
||||
&& (<div>- {error.data.data.image[0]} </div>) }
|
||||
</div>
|
||||
});
|
||||
this.setState({loading: false})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handleEditCardTypes =()=> {
|
||||
this.form.submitForm()
|
||||
}
|
||||
|
||||
handleFileUpload =(e)=> {
|
||||
if (Array.isArray(e)) {
|
||||
return this.setState({fileUpload: e});
|
||||
}
|
||||
return e && this.setState({fileUpload: e.fileList});
|
||||
}
|
||||
|
||||
handleFileUploadBackground =(e)=> {
|
||||
if (Array.isArray(e)) {
|
||||
return this.setState({fileUploadBackground: e});
|
||||
}
|
||||
return e && this.setState({fileUploadBackground: e.fileList});
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
if(!this.state.mounted) return null;
|
||||
|
||||
const { loading, userInfo } = this.state
|
||||
|
||||
return (
|
||||
<div style={{ border:'1px solid #E6ECF5' , paddingBottom: '10px'}}>
|
||||
<div>
|
||||
<h2 style={{margin: '25px 35px'}}>Card Types Details</h2>
|
||||
<Formik
|
||||
initialValues={{
|
||||
code: userInfo.code || '',
|
||||
type: userInfo.name || '',
|
||||
description: userInfo.description || '',
|
||||
image: userInfo.image || '',
|
||||
terms_and_conditions: userInfo.terms_and_conditions || '',
|
||||
faqs: userInfo.faqs || '',
|
||||
id_number: userInfo.id_number && userInfo.id_number == 1 ? userInfo.id_number : 2 || '',
|
||||
id_number_description: userInfo.id_number_description || '',
|
||||
virtual_card_font_color: userInfo.virtual_card_font_color && userInfo.virtual_card_font_color == 1 ? 2 : 1 || 1,
|
||||
bg_image: userInfo.bg_image || '',
|
||||
id_number_description: userInfo.id_number_description || '',
|
||||
}}
|
||||
ref={node => (this.form = node)}
|
||||
enableReinitialize={true}
|
||||
validationSchema={userDetailsSchema}
|
||||
onSubmit={this.handleSubmit }
|
||||
render = {(props)=>
|
||||
<EditCardForm
|
||||
{...props}
|
||||
loading={loading}
|
||||
history={this.props.history}
|
||||
handleFileUpload={this.handleFileUpload}
|
||||
handleFileUploadBackground={this.handleFileUploadBackground}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(CardTypeEdit);
|
|
@ -1,40 +0,0 @@
|
|||
|
||||
import * as Yup from 'yup'
|
||||
|
||||
export const userDetailsSchema = Yup.object().shape({
|
||||
code: Yup.string()
|
||||
.trim()
|
||||
.max(128, "Maximum character is 128.")
|
||||
//.max(12,"Card Code must be 12 characters only. "),
|
||||
.required('Card Code is required!'),
|
||||
type: Yup.string()
|
||||
.trim()
|
||||
.max(128, "Maximum character is 128.")
|
||||
.required('Card Type Description is required!'),
|
||||
description: Yup.string()
|
||||
.trim()
|
||||
.max(140, "Maximum character is 140.")
|
||||
.required('Card Type Short Description is required!'),
|
||||
image: Yup.string()
|
||||
.required('Upload Card Type Image is required!'),
|
||||
virtual_card_font_color: Yup.string()
|
||||
.required('Virtual Card Font Color is required!'),
|
||||
bg_image: Yup.string()
|
||||
.required('Upload Card Type Cover Image is required!'),
|
||||
terms_and_conditions: Yup.string()
|
||||
.trim()
|
||||
.max(32000, "Maximum character is 32,000.")
|
||||
.required('Terms and Condition is required!'),
|
||||
faqs: Yup.string()
|
||||
.trim()
|
||||
.max(32000, "Maximum character is 32,000.")
|
||||
.required('FAQs is required!'),
|
||||
id_number: Yup.string()
|
||||
.required('ID Number is required!'),
|
||||
id_number_description: Yup.string()
|
||||
.trim()
|
||||
.max(40, "Maximum character is 40."),
|
||||
})
|
||||
|
||||
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React, { Component } from 'react';
|
||||
import { Menu, Dropdown, notification, Icon, message } from "antd"
|
||||
import { connect } from "react-redux";
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
// COMPONENTS
|
||||
import AdvanceTable from "components/Tables/AdvanceTable";
|
||||
import HeaderForm from "components/Forms/HeaderForm";
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
import { API_UNI_OIL } from "utils/Api";
|
||||
import { customAction } from 'actions';
|
||||
|
||||
class CardTypeList extends Component {
|
||||
state= {
|
||||
updating: false,
|
||||
}
|
||||
|
||||
delete =(admin_uuid)=> {
|
||||
|
||||
}
|
||||
|
||||
updateDropDown = async(e) => {
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const { match, history } = this.props;
|
||||
|
||||
return (
|
||||
<div style={{border:'1px solid #E6ECF5'}}>
|
||||
<HeaderForm
|
||||
title="Card Types"
|
||||
action={()=> history.push({ pathname: `${match.url}/create` })}
|
||||
actionBtnName="Add Card"
|
||||
/>
|
||||
<AdvanceTable
|
||||
updating = { this.state.updating }
|
||||
keyValue="cardtype_uuid"
|
||||
url={{
|
||||
//default: 'admin?page=1&page_size=10&_sort_by=create_dt&_sort_order=desc'
|
||||
apiDelete: 'cardTypeBatchDelete',
|
||||
default: 'cardType',
|
||||
filter: '?page=1&page_size=10&_sort_by=create_dt&_sort_order=desc'
|
||||
}}
|
||||
filterValues ={["role", "status"]}
|
||||
columns={
|
||||
[
|
||||
{
|
||||
title: 'Card Type Code',
|
||||
dataIndex: 'code',
|
||||
key: 'code',
|
||||
sorter: true,
|
||||
filters: [],
|
||||
width: "17%",
|
||||
},
|
||||
{
|
||||
title: 'Card Type Description',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
sorter: true,
|
||||
filters:[],
|
||||
},
|
||||
{
|
||||
title: 'Action',
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
width: 150,
|
||||
buttons: [
|
||||
{
|
||||
key: 'edit',
|
||||
title: "Edit",
|
||||
icon: 'edit',
|
||||
url: 'about-us/card-types/edit'
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
title: "Delete",
|
||||
icon: 'delete',
|
||||
url: '',
|
||||
action: this.delete
|
||||
},
|
||||
{
|
||||
key: 'view',
|
||||
title: "View",
|
||||
icon: 'right-circle-o',
|
||||
url: 'about-us/card-types/view'
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
CardTypeList = connect(
|
||||
state => ({
|
||||
//user: state.viewUser.data,
|
||||
//status: state.viewUser.code,
|
||||
//responseMsg: state.viewUser.messages
|
||||
}),
|
||||
{ customAction }
|
||||
)(CardTypeList);
|
||||
|
||||
export default CardTypeList;
|
|
@ -1,103 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { Icon, Avatar, Row , Col } from 'antd'
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
|
||||
function ViewCardForm(props) {
|
||||
const {
|
||||
isSubmitting,
|
||||
userInfo
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{padding: '15px 30px 0px', borderTop: 0}}>
|
||||
<div>
|
||||
<h2 style={{margin: '0 0 20px'}}>Details</h2>
|
||||
{/*Account Details */}
|
||||
<h2 style={{fontWeight: 'bold', fontSize: '16px'}}>CARD DETAILS</h2>
|
||||
<Row style={styles.marginTop}>
|
||||
<Col span={18} push={5}>{userInfo && userInfo.code}</Col>
|
||||
<Col span={5} pull={18}><span style={{fontWeight: '600'}}>Card Code:</span></Col>
|
||||
</Row>
|
||||
<Row style={styles.marginTop}>
|
||||
<Col span={18} push={5}>{userInfo && userInfo.name}</Col>
|
||||
<Col span={5} pull={18}><span style={{fontWeight: '600'}}>Card Type Description:</span></Col>
|
||||
</Row>
|
||||
<Row style={styles.marginTop}>
|
||||
<Col span={18} push={5}>{userInfo && userInfo.description}</Col>
|
||||
<Col span={5} pull={18}><span style={{fontWeight: '600'}}>Card Type Short Description:</span></Col>
|
||||
</Row>
|
||||
<Row style={styles.marginTop}>
|
||||
<Col span={18} push={5}>
|
||||
<img
|
||||
src={userInfo && userInfo.image && `${userInfo.image}`}
|
||||
alt="avatar"
|
||||
width="300"
|
||||
style={{maxHeight: '250px'}}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={5} pull={18}><span style={{fontWeight: '600'}}>Card Type Image:</span></Col>
|
||||
</Row>
|
||||
<Row style={styles.marginTop}>
|
||||
<Col span={18} push={5}>{userInfo && userInfo.virtual_card_font_color && userInfo.virtual_card_font_color ? "Black": "White"}</Col>
|
||||
<Col span={5} pull={18}><span style={{fontWeight: '600'}}>Virtual Card Font Color:</span></Col>
|
||||
</Row>
|
||||
<Row style={styles.marginTop}>
|
||||
<Col span={18} push={5}>
|
||||
<img
|
||||
src={userInfo && userInfo.image && `${userInfo.bg_image}`}
|
||||
alt="avatar"
|
||||
width="300"
|
||||
style={{maxHeight: '250px'}}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={5} pull={18}><span style={{fontWeight: '600'}}>Card Type Cover Image:</span></Col>
|
||||
</Row>
|
||||
<Row style={styles.marginTop}>
|
||||
<Col span={18} push={5}>{userInfo && userInfo.id_number && userInfo.id_number ? "Yes": "No"}</Col>
|
||||
<Col span={5} pull={18}><span style={{fontWeight: '600'}}>ID Number Required:</span></Col>
|
||||
</Row>
|
||||
<Row style={styles.marginTop}>
|
||||
<Col span={18} push={5}>{userInfo && userInfo.id_number_description}</Col>
|
||||
<Col span={5} pull={18}><span style={{fontWeight: '600'}}>ID Number Description:</span></Col>
|
||||
</Row>
|
||||
</div>
|
||||
{/*Account Details */}
|
||||
<div style={{margin: '15px 0 10px'}}>
|
||||
<h2 style={{fontWeight: 'bold', fontSize: '16px'}}>DATA PRIVACY DETAILS</h2>
|
||||
<Row style={styles.marginTop}>
|
||||
<Col span={18} push={5}>{userInfo && userInfo.terms_and_conditions}</Col>
|
||||
<Col span={5} pull={18}><span style={{fontWeight: '600'}}>{`Terms and Conditions:`}</span></Col>
|
||||
</Row>
|
||||
<Row style={styles.marginTop}>
|
||||
<Col span={18} push={5}>{userInfo && userInfo.faqs}</Col>
|
||||
<Col span={5} pull={18}><span style={{fontWeight: '600'}}>FAQs:</span></Col>
|
||||
</Row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
ViewCardForm = connect(
|
||||
state => ({
|
||||
|
||||
}),
|
||||
)(ViewCardForm);
|
||||
|
||||
|
||||
export default ViewCardForm;
|
||||
|
||||
|
||||
const styles = {
|
||||
marginTop: {
|
||||
marginTop: '5px'
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React, { Component } from 'react'
|
||||
import { withRouter } from "react-router-dom"
|
||||
import { notification, message } from "antd"
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from 'components/Forms/HeaderForm'
|
||||
import ViewCardForm from './components/ViewCardForm'
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
import { API_UNI_OIL } from "utils/Api";
|
||||
|
||||
|
||||
class CardTypeView extends Component {
|
||||
state = {
|
||||
mounted: false,
|
||||
userInfo: null
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
|
||||
const { match } = this.props;
|
||||
|
||||
try {
|
||||
let response = await API_UNI_OIL.get(`cardType/${match.params.id}`)
|
||||
this.setState({
|
||||
userInfo: {...response.data.data},
|
||||
mounted: true
|
||||
})
|
||||
} catch ({response: error}) {
|
||||
notification.error({
|
||||
message: "Error",
|
||||
description: <div>
|
||||
<div>Something went wrong loading data.</div>
|
||||
- { error && error.data && error.data.message }
|
||||
</div> ,
|
||||
duration: 3,
|
||||
});
|
||||
if(error.status == 404) {
|
||||
if(this.props.location.pathname)
|
||||
this.props.history.push(`${this.props.location.pathname}/404`); return
|
||||
}
|
||||
this.setState({ mounted: false })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
delete = async (uuid) => {
|
||||
|
||||
const { userInfo } = this.state;
|
||||
const { match } = this.props;
|
||||
|
||||
try {
|
||||
await API_UNI_OIL.delete(`cardType/${userInfo.cardtype_uuid}`);
|
||||
message.success('Record was successfully deleted.');
|
||||
this.props.history.push("/about-us/card-types");
|
||||
} catch ({response:error}) {
|
||||
notification.error({
|
||||
message: "Error",
|
||||
description: <div>
|
||||
<div>Something went wrong deleting record.</div>
|
||||
- { error && error.data && error.data.message }
|
||||
</div> ,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
if(!this.state.mounted) return null;
|
||||
|
||||
const { userInfo } = this.state
|
||||
const { history, match } = this.props
|
||||
|
||||
return (
|
||||
<div style={{ border:'1px solid #E6ECF5' , paddingBottom: '10px'}}>
|
||||
<HeaderForm
|
||||
title="Card Type Details"
|
||||
action={()=> {this.props.history.push(`/about-us/card-types/edit/${match.params.id}`)}}
|
||||
actionBtnName="Update"
|
||||
styleBtn={{background: 'white', borderColor: 'rgb(184, 187, 201)',color: 'rgb(101, 105, 127)'}}
|
||||
deleteAction={this.delete}
|
||||
deleteBtnName="Delete"
|
||||
/>
|
||||
<div>
|
||||
<ViewCardForm userInfo={userInfo} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default withRouter(CardTypeView);
|
|
@ -1,83 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React from 'react';
|
||||
import { Row, Button, Col } from 'antd';
|
||||
import { Form, Field } from 'formik';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
import { Inputs, InputTextArea } from 'components/Forms';
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 4 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
};
|
||||
|
||||
function AddUserManagementForm(props) {
|
||||
const {
|
||||
isSubmitting,
|
||||
handleSubmit,
|
||||
generatePassword,
|
||||
loading,
|
||||
isGenerated,
|
||||
match,
|
||||
history
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Form noValidate>
|
||||
<HeaderForm
|
||||
isInsideForm
|
||||
loading={loading}
|
||||
disabled={props.isValid == false ? true : false}
|
||||
title={match.params.id == "1" ? "Terms" : "Privacy Policy"}
|
||||
action={handleSubmit}
|
||||
actionBtnName="Submit"
|
||||
withCancelConfirm={{ message: 'Are you sure you want to discard changes?'}}
|
||||
cancel={()=> { history.push("/about-us/term-privacy")}}
|
||||
cancelBtnName="Cancel"
|
||||
/>
|
||||
<Field
|
||||
name="title"
|
||||
type="text"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
label="Title"
|
||||
placeholder="Title"
|
||||
component={Inputs}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="details"
|
||||
type="text"
|
||||
icon="user"
|
||||
layout={formItemLayout}
|
||||
label="Details"
|
||||
placeholder="Details"
|
||||
rows={10}
|
||||
component={InputTextArea}
|
||||
/>
|
||||
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
AddUserManagementForm = connect(
|
||||
state => ({
|
||||
|
||||
}),
|
||||
)(AddUserManagementForm);
|
||||
|
||||
|
||||
export default AddUserManagementForm;
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React, { Component } from 'react'
|
||||
import { connect } from "react-redux"
|
||||
import { Formik } from 'formik'
|
||||
import { message,notification } from 'antd';
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
import AddUserManagementForm from './components/AddUserManagementForm'
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
import { userDetailsSchema } from './validationSchema'
|
||||
import { customAction } from "actions";
|
||||
import { API_GET, API_POST, API_UNI_OIL } from "utils/Api";
|
||||
import { apiFormValidation } from "utils/helper";
|
||||
|
||||
|
||||
class TermAndPrivacyCreate extends Component {
|
||||
state = {
|
||||
generated_password: null,
|
||||
userInfo: null,
|
||||
loading: false,
|
||||
isGenerated: false
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
handleSubmit = async (values, actions) => {
|
||||
const { setSubmitting, setErrors } = actions;
|
||||
let { history, match } = this.props;
|
||||
let params = { ...values, type: match.params.id }
|
||||
this.setState({ loading: true });
|
||||
|
||||
try {
|
||||
const response = await API_UNI_OIL.post('TermsAndPrivacy', params);
|
||||
if(response) {
|
||||
message.success('New record added.');
|
||||
this.setState({ loading: false });
|
||||
history.push({ pathname: '/about-us/term-privacy' });
|
||||
}
|
||||
|
||||
} catch ({response:error}) {
|
||||
if (error.status === 422) {
|
||||
apiFormValidation({ data: error.data.data, setErrors });
|
||||
}
|
||||
notification.error({
|
||||
message: "Error",
|
||||
description: <div>
|
||||
<div>Something went wrong creating new record.</div>
|
||||
- { error && error.data && error.data.message }
|
||||
</div> ,
|
||||
duration: 3,
|
||||
});
|
||||
setSubmitting(false);
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handleCreateTermPrivacy =()=> {
|
||||
this.form.submitForm()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { userManagement, match } = this.props
|
||||
const { loading, isGenerated } = this.state;
|
||||
|
||||
return (
|
||||
<div style={{ border:'1px solid #E6ECF5' , paddingBottom: '30px'}}>
|
||||
{/* <HeaderForm
|
||||
loading={loading}
|
||||
title={match.params.id == "1" ? "Terms" : "Privacy Policy"}
|
||||
action={this.handleCreateTermPrivacy}
|
||||
actionBtnName="Submit"
|
||||
withCancelConfirm={{ message: 'Are you sure you want to discard changes?'}}
|
||||
cancel={()=> { this.props.history.push("/about-us/term-privacy")}}
|
||||
cancelBtnName="Cancel"
|
||||
/> */}
|
||||
<div>
|
||||
<h2 style={{margin: '25px 35px'}}>{match.params.id == "1" ? "Terms" : "Privacy Policy"} Details</h2>
|
||||
<Formik
|
||||
initialValues={{
|
||||
title: '',
|
||||
details: '',
|
||||
}}
|
||||
ref={node => (this.form = node)}
|
||||
enableReinitialize={true}
|
||||
validationSchema={userDetailsSchema}
|
||||
onSubmit={this.handleSubmit }
|
||||
render = {(props)=>
|
||||
<AddUserManagementForm
|
||||
{...props}
|
||||
loading={userManagement.createRequestPending || loading}
|
||||
match={match}
|
||||
history={this.props.history}
|
||||
isGenerated={isGenerated}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TermAndPrivacyCreate = connect(
|
||||
state => ({
|
||||
//userInfo: state
|
||||
userManagement: state.userManagement,
|
||||
}),
|
||||
{ customAction }
|
||||
)(TermAndPrivacyCreate);
|
||||
|
||||
export default TermAndPrivacyCreate;
|
|
@ -1,18 +0,0 @@
|
|||
|
||||
import * as Yup from 'yup'
|
||||
|
||||
export const userDetailsSchema = Yup.object().shape({
|
||||
title: Yup.string()
|
||||
.trim()
|
||||
.max(128, "Maximum character is 128.")
|
||||
.required('Title is required!'),
|
||||
details: Yup.string()
|
||||
.trim()
|
||||
.max(32000, "Maximum character is 32,000.")
|
||||
.required('Details is required!'),
|
||||
// type: Yup.string()
|
||||
// .required('Type is required!')
|
||||
})
|
||||
|
||||
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React from 'react';
|
||||
import { Row, Button, Col } from 'antd';
|
||||
import { Form, Field } from 'formik';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
import { Inputs, InputTextArea } from 'components/Forms';
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 4 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
};
|
||||
|
||||
function EditUserManagementForm(props) {
|
||||
const {
|
||||
isSubmitting,
|
||||
generatePassword,
|
||||
loading,
|
||||
handleSubmit,
|
||||
isGenerated,
|
||||
history
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Form noValidate>
|
||||
<HeaderForm
|
||||
isInsideForm
|
||||
loading={loading}
|
||||
disabled={props.isValid == false ? true : false}
|
||||
title="Update Terms"
|
||||
action={handleSubmit}
|
||||
actionBtnName="Submit"
|
||||
withConfirm={{message: "Save changes to this record?"}}
|
||||
withCancelConfirm={{ message: 'Are you sure you want to discard changes?'}}
|
||||
cancel={()=> { history.push("/about-us/term-privacy")}}
|
||||
cancelBtnName="Cancel"
|
||||
/>
|
||||
<Field
|
||||
name="title"
|
||||
type="text"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
label="Title"
|
||||
placeholder="Title"
|
||||
component={Inputs}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="details"
|
||||
type="text"
|
||||
icon="user"
|
||||
layout={formItemLayout}
|
||||
label="Details"
|
||||
placeholder="Details"
|
||||
rows={10}
|
||||
component={InputTextArea}
|
||||
/>
|
||||
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
EditUserManagementForm = connect(
|
||||
state => ({
|
||||
|
||||
}),
|
||||
)(EditUserManagementForm);
|
||||
|
||||
|
||||
export default EditUserManagementForm;
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React, { Component } from 'react'
|
||||
import { Formik } from 'formik'
|
||||
import { withRouter } from "react-router-dom"
|
||||
import { notification, message } from "antd"
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
import EditUserManagementForm from './components/EditUserManagementForm'
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
import { userDetailsSchema } from './validationSchema'
|
||||
import { API_GET, API_PUT, API_POST } from "utils/Api";
|
||||
import { API_UNI_OIL } from "utils/Api";
|
||||
import { apiFormValidation } from "utils/helper";
|
||||
|
||||
class TermAndPrivacyEdit extends Component {
|
||||
state = {
|
||||
loading: false,
|
||||
userInfo: null,
|
||||
mounted: false,
|
||||
timerCount: 20,
|
||||
isGenerated: false
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
|
||||
const { match } = this.props;
|
||||
|
||||
try {
|
||||
let response = await API_UNI_OIL.get(`TermsAndPrivacy/${match.params.id}`);
|
||||
this.setState({
|
||||
userInfo: {...response.data.data},
|
||||
mounted: true
|
||||
})
|
||||
} catch ({response: error}) {
|
||||
notification.error({
|
||||
message: "Error",
|
||||
description: <div>
|
||||
<div>Something went wrong loading data.</div>
|
||||
- {error && error.data && error.data.message}
|
||||
</div> ,
|
||||
duration: 3,
|
||||
});
|
||||
if(error.status == 404) {
|
||||
if(this.props.location.pathname)
|
||||
this.props.history.push(`${this.props.location.pathname}/404`); return
|
||||
}
|
||||
this.setState({ mounted: false })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handleEditUserManagement =()=> {
|
||||
this.form.submitForm()
|
||||
}
|
||||
|
||||
handleSubmit = async (values, actions) => {
|
||||
|
||||
const { setErrors, setSubmitting } = actions;
|
||||
const { userInfo } = this.state;
|
||||
let { history } = this.props;
|
||||
|
||||
const params = {
|
||||
...values,
|
||||
type : userInfo.type
|
||||
}
|
||||
|
||||
this.setState({loading: true})
|
||||
try {
|
||||
const response = await API_PUT(`TermsAndPrivacy/${userInfo.tp_uuid}`, params);
|
||||
if(response.status === 422){
|
||||
if (response.status === 422) {
|
||||
apiFormValidation({ data: response.data.data, setErrors });
|
||||
}
|
||||
notification.error({ message: "Success", description: "Something went wrong updating record" });
|
||||
setSubmitting(false)
|
||||
this.setState({loading: false})
|
||||
}else {
|
||||
message.success('Record was successfully update.');
|
||||
this.setState({loading: false})
|
||||
this.props.history.push("/about-us/term-privacy");
|
||||
}
|
||||
} catch (error) {
|
||||
setSubmitting(false)
|
||||
this.setState({loading: false})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
if(!this.state.mounted) return null;
|
||||
|
||||
const { loading, userInfo } = this.state
|
||||
|
||||
return (
|
||||
<div style={{ border:'1px solid #E6ECF5' , paddingBottom: '30px'}}>
|
||||
{/* <HeaderForm
|
||||
loading={loading}
|
||||
title="Update Terms"
|
||||
action={this.handleEditUserManagement}
|
||||
actionBtnName="Submit"
|
||||
withConfirm={{message: "Save changes to this record?"}}
|
||||
withCancelConfirm={{ message: 'Are you sure you want to discard changes?'}}
|
||||
cancel={()=> { this.props.history.push("/about-us/term-privacy")}}
|
||||
cancelBtnName="Cancel"
|
||||
/> */}
|
||||
<div>
|
||||
<h2 style={{margin: '25px 35px'}}>Details</h2>
|
||||
<Formik
|
||||
initialValues={{
|
||||
title: userInfo.title || '',
|
||||
details: userInfo.details || '',
|
||||
}}
|
||||
ref={node => (this.form = node)}
|
||||
enableReinitialize={true}
|
||||
validationSchema={userDetailsSchema}
|
||||
onSubmit={this.handleSubmit }
|
||||
render = {(props)=>
|
||||
<EditUserManagementForm
|
||||
{...props}
|
||||
loading={loading}
|
||||
history={this.props.history}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default withRouter(TermAndPrivacyEdit);
|
|
@ -1,16 +0,0 @@
|
|||
|
||||
import * as Yup from 'yup'
|
||||
|
||||
export const userDetailsSchema = Yup.object().shape({
|
||||
title: Yup.string()
|
||||
.trim()
|
||||
.max(128, "Maximum character is 128.")
|
||||
.required('Title is required!'),
|
||||
details: Yup.string()
|
||||
.trim()
|
||||
.max(32000, "Maximum character is 32,000.")
|
||||
.required('Details is required!'),
|
||||
})
|
||||
|
||||
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React, { Component } from 'react';
|
||||
import { Menu, Dropdown, notification, Icon, message } from "antd"
|
||||
import { connect } from "react-redux";
|
||||
|
||||
// COMPONENTS
|
||||
import AdvanceTable from "components/Tables/AdvanceTable";
|
||||
import HeaderForm from "components/Forms/HeaderForm";
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
import { API_UNI_OIL } from "utils/Api";
|
||||
import { customAction } from 'actions';
|
||||
|
||||
class TermAndPrivacyList extends Component {
|
||||
state= {
|
||||
updating: false,
|
||||
}
|
||||
|
||||
delete =(admin_uuid)=> {
|
||||
|
||||
}
|
||||
|
||||
updateDropDown = async(e) => {
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const { match, history } = this.props;
|
||||
|
||||
return (
|
||||
<div style={{border:'1px solid #E6ECF5'}}>
|
||||
<HeaderForm
|
||||
isDropDown
|
||||
title={`Terms & Privacy`}
|
||||
actionPrivacy={()=> history.push({ pathname: `${match.url}/create/1` }) }
|
||||
actionTerms={()=> history.push({ pathname: `${match.url}/create/2` })}
|
||||
actionBtnName="Add User"
|
||||
/>
|
||||
<AdvanceTable
|
||||
updating = { this.state.updating }
|
||||
keyValue="tp_uuid"
|
||||
url={{
|
||||
//default: 'admin?page=1&page_size=10&_sort_by=create_dt&_sort_order=desc'
|
||||
apiDelete: 'TermsAndPrivacyBatchDelete',
|
||||
default: 'TermsAndPrivacy',
|
||||
filter: '?page=1&page_size=10&_sort_by=create_dt&_sort_order=desc'
|
||||
}}
|
||||
filterValues ={["role", "status"]}
|
||||
columns={
|
||||
[
|
||||
{
|
||||
title: 'Title',
|
||||
dataIndex: 'title',
|
||||
key: 'title',
|
||||
sorter: true,
|
||||
filters: [],
|
||||
width: "20%",
|
||||
},
|
||||
{
|
||||
title: 'Details',
|
||||
dataIndex: 'details',
|
||||
key: 'details',
|
||||
sorter: true,
|
||||
filters:[],
|
||||
render: (text, record) => (
|
||||
<div style={{ width: '490px', whiteSpace: 'noWrap',
|
||||
overflow: 'hidden', textOverflow: 'ellipsis'
|
||||
}}>
|
||||
{record && record.details}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Type',
|
||||
dataIndex: 'type',
|
||||
key: 'type',
|
||||
width: "8%",
|
||||
sorter: true,
|
||||
filters:[],
|
||||
render: (text, record) => (
|
||||
<span >
|
||||
{record && record.type == 1 ? "Terms": "Privacy"}
|
||||
</span>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'Action',
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
width: 150,
|
||||
buttons: [
|
||||
{
|
||||
key: 'edit',
|
||||
title: "Edit",
|
||||
icon: 'edit',
|
||||
url: '/user-management/edit'
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
title: "Delete",
|
||||
icon: 'delete',
|
||||
url: '',
|
||||
action: this.delete
|
||||
},
|
||||
{
|
||||
key: 'view',
|
||||
title: "View",
|
||||
icon: 'right-circle-o',
|
||||
url: '/user-management/view'
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TermAndPrivacyList = connect(
|
||||
state => ({
|
||||
//user: state.viewUser.data,
|
||||
//status: state.viewUser.code,
|
||||
//responseMsg: state.viewUser.messages
|
||||
}),
|
||||
{ customAction }
|
||||
)(TermAndPrivacyList);
|
||||
|
||||
export default TermAndPrivacyList;
|
|
@ -1,55 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { Icon, Avatar, Row , Col } from 'antd'
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
|
||||
function ViewUserManagementForm(props) {
|
||||
const {
|
||||
isSubmitting,
|
||||
userInfo
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{padding: '15px 30px 30px', borderTop: 0}}>
|
||||
<div>
|
||||
<h2 style={{margin: '0 0 20px'}}>Details</h2>
|
||||
{/*Account Details */}
|
||||
<Row style={{marginBottom: '5px'}}>
|
||||
<Col span={18} push={3}>{userInfo && userInfo.title}</Col>
|
||||
<Col span={3} pull={18}><span style={{fontWeight: '600'}}>Title:</span></Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={18} push={3}>{userInfo && <pre style={{
|
||||
overflow: 'auto' ,
|
||||
overflowWrap: 'break-word',
|
||||
whiteSpace: 'pre-wrap',
|
||||
wordWrap: 'break-word',}}>{userInfo.details}</pre>}
|
||||
</Col>
|
||||
<Col span={3} pull={18}><span style={{fontWeight: '600'}}>Details:</span></Col>
|
||||
</Row>
|
||||
{/* <Row>
|
||||
<Col span={18} push={3}>{userInfo && userInfo.type == "1" ? "Terms" : "Privacy"}</Col>
|
||||
<Col span={3} pull={18}><span style={{fontWeight: '600'}}>Type:</span></Col>
|
||||
</Row> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
ViewUserManagementForm = connect(
|
||||
state => ({
|
||||
|
||||
}),
|
||||
)(ViewUserManagementForm);
|
||||
|
||||
|
||||
export default ViewUserManagementForm;
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React, { Component } from 'react'
|
||||
import { withRouter } from "react-router-dom"
|
||||
import { notification, message } from "antd"
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from 'components/Forms/HeaderForm'
|
||||
import ViewUserManagementForm from './components/ViewUserManagementForm'
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
import { API_UNI_OIL } from "utils/Api";
|
||||
|
||||
|
||||
class TermAndPrivacyView extends Component {
|
||||
state = {
|
||||
mounted: false,
|
||||
userInfo: null
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
|
||||
const { match } = this.props;
|
||||
|
||||
try {
|
||||
let response = await API_UNI_OIL.get(`TermsAndPrivacy/${match.params.id}`)
|
||||
this.setState({
|
||||
userInfo: {...response.data.data},
|
||||
mounted: true
|
||||
})
|
||||
} catch ({response: error}) {
|
||||
notification.error({
|
||||
message: "Error",
|
||||
description: <div>
|
||||
<div>Something went wrong loading data.</div>
|
||||
- { error && error.data && error.data.message }
|
||||
</div> ,
|
||||
duration: 3,
|
||||
});
|
||||
if(error.status == 404) {
|
||||
if(this.props.location.pathname)
|
||||
this.props.history.push(`${this.props.location.pathname}/404`); return
|
||||
}
|
||||
this.setState({ mounted: false })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
delete = async (uuid) => {
|
||||
|
||||
const { userInfo } = this.state
|
||||
const { match } = this.props;
|
||||
|
||||
try {
|
||||
await API_UNI_OIL.delete(`TermsAndPrivacy/${userInfo.tp_uuid}`);
|
||||
message.success('Record was successfully deleted.');
|
||||
this.props.history.push("/about-us/term-privacy");
|
||||
} catch ({response:error}) {
|
||||
// this.props.history.push("/404");
|
||||
notification.error({
|
||||
message: "Error",
|
||||
description: <div>
|
||||
<div>Something went wrong deleting record.</div>
|
||||
{/* - { error && error.data && error.data.message } */}
|
||||
</div> ,
|
||||
duration: 3,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const { userInfo } = this.state
|
||||
const { history, match } = this.props
|
||||
|
||||
return (
|
||||
<div style={{ border:'1px solid #E6ECF5' , paddingBottom: '10px'}}>
|
||||
<HeaderForm
|
||||
title={"Terms & Privacy Details"}
|
||||
action={()=> {this.props.history.push(`/about-us/term-privacy/edit/${match.params.id}`)}}
|
||||
actionBtnName="Update"
|
||||
styleBtn={{background: 'white', borderColor: 'rgb(184, 187, 201)',color: 'rgb(101, 105, 127)'}}
|
||||
deleteAction={this.delete}
|
||||
deleteBtnName="Delete"
|
||||
/>
|
||||
<div>
|
||||
<ViewUserManagementForm userInfo={userInfo} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default withRouter(TermAndPrivacyView);
|
|
@ -1,137 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Switch, Route, Redirect } from 'react-router-dom';
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
// COMPONENTS
|
||||
import CardTypeList from './CardTypes/List';
|
||||
import CardTypeCreate from './CardTypes/Create';
|
||||
import CardTypeEdit from './CardTypes/Edit';
|
||||
import CardTypeView from './CardTypes/View';
|
||||
|
||||
import TermAndPrivacyList from './TermAndPrivacy/List';
|
||||
import TermAndPrivacyCreate from './TermAndPrivacy/Create';
|
||||
import TermAndPrivacyEdit from './TermAndPrivacy/Edit';
|
||||
import TermAndPrivacyView from './TermAndPrivacy/View';
|
||||
|
||||
// import TermAndPrivacyList from './TermAndPrivacy/List';
|
||||
|
||||
import { PAGE404 } from "components/PageError/index"
|
||||
import MainContent from 'components/Dashboard/Layout/components/MainContent';
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
|
||||
|
||||
|
||||
class AboutUs extends Component {
|
||||
state = {
|
||||
pageRoutes: [
|
||||
{
|
||||
path: `${this.props.match.url}/card-types`,
|
||||
name: "Card Types",
|
||||
component: CardTypeList,
|
||||
},
|
||||
{
|
||||
path: `${this.props.match.url}/card-types/create`,
|
||||
name: "Create Card Types",
|
||||
component: CardTypeCreate,
|
||||
},
|
||||
{
|
||||
path: `${this.props.match.url}/card-types/edit`,
|
||||
params: ':id',
|
||||
name: "Update Card Types",
|
||||
component: CardTypeEdit,
|
||||
},
|
||||
{
|
||||
path: `${this.props.match.url}/card-types/view`,
|
||||
params: ':id',
|
||||
name: "View Card Types",
|
||||
component: CardTypeView,
|
||||
},
|
||||
|
||||
{
|
||||
path: `${this.props.match.url}/term-privacy`,
|
||||
name: "Terms & Privacy",
|
||||
component: TermAndPrivacyList,
|
||||
},
|
||||
{
|
||||
path: `${this.props.match.url}/term-privacy/create`,
|
||||
params: ':id',
|
||||
name: "Terms",
|
||||
component: TermAndPrivacyCreate,
|
||||
},
|
||||
{
|
||||
path: `${this.props.match.url}/term-privacy/edit`,
|
||||
params: ':id',
|
||||
name: "Terms & Privacy",
|
||||
component:TermAndPrivacyEdit,
|
||||
},
|
||||
{
|
||||
path: `${this.props.match.url}/term-privacy/view`,
|
||||
params: ':id',
|
||||
name: "Terms & Privacy Details",
|
||||
component: TermAndPrivacyView,
|
||||
}
|
||||
|
||||
|
||||
|
||||
// {
|
||||
// path: `${this.props.match.url}/lock-account`,
|
||||
// name: "Locked Accounts",
|
||||
// component: CardMemberList,
|
||||
// },
|
||||
// {
|
||||
// path: `${this.props.match.url}/lock-account/view`,
|
||||
// params: ':id',
|
||||
// name: "View Locked Account",
|
||||
// component: CardMemberView,
|
||||
// }
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
const { userInfo } = this.props
|
||||
const { pageRoutes } = this.state;
|
||||
|
||||
return (
|
||||
|
||||
<div style={{position: 'relative'}}>
|
||||
<MainContent pageRoutes={userInfo.data.userInfo.role == 1 ? pageRoutes : []}>
|
||||
{
|
||||
userInfo.data.userInfo.role == 1
|
||||
?
|
||||
<Switch>
|
||||
<Redirect exact from="/about-us" to="/about-us/card-types"/>
|
||||
<Route exact path = "/about-us/card-types" component = { CardTypeList } />
|
||||
<Route exact path = "/about-us/card-types/create" component = { CardTypeCreate } />
|
||||
<Route exact path = "/about-us/card-types/view/:id" component = { CardTypeView } />
|
||||
<Route exact path = "/about-us/card-types/edit/:id" component = { CardTypeEdit } />
|
||||
|
||||
<Route exact path = "/about-us/term-privacy" component = { TermAndPrivacyList } />
|
||||
<Route exact path = "/about-us/term-privacy/create/:id" component = { TermAndPrivacyCreate } />
|
||||
<Route exact path = "/about-us/term-privacy/view/:id" component = { TermAndPrivacyView } />
|
||||
<Route exact path = "/about-us/term-privacy/edit/:id" component = { TermAndPrivacyEdit } />
|
||||
<PAGE404 />
|
||||
</Switch>
|
||||
:
|
||||
<Switch>
|
||||
<PAGE404 />
|
||||
</Switch>
|
||||
}
|
||||
</MainContent>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AboutUs = connect(
|
||||
state => ({
|
||||
userInfo: state.login
|
||||
}),
|
||||
)(AboutUs);
|
||||
|
||||
|
||||
export default AboutUs;
|
|
@ -1,254 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React from 'react';
|
||||
import { Row, Button, Col } from 'antd';
|
||||
import { Form, Field } from 'formik';
|
||||
import { connect } from 'react-redux';
|
||||
import moment from 'moment'
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
import { Inputs, Select, DatePicker , InputTextArea, UploadImage, TimePickerForm } from 'components/Forms';
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
|
||||
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 10 },
|
||||
},
|
||||
};
|
||||
|
||||
function AddPhotoSliderForm(props) {
|
||||
const {
|
||||
isSubmitting,
|
||||
handleSubmit,
|
||||
loading,
|
||||
promotionsOptions,
|
||||
handleFileUpload,
|
||||
handleGetDate,
|
||||
photoSliderLimit,
|
||||
dateStartEnd,
|
||||
history,
|
||||
handleAutoFillDeatils
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Form noValidate>
|
||||
<HeaderForm
|
||||
isInsideForm
|
||||
loading={loading}
|
||||
disabled={props.isValid == false ? true : false}
|
||||
title="Photo Slider"
|
||||
action={handleSubmit}
|
||||
actionBtnName="Submit"
|
||||
withCancelConfirm={{ message: 'Are you sure you want to discard changes?'}}
|
||||
cancel={() => { history.push("/home-page/photo-slider") }}
|
||||
cancelBtnName="Cancel"
|
||||
/>
|
||||
<Field
|
||||
allowClear
|
||||
name="promotion_uuid"
|
||||
type="select"
|
||||
icon=""
|
||||
disabled={photoSliderLimit}
|
||||
layout={formItemLayout}
|
||||
label="Promotion Name"
|
||||
placeholder="Promotion Name"
|
||||
mode="single"
|
||||
optionsList={promotionsOptions}
|
||||
handleGetDate={handleGetDate}
|
||||
component={Select}
|
||||
handleAutoFillDeatils={handleAutoFillDeatils}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="title"
|
||||
type="text"
|
||||
icon=""
|
||||
disabled={photoSliderLimit}
|
||||
layout={formItemLayout}
|
||||
label="Title"
|
||||
placeholder="Title"
|
||||
component={Inputs}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="description"
|
||||
type="text"
|
||||
icon=""
|
||||
disabled={photoSliderLimit}
|
||||
layout={formItemLayout}
|
||||
label="Description"
|
||||
placeholder="Description"
|
||||
rows={6}
|
||||
component={InputTextArea}
|
||||
/>
|
||||
|
||||
<Field
|
||||
isRatioMessage={{
|
||||
message: <div style={{fontSize: '13px'}} >
|
||||
<div>Image Size: 1020 x 621</div>
|
||||
<div>Maximum File Size: 100KB</div>
|
||||
</div>,
|
||||
// dimensions: [1021,621]
|
||||
}}
|
||||
limit100kb
|
||||
name="image"
|
||||
type="file"
|
||||
disabled={photoSliderLimit}
|
||||
accept=".jpg , .png, .gif"
|
||||
multiple={false}
|
||||
imageUrl={props.values.image && `${props.values.image}`}
|
||||
className="upload-list-inline"
|
||||
icon="user"
|
||||
layout={formItemLayout}
|
||||
label="Upload Image"
|
||||
placeholder="Upload Image"
|
||||
component={UploadImage}
|
||||
imgWidth="294px"
|
||||
imgStyle={{width:"100%", height:"170"}}
|
||||
handleFileUpload={handleFileUpload}
|
||||
/>
|
||||
|
||||
|
||||
<Field
|
||||
name="date_start"
|
||||
type="date"
|
||||
icon=""
|
||||
disabledDateStartEndPhotoSlider
|
||||
dateStartEnd={props.values.promotion_uuid ? dateStartEnd : null}
|
||||
disabled={photoSliderLimit}
|
||||
layout={formItemLayout}
|
||||
label="Start Appearance Date"
|
||||
placeholder="Start Appearance Date"
|
||||
component={DatePicker}
|
||||
isAutoFill
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="date_end"
|
||||
type="date"
|
||||
icon=""
|
||||
disabledDateStart
|
||||
disabledDateStartEndPhotoSlider
|
||||
disabledDateStartEndPhotoSliderEndDate
|
||||
dateStartEnd={props.values.promotion_uuid ? dateStartEnd : null}
|
||||
disabled={photoSliderLimit}
|
||||
layout={formItemLayout}
|
||||
label="End Appearance Date"
|
||||
placeholder="End Appearance Date"
|
||||
component={DatePicker}
|
||||
isAutoFill
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="start_time"
|
||||
type="date"
|
||||
disabledHours={()=> {
|
||||
if(props.values.promotion_uuid) {
|
||||
let time = dateStartEnd && dateStartEnd.date_start && moment(dateStartEnd.date_start, 'YYYY-MM-DDTHH:mm:ss').format('HH:mm:ss').replace(/[^0-9]/g,'').substring(0, 2)
|
||||
let disabledTime = [];
|
||||
let timeLimit = time;
|
||||
// if(time) {
|
||||
// while(timeLimit > 0) {
|
||||
// timeLimit--;
|
||||
// disabledTime.push(timeLimit)
|
||||
// }
|
||||
// }
|
||||
// return disabledTime
|
||||
|
||||
let date_start = moment(props.values.date_start).format('YYYY-MM-DD');
|
||||
let promotion_date_start = moment(dateStartEnd.date_start).format('YYYY-MM-DD');
|
||||
|
||||
if(date_start != promotion_date_start) {
|
||||
return []
|
||||
} else {
|
||||
if(time) {
|
||||
while(timeLimit > 0) {
|
||||
timeLimit--;
|
||||
disabledTime.push(timeLimit)
|
||||
}
|
||||
}
|
||||
return disabledTime
|
||||
}
|
||||
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
}}
|
||||
defaultOpenValue={moment('00:00', 'HH:mm')}
|
||||
format={'HH:mm'}
|
||||
icon=""
|
||||
disabled={photoSliderLimit}
|
||||
layout={formItemLayout}
|
||||
label="Start Time"
|
||||
placeholder="Start Time"
|
||||
component={TimePickerForm}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="end_time"
|
||||
type="date"
|
||||
disabledHours={() => {
|
||||
if(props.values.promotion_uuid) {
|
||||
let time = dateStartEnd && dateStartEnd.date_end && moment(dateStartEnd.date_end, 'YYYY-MM-DDTHH:mm:ss').format('HH:mm:ss').replace(/[^0-9]/g,'').substring(0, 2)
|
||||
let disabledEndTime = [];
|
||||
let timeLimit = time;
|
||||
// if(time) {
|
||||
// while(timeLimit < 23) {
|
||||
// timeLimit++;
|
||||
// disabledEndTime.push(timeLimit)
|
||||
// }
|
||||
// }
|
||||
// return disabledEndTime
|
||||
|
||||
let date_end = moment(props.values.date_end).format('YYYY-MM-DD');
|
||||
let promotion_date_end = moment(dateStartEnd.date_end).format('YYYY-MM-DD');
|
||||
|
||||
if(date_end != promotion_date_end) {
|
||||
return []
|
||||
} else {
|
||||
if(time) {
|
||||
while(timeLimit < 23) {
|
||||
timeLimit++;
|
||||
disabledEndTime.push(timeLimit)
|
||||
}
|
||||
}
|
||||
return disabledEndTime
|
||||
}
|
||||
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
}}
|
||||
defaultOpenValue={moment('00:00', 'HH:mm')}
|
||||
format={'HH:mm'}
|
||||
icon=""
|
||||
disabled={photoSliderLimit}
|
||||
layout={formItemLayout}
|
||||
label="End Time"
|
||||
placeholder="End Time"
|
||||
component={TimePickerForm}
|
||||
/>
|
||||
|
||||
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
AddPhotoSliderForm = connect(
|
||||
state => ({
|
||||
|
||||
}),
|
||||
)(AddPhotoSliderForm);
|
||||
|
||||
|
||||
export default AddPhotoSliderForm;
|
||||
|
|
@ -1,266 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React, { Component } from 'react'
|
||||
import { Formik } from 'formik'
|
||||
import { message, notification } from 'antd'
|
||||
import moment from 'moment'
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
import AddPhotoSliderForm from './components/AddPhotoSliderForm'
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
import { userDetailsSchema } from './validationSchema'
|
||||
import { API_GET, API_POST, API_UNI_OIL } from "utils/Api"
|
||||
import { apiFormValidation } from "utils/helper"
|
||||
|
||||
|
||||
class CreatePhotoSlider extends Component {
|
||||
state = {
|
||||
loading: false,
|
||||
promotionsOptions: null,
|
||||
mounted: false,
|
||||
photoSliderLimit: false,
|
||||
dateStartEnd: null
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
|
||||
try {
|
||||
let photoSlider = await API_UNI_OIL('photoSliderCount');
|
||||
if(photoSlider)
|
||||
this.setState({photoSliderLimit: false})
|
||||
} catch ({response:error}) {
|
||||
this.setState({photoSliderLimit: true})
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
let promotionsList = await API_GET('getPromotions');
|
||||
|
||||
if (promotionsList) {
|
||||
|
||||
let promotionsOptions = []
|
||||
|
||||
await promotionsList.data.data.map(item => {
|
||||
promotionsOptions.push({
|
||||
label: item.title,
|
||||
value: item.promotion_uuid,
|
||||
date: { dateStart: item.date_start , dateEnd: item.date_end }
|
||||
})
|
||||
})
|
||||
|
||||
this.setState({
|
||||
promotionsOptions: promotionsOptions,
|
||||
mounted: true
|
||||
})
|
||||
}
|
||||
|
||||
} catch ({ response: error }) {
|
||||
notification.error({
|
||||
message: "Error",
|
||||
description: <div>
|
||||
<div>Something went wrong loading data.</div>
|
||||
- {error && error.data && error.data.message}
|
||||
</div>,
|
||||
duration: 3,
|
||||
});
|
||||
this.setState({ mounted: false })
|
||||
}
|
||||
}
|
||||
|
||||
handleSubmit = async (values, actions) => {
|
||||
|
||||
const { fileUpload } = this.state;
|
||||
const { history } = this.props;
|
||||
const { setErrors } = actions;
|
||||
|
||||
this.setState({ loading: true })
|
||||
try {
|
||||
const headers = {
|
||||
'ContentType': 'multipart/form-data',
|
||||
};
|
||||
const formData = new FormData();
|
||||
|
||||
if (fileUpload) {
|
||||
fileUpload.forEach((t, i) => {
|
||||
formData.append(`image`, t.originFileObj);
|
||||
});
|
||||
} else {
|
||||
if(values.image) {
|
||||
let imageUrlPath = values.image
|
||||
formData.append(`image`, imageUrlPath);
|
||||
}
|
||||
}
|
||||
|
||||
let date_start = moment(values.date_start).format('YYYY-MM-DD');
|
||||
let start_time = moment(values.start_time).format('HH:mm:ss');
|
||||
|
||||
|
||||
if(start_time == 'Invalid date') {
|
||||
start_time = values.start_time
|
||||
} else {
|
||||
start_time = moment(values.start_time).format('HH:mm:ss');
|
||||
}
|
||||
|
||||
let date_end = moment(values.date_end).format('YYYY-MM-DD');
|
||||
let end_time = moment(values.end_time).format('HH:mm:ss');
|
||||
|
||||
if(end_time == 'Invalid date') {
|
||||
end_time = values.end_time
|
||||
} else {
|
||||
end_time = moment(values.end_time).format('HH:mm:ss');
|
||||
}
|
||||
|
||||
let startDateTime = moment(date_start + ' ' + start_time, 'YYYY-MM-DDTHH:mm:ss');
|
||||
let endDateTime = moment(date_end + ' ' + end_time, 'YYYY-MM-DDTHH:mm:ss');
|
||||
|
||||
values.promotion_uuid && (formData.append('promotion_uuid', values.promotion_uuid));
|
||||
values.title && (formData.append('title', values.title));
|
||||
values.description && (formData.append('description', values.description));
|
||||
values.date_start && (formData.append('date_start', startDateTime.format('YYYY-MM-DDTHH:mm:ss')));
|
||||
values.date_end && (formData.append('date_end', endDateTime.format('YYYY-MM-DDTHH:mm:ss')));
|
||||
|
||||
let response = await API_UNI_OIL.post('photoSlider', formData, headers)
|
||||
|
||||
if (response) {
|
||||
message.success('New record added.');
|
||||
this.setState({ loading: false })
|
||||
history.push({ pathname: "/home-page/photo-slider" })
|
||||
}
|
||||
|
||||
} catch ({ response: error }) {
|
||||
if (error.status === 422) {
|
||||
apiFormValidation({ data: error.data.data, setErrors })
|
||||
}
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: <div>
|
||||
{error && error.data && error.data.data && error.data.data.image
|
||||
&& (<div>{error.data.data.image[0] ? `- ${error.data.data.image[0]}` : "Something went wrong creating new record."} </div>) }
|
||||
</div>
|
||||
});
|
||||
this.setState({ loading: false })
|
||||
}
|
||||
}
|
||||
|
||||
handleAddPhotoSlider = () => {
|
||||
this.form.submitForm()
|
||||
}
|
||||
|
||||
handleFileUpload = (e) => {
|
||||
if (Array.isArray(e)) {
|
||||
return this.setState({ fileUpload: e });
|
||||
}
|
||||
return e && this.setState({ fileUpload: e.fileList });
|
||||
}
|
||||
|
||||
handleGetDate = async (id) => {
|
||||
const {promotionsOptions} = this.state;
|
||||
|
||||
if(promotionsOptions) {
|
||||
await promotionsOptions.map(item=> {
|
||||
if(item.value == id) {
|
||||
this.setState({
|
||||
dateStartEnd: {
|
||||
date_start: item.date.dateStart,
|
||||
date_end: item.date.dateEnd
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handleAutoFillDeatils = async (id,setFieldValue) => {
|
||||
|
||||
if(id) {
|
||||
|
||||
try {
|
||||
let promotionsList = await API_GET(`promotion/${id}`);
|
||||
let autofillData = {
|
||||
...promotionsList.data.data
|
||||
}
|
||||
|
||||
setFieldValue('title', autofillData.title);
|
||||
setFieldValue('description', autofillData.description);
|
||||
setFieldValue('image', `${autofillData.image}`);
|
||||
setFieldValue('date_start', moment(autofillData.date_start, 'YYYY-MM-DDTHH:mm'));
|
||||
setFieldValue('date_end', moment(autofillData.date_end, 'YYYY-MM-DDTHH:mm'));
|
||||
setFieldValue('start_time', moment(autofillData.date_start, 'YYYY-MM-DDTHH:mm').format('HH:mm') );
|
||||
setFieldValue('end_time', moment(autofillData.date_end, 'YYYY-MM-DDTHH:mm').format('HH:mm') );
|
||||
|
||||
this.setState({
|
||||
isAutofill: true
|
||||
})
|
||||
|
||||
} catch ({response: error}) {
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: <div>
|
||||
Something went wrong autofill records.
|
||||
- {error && error.data && error.data.message}
|
||||
</div>
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
if (!this.state.mounted) return null;
|
||||
|
||||
const { loading, promotionsOptions, photoSliderLimit, dateStartEnd } = this.state
|
||||
|
||||
return (
|
||||
<div style={{ border: '1px solid #E6ECF5', paddingBottom: '10px' }}>
|
||||
{/* <HeaderForm
|
||||
loading={loading}
|
||||
title="Photo Slider"
|
||||
action={this.handleAddPhotoSlider}
|
||||
disabled={photoSliderLimit}
|
||||
actionBtnName="Submit"
|
||||
withCancelConfirm={{ message: 'Are you sure you want to discard changes?'}}
|
||||
cancel={() => { this.props.history.push("/home-page/photo-slider") }}
|
||||
cancelBtnName="Cancel"
|
||||
/> */}
|
||||
<div>
|
||||
<h2 style={{ margin: '25px 35px' }}>Photo Slider Content Details</h2>
|
||||
<Formik
|
||||
initialValues={{
|
||||
promotion_uuid: '',
|
||||
title: '',
|
||||
description: '',
|
||||
image: '',
|
||||
date_start: '',
|
||||
date_end: '',
|
||||
start_time: '',
|
||||
end_time: '',
|
||||
}}
|
||||
ref={node => (this.form = node)}
|
||||
enableReinitialize={true}
|
||||
validationSchema={userDetailsSchema}
|
||||
onSubmit={this.handleSubmit}
|
||||
render={(props) =>
|
||||
<AddPhotoSliderForm
|
||||
{...props}
|
||||
loading={loading}
|
||||
history={this.props.history}
|
||||
photoSliderLimit={photoSliderLimit}
|
||||
promotionsOptions={promotionsOptions}
|
||||
handleGetDate={this.handleGetDate}
|
||||
dateStartEnd={dateStartEnd}
|
||||
handleFileUpload={this.handleFileUpload}
|
||||
handleAutoFillDeatils={this.handleAutoFillDeatils}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default CreatePhotoSlider
|
|
@ -1,28 +0,0 @@
|
|||
|
||||
import * as Yup from 'yup'
|
||||
|
||||
export const userDetailsSchema = Yup.object().shape({
|
||||
promotion_uuid: Yup.string(),
|
||||
//.required('Branches is required!'),
|
||||
title: Yup.string()
|
||||
.trim()
|
||||
.max(128, "Maximum character is 128.")
|
||||
.required('Title is required!'),
|
||||
description: Yup.string()
|
||||
.trim()
|
||||
.max(32000, "Maximum character is 32,000."),
|
||||
//.required('Description is required!'),
|
||||
image: Yup.string()
|
||||
.required('Upload Image is required!'),
|
||||
date_start: Yup.string()
|
||||
.required('Start Appearance Date is required!'),
|
||||
date_end: Yup.string()
|
||||
.required('End Appearance Date is required!'),
|
||||
start_time: Yup.string()
|
||||
.required('Start Time is required!'),
|
||||
end_time: Yup.string()
|
||||
.required('End Time is required!'),
|
||||
})
|
||||
|
||||
|
||||
|
|
@ -1,236 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React from 'react'
|
||||
import { Row, Button, Col } from 'antd'
|
||||
import { Form, Field } from 'formik'
|
||||
import { connect } from 'react-redux'
|
||||
import moment from 'moment'
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
import { Inputs, Select, DatePicker , InputTextArea, UploadImage ,TimePickerForm } from 'components/Forms'
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 5 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 10 },
|
||||
},
|
||||
};
|
||||
|
||||
function EditUserManagementForm(props) {
|
||||
const {
|
||||
isSubmitting,
|
||||
loading,
|
||||
handleSubmit,
|
||||
promotionsDefaultValue,
|
||||
promotionsOptions,
|
||||
handleFileUpload,
|
||||
dateStartEnd,
|
||||
handleGetDate,
|
||||
history,
|
||||
handleAutoFillDeatils,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Form noValidate>
|
||||
<HeaderForm
|
||||
isInsideForm
|
||||
loading={loading}
|
||||
disabled={props.isValid == false ? true : false}
|
||||
title="Update Photo Slider"
|
||||
action={handleSubmit}
|
||||
actionBtnName="Submit"
|
||||
withConfirm={{message: "Save changes to this record?"}}
|
||||
withCancelConfirm={{ message: 'Are you sure you want to discard changes?'}}
|
||||
cancel={()=> history.push("/home-page/photo-slider")}
|
||||
cancelBtnName="Cancel"
|
||||
/>
|
||||
<Field
|
||||
allowClear
|
||||
name="promotion_uuid"
|
||||
type="select"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
label="Promotion Name"
|
||||
placeholder="Promotion Name"
|
||||
mode="single"
|
||||
defaultValue={promotionsDefaultValue && (promotionsDefaultValue)}
|
||||
optionsList={promotionsOptions}
|
||||
handleGetDate={handleGetDate}
|
||||
component={Select}
|
||||
handleAutoFillDeatils={handleAutoFillDeatils}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="title"
|
||||
type="text"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
label="Title"
|
||||
placeholder="Title"
|
||||
component={Inputs}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="description"
|
||||
type="text"
|
||||
icon=""
|
||||
layout={formItemLayout}
|
||||
label="Description"
|
||||
placeholder="Description"
|
||||
rows={6}
|
||||
component={InputTextArea}
|
||||
/>
|
||||
|
||||
<Field
|
||||
isRatioMessage={{
|
||||
message: <div style={{fontSize: '13px'}} >
|
||||
<div>Image Size: 1020 x 621</div>
|
||||
<div>Maximum File Size: 100KB</div>
|
||||
</div>,
|
||||
// dimensions: [1021,621]
|
||||
}}
|
||||
limit100kb
|
||||
name="image"
|
||||
type="file"
|
||||
accept=".jpg , .png, .gif"
|
||||
multiple={false}
|
||||
imageUrl={props.values.image && `${props.values.image}`}
|
||||
className="upload-list-inline"
|
||||
icon="user"
|
||||
layout={formItemLayout}
|
||||
label="Upload Image"
|
||||
placeholder="Upload Image"
|
||||
component={UploadImage}
|
||||
imgWidth="294px"
|
||||
imgStyle={{width:"100%", height:"170"}}
|
||||
handleFileUpload={handleFileUpload}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="date_start"
|
||||
type="date"
|
||||
icon=""
|
||||
isEdit
|
||||
disabledDateStartEndPhotoSlider
|
||||
dateStartEnd={props.values.promotion_uuid ? dateStartEnd : null }
|
||||
defaultValue={ moment(props.values.date_start, 'YYYY-MM-DD') }
|
||||
layout={formItemLayout}
|
||||
label="Start Appearance Date"
|
||||
placeholder="Start Appearance Date"
|
||||
component={DatePicker}
|
||||
isAutoFill
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="date_end"
|
||||
type="date"
|
||||
icon=""
|
||||
isEdit
|
||||
disabledDateStart
|
||||
disabledDateStartEndPhotoSlider
|
||||
disabledDateStartEndPhotoSliderEndDate
|
||||
dateStartEnd={props.values.promotion_uuid ? dateStartEnd : null }
|
||||
defaultValue={ moment(props.values.date_end, 'YYYY-MM-DD') }
|
||||
layout={formItemLayout}
|
||||
label="End Appearance Date"
|
||||
placeholder="End Appearance Date"
|
||||
component={DatePicker}
|
||||
isAutoFill
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="start_time"
|
||||
type="date"
|
||||
icon=""
|
||||
disabledHours={()=> {
|
||||
if(props.values.promotion_uuid) {
|
||||
let time = dateStartEnd && dateStartEnd.date_start && moment(dateStartEnd.date_start, 'YYYY-MM-DDTHH:mm').format('HH:mm').replace(/[^0-9]/g,'').substring(0, 2)
|
||||
let disabledTime = [];
|
||||
let timeLimit = time;
|
||||
|
||||
let date_start = moment(props.values.date_start).format('YYYY-MM-DD');
|
||||
let promotion_date_start = moment(dateStartEnd.date_start).format('YYYY-MM-DD');
|
||||
|
||||
if(date_start != promotion_date_start) {
|
||||
return []
|
||||
} else {
|
||||
if(time) {
|
||||
while(timeLimit > 0) {
|
||||
timeLimit--;
|
||||
disabledTime.push(timeLimit)
|
||||
}
|
||||
}
|
||||
return disabledTime
|
||||
}
|
||||
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
}}
|
||||
defaultValue={moment(props.values.start_time, 'HH:mm')}
|
||||
format={'HH:mm'}
|
||||
layout={formItemLayout}
|
||||
label="Start Time"
|
||||
placeholder="Start Time"
|
||||
component={TimePickerForm}
|
||||
/>
|
||||
|
||||
<Field
|
||||
name="end_time"
|
||||
type="date"
|
||||
icon=""
|
||||
disabledHours={() => {
|
||||
if(props.values.promotion_uuid) {
|
||||
let time = dateStartEnd && dateStartEnd.date_end && moment(dateStartEnd.date_end, 'YYYY-MM-DDTHH:mm').format('HH:mm').replace(/[^0-9]/g,'').substring(0, 2)
|
||||
let disabledEndTime = [];
|
||||
let timeLimit = time;
|
||||
|
||||
let date_end = moment(props.values.date_end).format('YYYY-MM-DD');
|
||||
let promotion_date_end = moment(dateStartEnd.date_end).format('YYYY-MM-DD');
|
||||
|
||||
if(date_end != promotion_date_end) {
|
||||
return []
|
||||
} else {
|
||||
if(time) {
|
||||
while(timeLimit < 23) {
|
||||
timeLimit++;
|
||||
disabledEndTime.push(timeLimit)
|
||||
}
|
||||
}
|
||||
return disabledEndTime
|
||||
}
|
||||
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
|
||||
}}
|
||||
defaultValue={moment(props.values.end_time, 'HH:mm')}
|
||||
format={'HH:mm'}
|
||||
layout={formItemLayout}
|
||||
label="End Time"
|
||||
placeholder="End Time"
|
||||
component={TimePickerForm}
|
||||
/>
|
||||
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
EditUserManagementForm = connect(
|
||||
state => ({
|
||||
|
||||
}),
|
||||
)(EditUserManagementForm);
|
||||
|
||||
|
||||
export default EditUserManagementForm;
|
||||
|
|
@ -1,331 +0,0 @@
|
|||
// LIBRARIES
|
||||
import React, { Component } from 'react'
|
||||
import { Formik } from 'formik'
|
||||
import moment from 'moment'
|
||||
import { notification, message } from "antd"
|
||||
|
||||
// COMPONENTS
|
||||
import HeaderForm from "components/Forms/HeaderForm"
|
||||
import EditPhotoSliderForm from './components/EditPhotoSliderForm'
|
||||
|
||||
// HELPER FUNCTIONS
|
||||
import { userDetailsSchema } from './validationSchema'
|
||||
import { API_GET, API_PUT, API_POST } from "utils/Api";
|
||||
import { API_UNI_OIL } from "utils/Api";
|
||||
import { apiFormValidation } from "utils/helper";
|
||||
|
||||
class EditPhotoSlider extends Component {
|
||||
state = {
|
||||
loading: false,
|
||||
userInfo: null,
|
||||
mounted: false,
|
||||
promotionsDefaultValue: null,
|
||||
promotionsDefaultKeyValue: null,
|
||||
promotionsOptions: null,
|
||||
dateStartEnd: null
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
|
||||
const { match } = this.props;
|
||||
let promotionsDefaultValue = []
|
||||
let promotionsDefaultKeyValue = []
|
||||
|
||||
try {
|
||||
let response = await API_UNI_OIL.get(`photoSlider/${match.params.id}`);
|
||||
// default options branch
|
||||
|
||||
let promotions = []
|
||||
|
||||
if(response.data.data.promotion) {
|
||||
|
||||
promotions.push({...response.data.data.promotion})
|
||||
|
||||
await promotions.map(item => {
|
||||
promotionsDefaultValue.push(
|
||||
item.title
|
||||
)
|
||||
promotionsDefaultKeyValue.push(
|
||||
item.promotion_uuid
|
||||
)
|
||||
})
|
||||
}
|
||||
// default options promotype
|
||||
|
||||
let dateStartEnd = promotions && promotions[0] && {
|
||||
date_start: promotions[0].date_start,
|
||||
date_end: promotions[0].date_end
|
||||
}
|
||||
|
||||
this.setState({
|
||||
userInfo: {...response.data.data},
|
||||
mounted: true,
|
||||
promotionsDefaultValue,
|
||||
promotionsDefaultKeyValue,
|
||||
dateStartEnd: dateStartEnd
|
||||
})
|
||||
|
||||
|
||||
} catch ({response: error}) {
|
||||
notification.error({
|
||||
message: "Error",
|
||||
description: <div>
|
||||
<div>Something went wrong loading data.</div>
|
||||
- { error && error.data && error.data.message }
|
||||
</div> ,
|
||||
duration: 3,
|
||||
});
|
||||
if(error.status == 404) {
|
||||
if(this.props.location.pathname) {
|
||||
this.props.history.push(`${this.props.location.pathname}/404`);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
this.setState({ mounted: false })
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// options
|
||||
try {
|
||||
|
||||
let params = {
|
||||
selected_promotion: promotionsDefaultKeyValue.length > 0 && promotionsDefaultKeyValue[0]
|
||||
}
|
||||
let promotionsOptions = []; let promoTypeOptions = []
|
||||
let promotionsList = await API_GET('getPromotions', params);
|
||||
|
||||
if(promotionsList) {
|
||||
await promotionsList.data.data.map(item => {
|
||||
promotionsOptions.push({
|
||||
label: item.title,
|
||||
value: item.promotion_uuid,
|
||||
date: { dateStart: item.date_start , dateEnd: item.date_end }
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
this.setState({
|
||||
promotionsOptions: promotionsOptions,
|
||||
mounted: true
|
||||
})
|
||||
|
||||
} catch ({response: error}) {
|
||||
this.setState({ mounted: false })
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
handleSubmit = async (values, actions) => {
|
||||
|
||||
const { fileUpload, branchesOptions, userInfo } = this.state;
|
||||
const { history } = this.props;
|
||||
const { setErrors } = actions;
|
||||
|
||||
console.log(values, 'valuesvaluesvalues')
|
||||
|
||||
this.setState({loading: true})
|
||||
try {
|
||||
const headers = {
|
||||
'ContentType': 'multipart/form-data',
|
||||
};
|
||||
|
||||
const formData = new FormData();
|
||||
|
||||
if(fileUpload) {
|
||||
fileUpload.forEach((t, i) => {
|
||||
formData.append( `image`, t.originFileObj);
|
||||
});
|
||||
} else {
|
||||
if(values.image) {
|
||||
let imageUrlPath = values.image
|
||||
formData.append(`image`, imageUrlPath);
|
||||
}
|
||||
}
|
||||
|
||||
let date_start = moment(values.date_start).format('YYYY-MM-DD');
|
||||
let start_time = moment(values.start_time).format('HH:mm:ss');
|
||||
|
||||
if(start_time == 'Invalid date') {
|
||||
start_time = values.start_time
|
||||
} else {
|
||||
start_time = moment(values.start_time).format('HH:mm:ss');
|
||||
}
|
||||
|
||||
let date_end = moment(values.date_end).format('YYYY-MM-DD');
|
||||
let end_time = moment(values.end_time).format('HH:mm:ss');
|
||||
|
||||
if(end_time == 'Invalid date') {
|
||||
end_time = values.end_time
|
||||
} else {
|
||||
end_time = moment(values.end_time).format('HH:mm:ss');
|
||||
}
|
||||
|
||||
let startDateTime = moment(date_start + ' ' + start_time, 'YYYY-MM-DDTHH:mm:ss');
|
||||
let endDateTime = moment(date_end + ' ' + end_time, 'YYYY-MM-DDTHH:mm:ss');
|
||||
|
||||
// let branchesList = []
|
||||
|
||||
// values.promotion.map(item => {
|
||||
// branchesOptions.map(userInfo => {
|
||||
// if(userInfo.label == item || userInfo.value == item) {
|
||||
// branchesList.push(userInfo.value);
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
|
||||
values.promotion_uuid && (formData.append('promotion_uuid', values.promotion_uuid ));
|
||||
values.title && (formData.append('title', values.title));
|
||||
values.description && (formData.append('description', values.description));
|
||||
values.date_start && (formData.append('date_start', startDateTime.format('YYYY-MM-DDTHH:mm:ss') ) );
|
||||
values.date_end && (formData.append('date_end', endDateTime.format('YYYY-MM-DDTHH:mm:ss') ) );
|
||||
|
||||
// log formdata
|
||||
// for (var pair of formData.entries()) {
|
||||
// console.log(pair[0]+ ', ' + pair[1]);
|
||||
// }
|
||||
let response = await API_UNI_OIL.post(`updatePhotoSlider/${userInfo.photoslider_uuid}`, formData , headers)
|
||||
|
||||
if(response) {
|
||||
message.success('Record was successfully update.');
|
||||
this.setState({loading: false})
|
||||
history.push({ pathname: "/home-page/photo-slider" })
|
||||
}
|
||||
|
||||
} catch ({response: error}) {
|
||||
if (error.status === 422) {
|
||||
apiFormValidation({ data: error.data.data, setErrors })
|
||||
}
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: <div>
|
||||
{ error && error.data && error.data.data && error.data.data.image
|
||||
&& (<div>{error.data.data.image[0] ? `- ${error.data.data.image[0]}` : "Something went wrong updating record."} </div>) }
|
||||
</div>
|
||||
});
|
||||
this.setState({loading: false})
|
||||
}
|
||||
}
|
||||
|
||||
handleEditPhotoSlider =()=> {
|
||||
this.form.submitForm()
|
||||
}
|
||||
|
||||
handleFileUpload =(e)=> {
|
||||
if (Array.isArray(e)) {
|
||||
return this.setState({fileUpload: e});
|
||||
}
|
||||
return e && this.setState({fileUpload: e.fileList});
|
||||
}
|
||||
|
||||
handleGetDate = async (id) => {
|
||||
const {promotionsOptions} = this.state;
|
||||
|
||||
if(promotionsOptions) {
|
||||
await promotionsOptions.map(item=> {
|
||||
if(item.value == id) {
|
||||
this.setState({
|
||||
dateStartEnd: {
|
||||
date_start: item.date.dateStart,
|
||||
date_end: item.date.dateEnd
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handleAutoFillDeatils = async (id,setFieldValue) => {
|
||||
|
||||
if(id) {
|
||||
|
||||
try {
|
||||
let promotionsList = await API_GET(`promotion/${id}`);
|
||||
let autofillData = {
|
||||
...promotionsList.data.data
|
||||
}
|
||||
|
||||
setFieldValue('title', autofillData.title);
|
||||
setFieldValue('description', autofillData.description);
|
||||
setFieldValue('image', `${autofillData.image}`);
|
||||
setFieldValue('date_start', moment(autofillData.date_start, 'YYYY-MM-DDTHH:mm'));
|
||||
setFieldValue('date_end', moment(autofillData.date_end, 'YYYY-MM-DDTHH:mm'));
|
||||
setFieldValue('start_time', moment(autofillData.date_start, 'YYYY-MM-DDTHH:mm').format('HH:mm') );
|
||||
setFieldValue('end_time', moment(autofillData.date_end, 'YYYY-MM-DDTHH:mm').format('HH:mm') );
|
||||
|
||||
this.setState({
|
||||
isAutofill: true
|
||||
})
|
||||
|
||||
} catch ({response: error}) {
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: <div>
|
||||
Something went wrong autofill records.
|
||||
- {error && error.data && error.data.message}
|
||||
</div>
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
if(!this.state.mounted) return null;
|
||||
|
||||
const { loading, userInfo, promotionsOptions, promotionsDefaultValue , promotionsDefaultKeyValue, dateStartEnd } = this.state
|
||||
|
||||
return (
|
||||
<div style={{ border:'1px solid #E6ECF5' , paddingBottom: '10px'}}>
|
||||
{/* <HeaderForm
|
||||
loading={loading}
|
||||
title="Update Photo Slider"
|
||||
action={this.handleEditPhotoSlider}
|
||||
actionBtnName="Submit"
|
||||
withConfirm={{message: "Save changes to this record?"}}
|
||||
withCancelConfirm={{ message: 'Are you sure you want to discard changes?'}}
|
||||
cancel={()=> this.props.history.push("/home-page/photo-slider")}
|
||||
cancelBtnName="Cancel"
|
||||
/> */}
|
||||
<div>
|
||||
<h2 style={{margin: '25px 35px'}}>Photo Slider Content Details</h2>
|
||||
<Formik
|
||||
initialValues={{
|
||||
promotion_uuid: promotionsDefaultKeyValue[0] || '',
|
||||
title: userInfo.title || '',
|
||||
description: userInfo.description || '',
|
||||
image: userInfo.image || '',
|
||||
date_start: moment(userInfo.date_start, 'YYYY-MM-DDTHH:mm').format('YYYY-MM-DD') || '',
|
||||
date_end: moment( userInfo.date_end, 'YYYY-MM-DDTHH:mm').format('YYYY-MM-DD') || '',
|
||||
start_time: moment(userInfo.date_start, 'YYYY-MM-DDTHH:mm').format('HH:mm') || '',
|
||||
end_time: moment(userInfo.date_end, 'YYYY-MM-DDTHH:mm' ).format('HH:mm') || '',
|
||||
}}
|
||||
ref={node => (this.form = node)}
|
||||
enableReinitialize={true}
|
||||
validationSchema={userDetailsSchema}
|
||||
onSubmit={this.handleSubmit }
|
||||
render = {(props)=>
|
||||
<EditPhotoSliderForm
|
||||
{...props}
|
||||
loading={loading}
|
||||
history={this.props.history}
|
||||
dateStartEnd={dateStartEnd}
|
||||
promotionsOptions={promotionsOptions}
|
||||
promotionsDefaultValue={promotionsDefaultValue}
|
||||
handleFileUpload={this.handleFileUpload}
|
||||
handleGetDate={this.handleGetDate}
|
||||
handleAutoFillDeatils={this.handleAutoFillDeatils}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default EditPhotoSlider
|
|
@ -1,28 +0,0 @@
|
|||
|
||||
import * as Yup from 'yup'
|
||||
|
||||
export const userDetailsSchema = Yup.object().shape({
|
||||
promotion_uuid: Yup.string(),
|
||||
//.required('Promotion Name is required!'),
|
||||
title: Yup.string()
|
||||
.trim()
|
||||
.max(128, "Maximum character is 128.")
|
||||
.required('Title is required!'),
|
||||
description: Yup.string()
|
||||
.trim()
|
||||
.max(32000, "Maximum character is 32,000."),
|
||||
// .required('Description is required!'),
|
||||
image: Yup.string()
|
||||
.required('Upload Image is required!'),
|
||||
date_start: Yup.string()
|
||||
.required('Start Appearance Date is required!'),
|
||||
date_end: Yup.string()
|
||||
.required('End Appearance Date is required!'),
|
||||
start_time: Yup.string()
|
||||
.required('Start Time is required!'),
|
||||
end_time: Yup.string()
|
||||
.required('End Time is required!'),
|
||||
})
|
||||
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue