Ionic + React accounts android app and PWA
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

130 wiersze
5.2 KiB

  1. import React, { useState } from 'react';
  2. import styles from './invoice.module.scss';
  3. import { ReactComponent as ChevronBack } from 'ionicons/dist/svg/chevron-back.svg';
  4. import { format } from 'date-fns';
  5. import { IonButton, IonDatetime, IonInput } from '@ionic/react';
  6. type OwnProps = {
  7. invoice: {
  8. id: string,
  9. date: string,
  10. status: string,
  11. dateOfPayment?: string,
  12. referenceNumber?: string,
  13. },
  14. client: {
  15. name: string,
  16. logo: string,
  17. project: {
  18. name: string,
  19. contract: {
  20. name: string,
  21. amount: string,
  22. },
  23. }
  24. }
  25. }
  26. export const InvoiceCard: React.FC<OwnProps> = (props) => {
  27. const [showDetails, setShowDetails] = useState<boolean>(false);
  28. const [formInputs, setFormInputs] = useState<{
  29. dateOfPayment: string,
  30. referenceNumber: string,
  31. }>({
  32. dateOfPayment: props.invoice.dateOfPayment ? props.invoice.dateOfPayment.toString() : '',
  33. referenceNumber: props.invoice.referenceNumber ? props.invoice.referenceNumber : '',
  34. });
  35. let statusClass = '';
  36. switch (props.invoice.status) {
  37. case 'due': statusClass = styles.due; break;
  38. case 'over due': statusClass = styles.overDue; break;
  39. case 'paid': statusClass = styles.paid; break;
  40. case 'cancelled': statusClass = styles.cancelled; break;
  41. default: break;
  42. }
  43. return <div>
  44. <section className={styles.card} onClick={() => setShowDetails(true)}>
  45. <figure>
  46. <img src={props.client.logo} alt="logo" />
  47. </figure>
  48. <div className={styles.contentHolder}>
  49. <h6> Invoice ID: {props.invoice.id} </h6>
  50. <h2> {props.client.project.contract.amount} </h2>
  51. <p> {props.client.project.contract.name} </p>
  52. </div>
  53. <div className={styles.status}>
  54. <span className={statusClass}> {props.invoice.status} </span>
  55. </div>
  56. </section>
  57. { showDetails && <div className={styles.backdrop}>
  58. <section className={styles.cardDetails}>
  59. <header>
  60. <IonButton onClick={() => setShowDetails(false)} fill={'clear'} size={'small'}> <ChevronBack /> </IonButton>
  61. <h4> Pending Invoice </h4>
  62. </header>
  63. <ul>
  64. <li>
  65. <label> Invoice ID </label>
  66. <p> {props.invoice.id} </p>
  67. </li>
  68. <li>
  69. <label> Invoice Date </label>
  70. <p> {format(new Date(props.invoice.date), 'dd MMMM yyyy')} </p>
  71. </li>
  72. <li>
  73. <label> Client </label>
  74. <p> {props.client.name} </p>
  75. </li>
  76. <li>
  77. <label> Project </label>
  78. <p> {props.client.project.name} </p>
  79. </li>
  80. <li>
  81. <label> Contract </label>
  82. <p> {props.client.project.contract.name} </p>
  83. </li>
  84. <li>
  85. <label> Invoice Amount </label>
  86. <p> {props.client.project.contract.amount} </p>
  87. </li>
  88. </ul>
  89. <section className={styles.form}>
  90. <div className={styles.inputHolder}>
  91. <label> Payment Date </label>
  92. <IonDatetime value={formInputs.dateOfPayment} mode={'ios'} placeholder={'DD/MM/YYYY'} displayFormat={'DD/MM/YYYY'}
  93. onIonChange={(e) => setFormInputs({
  94. dateOfPayment: e.detail.value? e.detail.value.toString() : '',
  95. referenceNumber: formInputs.referenceNumber,
  96. })}></IonDatetime>
  97. </div>
  98. <div className={styles.inputHolder}>
  99. <label> Reference No. </label>
  100. <IonInput placeholder={'Enter here'} value={formInputs.referenceNumber}
  101. onIonChange={(e) => setFormInputs({
  102. dateOfPayment: formInputs.dateOfPayment,
  103. referenceNumber: e.detail.value? e.detail.value.toString() : '',
  104. })}></IonInput>
  105. </div>
  106. {(props.invoice.status !== 'cancelled' && props.invoice.status !== 'paid' || formInputs.dateOfPayment !== props.invoice.dateOfPayment || formInputs.dateOfPayment !== props.invoice.date) && <div className={styles.buttonsHolder}>
  107. <IonButton fill={'outline'} className={styles.cancel} shape={'round'}> Cancel Invoice </IonButton>
  108. <IonButton fill={'solid'} className={styles.approve + ' ' + (formInputs.dateOfPayment && formInputs.referenceNumber ? '' : styles.disabled)} shape={'round'}
  109. onClick={() => setShowDetails(false)}> Paid </IonButton>
  110. </div>}
  111. </section>
  112. </section>
  113. </div> }
  114. </div>
  115. }