Advertisement
Guest User

Untitled

a guest
Jun 26th, 2019
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.21 KB | None | 0 0
  1. import React, { Component } from "react";
  2. import { withRouter} from "react-router-dom";
  3. import {
  4. Row,
  5. Col,
  6. Card,
  7. } from "reactstrap";
  8. import CurrencyFormatter from "../../../utility/currency-formatter";
  9. import app from "firebase/app";
  10. import MDSpinner from "react-md-spinner";
  11. import AuthContext from "../../../context/auth-contex";
  12. import styled from 'styled-components'
  13. import CheckoutModal from './CheckoutStatusModal'
  14. import ReactPlayer from 'react-player'
  15. import {ButtonPrimary, Input} from '../../containers/StyledComponent/Index'
  16. import {Link} from 'react-router-dom'
  17. import moment from 'moment'
  18.  
  19. const ContainerFlex = styled.div`
  20. display: grid
  21. grid-template-columns: 0.3fr 1fr
  22. width: 100%
  23. justify-content: space-between
  24. @media (max-width: 700px) {
  25. grid-template-columns: 1fr
  26. grid-gap: 20px
  27. }
  28. `
  29.  
  30. const Wrapper = styled.div`
  31. display: grid
  32. grid-template-columns: 1fr 1fr
  33. grid-gap: 20px
  34. width: 100%
  35. justify-content: space-between
  36. @media (max-width: 700px) {
  37. grid-template-columns: 1fr
  38. }
  39. `
  40.  
  41. const ContainerDiv = styled.div`
  42. width: 40%
  43. @media (max-width: 700px) {
  44. width: 100%
  45. }
  46. `
  47.  
  48.  
  49. class CheckoutContainer extends Component {
  50. static contextType = AuthContext
  51. state = {
  52. course: {},
  53. invoice: {},
  54. isLoading: true,
  55. isLoadingCheckout: false,
  56. isPaid: false,
  57. isCheckout: false,
  58. paymentStatus: '',
  59. value: '',
  60. totalAkhir: 0,
  61. voucher: 0,
  62. tipeVoucher: 0,
  63. kodeVoucher: '',
  64. redeem: false,
  65. modal: false,
  66. haveTransaction: false,
  67. isExpired: false,
  68. status_input: true,
  69. precentage: false
  70. };
  71.  
  72. componentDidMount() {
  73. const course_id = this.props.match.params.id;
  74. let db = app.firestore();
  75. db.collection("courses")
  76. .doc(course_id)
  77. .get()
  78. .then(doc => {
  79. this.setState({
  80. course: { id: doc.id, ...doc.data() },
  81. totalAkhir: doc.data().price,
  82. });
  83. this.getCheckoutData();
  84. });
  85. }
  86.  
  87. getCheckoutData = () => {
  88. const course_id = this.props.match.params.id;
  89. const user_id = this.context.user.uid;
  90. const db = app.firestore();
  91. db.collection("invoices")
  92. .where("user_id", "==", user_id)
  93. .where("course_id", "==", course_id)
  94. .onSnapshot(doc => {
  95.  
  96. var source = doc.metadata.hasPendingWrites ? "Local" : "Server";
  97. if (doc.size === 0) {
  98. this.setState({
  99. invoices: {},
  100. isLoading: false
  101. });
  102. } else {
  103. doc.forEach(document => {
  104.  
  105. if (document.data().status == "NEED_PAYMENT") {
  106. this.setState({
  107. invoice: { id: document.id, ...document.data() },
  108. isLoading: false,
  109. isCheckout: true,
  110. redeem: document.data().redeem,
  111. totalAkhir: document.data().price,
  112. kodeVoucher: document.data().voucher_code
  113. });
  114. }
  115. });
  116. }
  117. });
  118. db.collection("transaction")
  119. .where("user_id", "==", user_id)
  120. .where("course_id", "==", course_id)
  121. .onSnapshot(doc => {
  122.  
  123. if(doc.size === 0) {
  124.  
  125. this.setState({
  126. haveTransaction: false,
  127. });
  128. } else {
  129. doc.forEach(val => {
  130. if(val.data().status_code === "201") {
  131. const currentDate = moment().unix()
  132. const invoice_date = val.data().date
  133. const res = currentDate - invoice_date
  134. if(res/3600 > 23) {
  135.  
  136. db.collection("invoices").doc(val.data().invoice_id).delete().then(docss => {
  137.  
  138. db.collection("transaction").doc(val.id).delete().then(doc => {
  139.  
  140. window.location.reload(true)
  141. }).catch(error => {
  142. alert('error, laporkan bug')
  143. })
  144. }).catch(err => {
  145. alert('error, laporkan bug')
  146. })
  147.  
  148. } else {
  149.  
  150. this.setState(prevState => ({
  151. haveTransaction: true,
  152. modal: true,
  153. }));
  154. }
  155. } else {
  156.  
  157. this.props.history.push(`/account/transaction/${this.context.user.uid}`)
  158. }
  159. })
  160. }
  161. });
  162. };
  163.  
  164. createCheckout = () => {
  165. this.setState({
  166. isLoading: false
  167. })
  168. let course_id = this.props.match.params.id;
  169. const db = app.firestore();
  170. db.collection("invoices")
  171. .add({
  172. user_id: this.context.user.uid,
  173. course_id: course_id,
  174. status: "INVOICE_CREATED",
  175. bank: "BCA",
  176. redeem: this.state.redeem,
  177. price: this.state.totalAkhir,
  178. date: moment().unix(),
  179. voucher_code: this.state.kodeVoucher
  180. })
  181. .then(docRef => {
  182. this.setState({
  183. isLoadingCheckout: true
  184. })
  185. const course_id = this.props.match.params.id;
  186. const user_id = this.context.user.uid;
  187. const db = app.firestore();
  188. db.collection("invoices")
  189. .where("user_id", "==", user_id)
  190. .where("course_id", "==", course_id)
  191. .onSnapshot(doc => {
  192. var source = doc.metadata.hasPendingWrites ? "Local" : "Server";
  193. if (doc.size === 0) {
  194. this.setState({
  195. invoices: {},
  196. isLoading: false
  197. });
  198. } else {
  199. doc.forEach(document => {
  200.  
  201. if (document.data().status === "NEED_PAYMENT") {
  202. this.setState({
  203. invoice: { id: document.id, ...document.data() },
  204. isLoading: false,
  205. isCheckout: true
  206. });
  207. this.pay()
  208. }
  209. });
  210. }
  211. });
  212. })
  213. .catch(error => {
  214.  
  215. });
  216. };
  217.  
  218. pay = () => {
  219. let course_id = this.props.match.params.id;
  220. const user = this.context.user.uid
  221. const link = `/account/transaction/${user}`
  222. const getCheckoutDataAgain = () => {
  223. this.getCheckoutData()
  224. }
  225. const isCheckout = this.state.isCheckout
  226. const invoice_id = this.state.invoice.id
  227. const transaction_token = this.state.invoice.transaction_token
  228. window.snap.pay(this.state.invoice.transaction_token, {
  229. onSuccess: function(result) {
  230. let db = app.firestore();
  231.  
  232. db.collection("transaction")
  233. .add({
  234. user_id: user,
  235. course_id: course_id,
  236. invoice_id: invoice_id,
  237. ...result
  238. })
  239. .then(docRef => {
  240.  
  241. })
  242. .catch(error => {
  243. alert(error)
  244. });
  245. let addCourse = db.collection("users").doc(user);
  246. return addCourse.update({
  247. myCourse: app.firestore.FieldValue.arrayUnion(this.state.myCourse)
  248. })
  249. .then(function() {
  250.  
  251. })
  252. .catch(function(error) {
  253. console.error("Error updating document: ", error);
  254. });
  255. },
  256. onPending: function(result) {
  257. let db = app.firestore();
  258.  
  259. db.collection("transaction")
  260. .add({
  261. user_id: user,
  262. course_id: course_id,
  263. invoice_id: invoice_id,
  264. date: moment().unix(),
  265. transaction_token: transaction_token,
  266. ...result
  267. })
  268. .then(docRef => {
  269. window.location.replace(link)
  270. })
  271. .catch(error => {
  272. alert(error)
  273. });
  274. const ref = `${result.payment_code}`
  275. },
  276. onError: function(result) {
  277. let db = app.firestore();
  278. db.collection('invoices').doc(invoice_id).delete().then(val => {
  279. window.location.reload(true)
  280. })
  281. getCheckoutDataAgain();
  282. }
  283. });
  284. };
  285.  
  286. handleVoucher = (event) => {
  287. this.setState({value: event.target.value});
  288. }
  289.  
  290. handleClick = () => {
  291. const db = app.firestore();
  292. db.collection('voucher')
  293. .where("code", "==", this.state.value)
  294. .onSnapshot(doc => {
  295. if(doc.size === 0) {
  296. this.setState({
  297. redeem: false,
  298. })
  299. } else {
  300. doc.forEach(document => {
  301. if(document.data().type_diskon === 'rupiah') {
  302. this.setState({
  303. redeem: true,
  304. kodeVoucher: document.data().code,
  305. voucher: document.data().diskon,
  306. precentage: document.data().status,
  307. totalAkhir : this.state.totalAkhir - document.data().diskon
  308. })
  309. } else {
  310. this.setState({
  311. redeem: true,
  312. kodeVoucher: document.data().code,
  313. voucher: document.data().diskon,
  314. precentage: document.data().status,
  315. totalAkhir : this.state.totalAkhir - this.state.totalAkhir*document.data().diskon/100
  316. })
  317. }
  318. })
  319. }
  320. })
  321. }
  322.  
  323.  
  324. render() {
  325. const {modal} = this.state
  326. if (this.state.isLoading) {
  327. return (
  328. <div className="bg-light">
  329. <div className="container py-4">
  330. <Row>
  331. <Col md={12} style={{ marginBottom: 48, marginTop: 24 }}>
  332. <center>
  333. <MDSpinner size={64} />
  334. </center>
  335. </Col>
  336. </Row>
  337. </div>
  338. </div>
  339. );
  340. }
  341. return (
  342. <React.Fragment style={{
  343. width: '100%',
  344. padding: '20px',
  345. gridTemplateColumns: '1fr',
  346. height: '100%',
  347. display: 'grid',
  348. position: 'absolute',
  349. padding: '0 30px',
  350. }}>
  351. <div style={{
  352. width: '100%',
  353. minWidth: '100%',
  354. background: 'white',
  355. color: 'black',
  356. padding: '10px 0 0 20px',
  357. }}>
  358. <div style={{
  359. fontSize: '24px',
  360. }}>Checkout</div>
  361. </div>
  362. <div>
  363. <Card style={{ padding: 24, width: '100%', minHeight: '100vh', height: '100%'}}>
  364. <ContainerFlex>
  365. <div>
  366. <ReactPlayer
  367. url={this.state.course.mainVidLink}
  368. width='200px'
  369. height='100px'
  370. light={true}
  371. muted={true}
  372. />
  373. </div>
  374. <ContainerDiv>
  375. <h5>{this.state.course.title}</h5>
  376. <div className="text-muted">
  377. By {this.state.course.teacher}
  378. </div>
  379. <hr />
  380. <div className="text-muted">Price</div>
  381. <strike>
  382. <small className="text-muted">
  383. {CurrencyFormatter.format(this.state.course.price*1.2)}
  384. </small>
  385. </strike>
  386. <h5 className="card-text">
  387. {CurrencyFormatter.format(this.state.course.price)}
  388. </h5>
  389. {
  390. this.state.haveTransaction ? (
  391. <div>
  392. Anda telah melakukan transaksi
  393. </div>
  394. ) : (
  395. <div>
  396. <div>Kode Voucher</div>
  397. <div>
  398. {
  399. this.state.isCheckout ? (
  400. <div style={{
  401. width: '100%',
  402. gridGap: '20px',
  403. display: 'grid',
  404. gridTemplateColumns: '1fr 0.3fr'
  405. }}>
  406. <Input type="text" value={this.state.value} placeholder={this.state.kodeVoucher} onChange={this.handleVoucher}/>
  407. <ButtonPrimary
  408. style={{
  409. maxWidth: '120px',
  410. width: '100%'
  411. }}
  412. onClick={this.handleClick}>Redeem</ButtonPrimary>
  413. </div>
  414. ) : (
  415. <div>
  416. {
  417. this.state.redeem ? (
  418. <div style={{
  419. width: '100%',
  420. gridGap: '20px',
  421. display: 'grid',
  422. gridTemplateColumns: '1fr 0.3fr'
  423. }}>
  424. <Input type="text" value={this.state.value} placeholder="masukan kode voucher" onChange={this.handleVoucher} disabled/>
  425. <ButtonPrimary
  426. style={{
  427. maxWidth: '120px',
  428. width: '100%'
  429. }}
  430. onClick={this.handleClick} disabled>Redeem</ButtonPrimary>
  431. {
  432. this.state.precentage ? (
  433. <div style={{
  434. display: 'grid',
  435. gridTemplateColumns: '1fr 1fr',
  436. width: '100%',
  437. }}>
  438. <div className="text-muted">
  439. Potongan Harga
  440. </div>
  441. <div>{CurrencyFormatter.format(this.state.voucher)}</div>
  442. </div>
  443. ) : (
  444. <div style={{
  445. display: 'grid',
  446. gridTemplateColumns: '1fr 1fr',
  447. width: '100%',
  448. }}>
  449. <div>
  450. Potongan harga {this.state.voucher}% (Hemat {CurrencyFormatter.format(this.state.totalAkhir*this.state.voucher/100)})
  451. </div>
  452. </div>
  453. )
  454. }
  455. </div>
  456. ) : (
  457. <div style={{
  458. width: '100%',
  459. gridGap: '20px',
  460. display: 'grid',
  461. gridTemplateColumns: '1fr 0.3fr'
  462. }}>
  463. <Input type="text" value={this.state.value} placeholder="masukan kode voucher" onChange={this.handleVoucher}/>
  464. <ButtonPrimary
  465. style={{
  466. maxWidth: '120px',
  467. width: '100%'
  468. }}
  469. onClick={this.handleClick}>Redeem</ButtonPrimary>
  470. {
  471. this.state.status_input ? (
  472. <div></div>
  473. ) : (
  474. <div style={{
  475. color: 'red',
  476. fontSize: '12px'
  477. }}>
  478. kode yang anda masukan salah
  479. </div>
  480. )
  481. }
  482. </div>
  483. )
  484. }
  485. </div>
  486. )
  487. }
  488. </div>
  489. </div>
  490. )
  491. }
  492. <div className="text-muted" style={{
  493. marginTop: '20px',
  494. fontWeight: 'bold'
  495. }}>Total Bayar</div>
  496. <h4 className="card-text" style={{
  497. fontWeight: 'bold'
  498. }}>
  499. {CurrencyFormatter.format(this.state.totalAkhir)}
  500. </h4>
  501. {
  502. (this.state.isCheckout) ? (
  503. <div>
  504. {
  505. this.state.haveTransaction ? (
  506. <Link to={`/account/transaction/${this.context.user.uid}`}>
  507. <ButtonPrimary primary color="success">
  508. Lihat Transaksi
  509. </ButtonPrimary>
  510. </Link>
  511. ) : (
  512. <ButtonPrimary primary onClick={this.pay} color="success">
  513. Lakukan pembayaran
  514. </ButtonPrimary>
  515. )
  516. }
  517. </div>
  518. ) : (
  519. <div>
  520. {
  521. this.state.isLoadingCheckout ? (
  522. <ButtonPrimary primary color="success" >
  523. <MDSpinner size={24} />
  524. Mohon Tunggu Sebentar
  525. </ButtonPrimary>
  526. ) : (
  527. <ButtonPrimary primary onClick={this.createCheckout} color="success">
  528. Checkout
  529. </ButtonPrimary>
  530. )
  531. }
  532. </div>
  533. )
  534. }
  535. </ContainerDiv>
  536. </ContainerFlex>
  537. </Card>
  538. </div>
  539. <ContainerFlex style={{
  540. padding: '10px 20px 20px 20px'
  541. }}>
  542. <CheckoutModal isOpen={this.state.modal} user={this.context.user.uid}/>
  543. </ContainerFlex>
  544. </React.Fragment>
  545. );
  546. }
  547. }
  548.  
  549. const WrappedClass = withRouter(CheckoutContainer);
  550. WrappedClass.WrappedComponent.contextType = AuthContext;
  551. export default WrappedClass;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement