@@ -0,0 +1,100 @@ | |||
%card { | |||
background-color: white; | |||
border: 1px solid var(--card-outline); | |||
overflow: hidden; | |||
border-radius: 20px; | |||
display: flex; | |||
margin: 20px auto; | |||
} | |||
%commonIonInput { | |||
font-size: 14px; | |||
color: var(--black); | |||
--padding-top: 5px; | |||
--padding-end: 0; | |||
--padding-bottom: 5px; | |||
--padding-start: 0px; | |||
} | |||
%formSubmitIonButton { | |||
width: calc(50% - 10px); | |||
display: block; | |||
margin: 0 auto; | |||
height: 40px; | |||
font-size: 13px; | |||
letter-spacing: 0.5px; | |||
&.cancel { | |||
--border-width: 1px; | |||
--border-color: var(--black); | |||
color: var(--black); | |||
} | |||
&.approve { | |||
--background: var(--teal); | |||
} | |||
&.disabled { | |||
pointer-events: none; | |||
filter: grayscale(100%); | |||
} | |||
} | |||
%commonCardDetailsPopup { | |||
position: fixed; | |||
left: 0; | |||
top: 0; | |||
z-index: 2; | |||
background-color: rgba(0, 0, 0, 0); | |||
width: 100%; | |||
height: 100vh; | |||
display: flex; | |||
align-items: flex-end; | |||
justify-content: stretch; | |||
overflow: auto; | |||
transform: translateY(50vh); | |||
animation: popFromBottom 0.3s forwards; | |||
@keyframes popFromBottom { | |||
0% { | |||
transform: translateY(50vh); | |||
} 50% { | |||
transform: translateY(0vh); | |||
background-color: rgba(0, 0, 0, 0); | |||
} 100% { | |||
background-color: rgba(0, 0, 0, 0.6); | |||
transform: translateY(0vh); | |||
} | |||
} | |||
.cardDetails { | |||
border-top-right-radius: 30px; | |||
border-top-left-radius: 30px; | |||
background-color: white; | |||
width: 100%; | |||
} | |||
header { | |||
position: relative; | |||
padding: 15px; | |||
ion-button { | |||
width: 30px; | |||
svg { | |||
width: 16px; | |||
height: 16px; | |||
color: var(--black); | |||
} | |||
} | |||
h4 { | |||
font-size: 16px; | |||
text-align: center; | |||
color: var(--black); | |||
font-weight: 500; | |||
width: calc(100% - 60px); | |||
margin-right: auto; | |||
} | |||
} | |||
} |
@@ -1,6 +1,5 @@ | |||
@import '../common'; | |||
.card { | |||
@extend %card; | |||
@@ -74,7 +73,7 @@ | |||
} | |||
} | |||
&.overdue { | |||
&.overDue { | |||
color: var(--red); | |||
&::before { | |||
@@ -94,62 +93,7 @@ | |||
} | |||
.backdrop { | |||
position: fixed; | |||
left: 0; | |||
top: 0; | |||
z-index: 2; | |||
background-color: rgba(0, 0, 0, 0); | |||
width: 100%; | |||
height: 100vh; | |||
display: flex; | |||
align-items: flex-end; | |||
justify-content: stretch; | |||
overflow: auto; | |||
transform: translateY(50vh); | |||
animation: popFromBottom 0.3s forwards; | |||
@keyframes popFromBottom { | |||
0% { | |||
transform: translateY(50vh); | |||
} 50% { | |||
transform: translateY(0vh); | |||
background-color: rgba(0, 0, 0, 0); | |||
} 100% { | |||
background-color: rgba(0, 0, 0, 0.6); | |||
transform: translateY(0vh); | |||
} | |||
} | |||
.cardDetails { | |||
border-top-right-radius: 30px; | |||
border-top-left-radius: 30px; | |||
background-color: white; | |||
width: 100%; | |||
} | |||
header { | |||
position: relative; | |||
padding: 15px; | |||
ion-button { | |||
width: 30px; | |||
svg { | |||
width: 16px; | |||
height: 16px; | |||
color: var(--black); | |||
} | |||
} | |||
h4 { | |||
font-size: 16px; | |||
text-align: center; | |||
color: var(--black); | |||
font-weight: 500; | |||
width: calc(100% - 60px); | |||
margin-right: auto; | |||
} | |||
} | |||
@extend %commonCardDetailsPopup; | |||
ul { | |||
padding: 15px; | |||
@@ -178,34 +122,34 @@ | |||
} | |||
} | |||
} | |||
} | |||
.form { | |||
padding: 0 15px; | |||
.inputHolder { | |||
display: block; | |||
margin: 15px 0; | |||
label { | |||
text-align: left; | |||
font-size: 11px; | |||
color: var(--grey); | |||
font-weight: 500; | |||
letter-spacing: 0.5px; | |||
} | |||
ion-input { | |||
@extend %commonIonInput; | |||
.form { | |||
padding: 0 15px; | |||
.inputHolder { | |||
display: block; | |||
margin: 15px 0; | |||
label { | |||
text-align: left; | |||
font-size: 11px; | |||
color: var(--grey); | |||
font-weight: 500; | |||
letter-spacing: 0.5px; | |||
} | |||
ion-input { | |||
@extend %commonIonInput; | |||
} | |||
} | |||
} | |||
.buttonsHolder { | |||
margin: 15px 0; | |||
display: flex; | |||
ion-button { | |||
@extend %formSubmitIonButton; | |||
.buttonsHolder { | |||
margin: 15px 0; | |||
display: flex; | |||
ion-button { | |||
@extend %formSubmitIonButton; | |||
} | |||
} | |||
} | |||
} |
@@ -7,9 +7,9 @@ import { IonButton, IonDatetime, IonInput } from '@ionic/react'; | |||
type OwnProps = { | |||
invoice: { | |||
id: string, | |||
date: Date, | |||
date: string, | |||
status: string, | |||
dateOfPayment?: Date, | |||
dateOfPayment?: string, | |||
referenceNumber?: string, | |||
}, | |||
client: { | |||
@@ -45,7 +45,7 @@ export const InvoiceCard: React.FC<OwnProps> = (props) => { | |||
default: break; | |||
} | |||
return <div className={styles.cardContainer}> | |||
return <div> | |||
<section className={styles.card} onClick={() => setShowDetails(true)}> | |||
<figure> | |||
<img src={props.client.logo} alt="logo" /> | |||
@@ -74,7 +74,7 @@ export const InvoiceCard: React.FC<OwnProps> = (props) => { | |||
<li> | |||
<label> Invoice Date </label> | |||
<p> {format(props.invoice.date, 'dd MMMM yyyy')} </p> | |||
<p> {format(new Date(props.invoice.date), 'dd MMMM yyyy')} </p> | |||
</li> | |||
<li> | |||
@@ -117,7 +117,7 @@ export const InvoiceCard: React.FC<OwnProps> = (props) => { | |||
})}></IonInput> | |||
</div> | |||
{props.invoice.status !== 'cancelled' && props.invoice.status !== 'paid' && <div className={styles.buttonsHolder}> | |||
{(props.invoice.status !== 'cancelled' && props.invoice.status !== 'paid' || formInputs.dateOfPayment !== props.invoice.dateOfPayment || formInputs.dateOfPayment !== props.invoice.date) && <div className={styles.buttonsHolder}> | |||
<IonButton fill={'outline'} className={styles.cancel} shape={'round'}> Cancel Invoice </IonButton> | |||
<IonButton fill={'solid'} className={styles.approve + ' ' + (formInputs.dateOfPayment && formInputs.referenceNumber ? '' : styles.disabled)} shape={'round'} | |||
onClick={() => setShowDetails(false)}> Paid </IonButton> |
@@ -1,42 +0,0 @@ | |||
%card { | |||
background-color: white; | |||
border: 1px solid var(--card-outline); | |||
overflow: hidden; | |||
border-radius: 20px; | |||
display: flex; | |||
margin: 20px auto; | |||
} | |||
%commonIonInput { | |||
font-size: 14px; | |||
color: var(--black); | |||
--padding-top: 5px; | |||
--padding-end: 0; | |||
--padding-bottom: 5px; | |||
--padding-start: 0px; | |||
} | |||
%formSubmitIonButton { | |||
width: calc(50% - 10px); | |||
display: block; | |||
margin: 0 auto; | |||
height: 40px; | |||
font-size: 13px; | |||
letter-spacing: 0.5px; | |||
&.cancel { | |||
--border-width: 1px; | |||
--border-color: var(--black); | |||
color: var(--black); | |||
} | |||
&.approve { | |||
--background: var(--teal); | |||
} | |||
&.disabled { | |||
pointer-events: none; | |||
filter: grayscale(100%); | |||
} | |||
} |
@@ -1 +0,0 @@ | |||
export {}; |
@@ -0,0 +1,10 @@ | |||
import React from 'react'; | |||
import styles from './invoice.module.scss'; | |||
import { format } from 'date-fns'; | |||
export const TransactionCard: React.FC = () => { | |||
return <div className={styles.card}> | |||
</div> | |||
} |
@@ -24,9 +24,13 @@ | |||
} | |||
} | |||
.upfold { | |||
.dataBoard { | |||
background-color: var(--black); | |||
border-bottom-left-radius: 30px; | |||
position: sticky; | |||
position: -webkit-sticky; | |||
top: calc(98px - 255px); | |||
z-index: 1; | |||
} | |||
.segments { | |||
@@ -100,7 +104,7 @@ | |||
} | |||
} | |||
.actions { | |||
.quickDraw { | |||
white-space: nowrap; | |||
overflow-x: auto; | |||
padding: 15px 20px; | |||
@@ -128,34 +132,44 @@ | |||
} | |||
} | |||
.allTransactionsContainer { | |||
.dashboardContainer { | |||
position: relative; | |||
background-color: var(--black); | |||
} | |||
.allTransactions { | |||
background-color: white; | |||
border-top-right-radius: 30px; | |||
} | |||
.transactionCard { | |||
padding: 20px; | |||
box-shadow: 0px 10px 10px -10px var(--light-grey); | |||
header { | |||
display: flex; | |||
align-items: center; | |||
justify-content: space-between; | |||
&::before { | |||
content: ''; | |||
position: absolute; | |||
left: 0; | |||
top: 0; | |||
width: 100%; | |||
height: 100%; | |||
background-color: white; | |||
border-top-right-radius: 30px; | |||
} | |||
h5 { | |||
font-size: 12px; | |||
font-weight: 500; | |||
color: var(--grey); | |||
} | |||
& > * { | |||
position: relative; | |||
} | |||
a { | |||
color: var(--teal); | |||
font-size: 12px; | |||
.dashboardContainerSegment { | |||
padding: 20px; | |||
box-shadow: 0px 10px 10px -10px var(--light-grey); | |||
header { | |||
display: flex; | |||
align-items: center; | |||
justify-content: space-between; | |||
h5 { | |||
font-size: 12px; | |||
font-weight: 500; | |||
color: var(--grey); | |||
} | |||
a { | |||
color: var(--teal); | |||
font-size: 12px; | |||
} | |||
} | |||
} | |||
} |
@@ -2,12 +2,12 @@ import { IonContent, IonPage } from '@ionic/react'; | |||
import { ReactComponent as CogIcon } from 'ionicons/dist/svg/cog-outline.svg'; | |||
import { ReactComponent as LineChartIcon } from 'ionicons/dist/svg/stats-chart.svg'; | |||
import styles from './accounts.module.scss'; | |||
import { InvoiceCard } from '../../components/passbook/invoice-card/invoice'; | |||
import { InvoiceCard } from '../../components/invoice-card/invoice'; | |||
const sampleInvoiceData = [{ | |||
invoice: { | |||
id: '2021-22/50', | |||
date: new Date(), | |||
date: new Date().toString(), | |||
status: 'due', | |||
}, | |||
client: { | |||
@@ -24,10 +24,8 @@ const sampleInvoiceData = [{ | |||
}, { | |||
invoice: { | |||
id: '2021-22/51', | |||
date: new Date(), | |||
status: 'paid', | |||
dateOfPayment: new Date(), | |||
referenceNumber: '23226675560' | |||
date: new Date().toString(), | |||
status: 'over due', | |||
}, | |||
client: { | |||
name: 'TechM', | |||
@@ -51,7 +49,8 @@ const Accounts: React.FC = () => { | |||
<button> <CogIcon /> </button> | |||
</header> | |||
<section className={styles.upfold}> | |||
<section className={styles.dataBoard}> | |||
<section className={styles.segments}> | |||
<button className={styles.active}> Sep </button> | |||
<button> 1Q </button> | |||
@@ -71,7 +70,7 @@ const Accounts: React.FC = () => { | |||
</li> | |||
</ul> | |||
<ul className={styles.actions}> | |||
<ul className={styles.quickDraw}> | |||
<li> | |||
<button> </button> | |||
<label> Add Expense </label> | |||
@@ -95,21 +94,54 @@ const Accounts: React.FC = () => { | |||
</ul> | |||
</section> | |||
<div className={styles.allTransactionsContainer}> | |||
<section className={styles.allTransactions}> | |||
<div className={styles.transactionCard}> | |||
<header> | |||
<h5> Pending Invoices </h5> | |||
<a> See All </a> | |||
</header> | |||
{sampleInvoiceData.map((invoice, key) => { | |||
return <InvoiceCard key={key} invoice={invoice.invoice} client={invoice.client} /> | |||
})} | |||
</div> | |||
</section> | |||
<div className={styles.dashboardContainer}> | |||
<div className={styles.dashboardContainerSegment}> | |||
<header> | |||
<h5> Pending Invoices </h5> | |||
<a> See All </a> | |||
</header> | |||
{sampleInvoiceData.map((invoice, key) => { | |||
return <InvoiceCard key={key} invoice={invoice.invoice} client={invoice.client} /> | |||
})} | |||
</div> | |||
<div className={styles.dashboardContainerSegment}> | |||
<header> | |||
<h5> Pending Invoices </h5> | |||
<a> See All </a> | |||
</header> | |||
{sampleInvoiceData.map((invoice, key) => { | |||
return <InvoiceCard key={key} invoice={invoice.invoice} client={invoice.client} /> | |||
})} | |||
</div> | |||
<div className={styles.dashboardContainerSegment}> | |||
<header> | |||
<h5> Pending Invoices </h5> | |||
<a> See All </a> | |||
</header> | |||
{sampleInvoiceData.map((invoice, key) => { | |||
return <InvoiceCard key={key} invoice={invoice.invoice} client={invoice.client} /> | |||
})} | |||
</div> | |||
<div className={styles.dashboardContainerSegment}> | |||
<header> | |||
<h5> Pending Invoices </h5> | |||
<a> See All </a> | |||
</header> | |||
{sampleInvoiceData.map((invoice, key) => { | |||
return <InvoiceCard key={key} invoice={invoice.invoice} client={invoice.client} /> | |||
})} | |||
</div> | |||
</div> | |||
</IonContent> | |||
</IonPage> | |||
); | |||