Skip to content

Commit

Permalink
feat(mpesa): Add dashboard components
Browse files Browse the repository at this point in the history
Co-authored-by: Joseph Mania <[email protected]>
  • Loading branch information
shadrak98 and maniamartial committed Jan 20, 2025
1 parent aa1a0aa commit 7e38127
Show file tree
Hide file tree
Showing 17 changed files with 1,870 additions and 85 deletions.
3 changes: 2 additions & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,7 @@
"Vetur",
"Mpesa",
"msisdn",
"stkpush"
"stkpush",
"Pesa"
]
}
155 changes: 155 additions & 0 deletions dashboard/src2/components/billing/AddExchangeRate.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<template>
<Dialog :options="{ title: 'Add Currency Exchange', size: 'lg' }">
<template #body-content>
<div class="grid grid-cols-2 gap-4">
<FormControl
label="From Currency"
v-model="fromCurrency"
type="autocomplete"
variant="subtle"
:disabled="false"
:options="currencySymbols"
name="from_currency"
class="mb-5"
required
/>

<FormControl
label="To Currency"
v-model="toCurrency"
name="to_currency"
type="autocomplete"
variant="subtle"
:disabled="false"
:options="currencySymbols"
class="mb-5"
required
/>

<FormControl
label="Exchange Rate"
v-model="exchangeRate"
name="exchange_rate"
autocomplete="off"
class="mb-5"
type="number"
required
/>

<DatePicker
v-model="date"
variant="subtle"
name="date"
placeholder="Placeholder"
:disabled="false"
label="Date"
/>
</div>

<div class="mt-4 flex w-full items-center justify-center">
<Button
@click="saveExchangeRate"
class="justify-center w-full font-bold"
variant="solid"
type="primary"
>Add Currency Exchange</Button
>
</div>
</template>
<ErrorMessage class="mt-2" :message="ErrorMessage" />
</Dialog>
</template>

<script>
import { toast } from 'vue-sonner';
import { frappeRequest } from 'frappe-ui';
import { DashboardError } from '../../utils/error';
import FormControl from 'frappe-ui/src/components/FormControl.vue';
import DatePicker from 'frappe-ui/src/components/DatePicker.vue';
import ErrorMessage from 'frappe-ui/src/components/ErrorMessage.vue';
export default {
name: 'AddExchangeRate',
components: { DatePicker },
data() {
return {
fromCurrency: '',
toCurrency: '',
date: '',
exchangeRate: '',
currencySymbols: [],
};
},
resources: {
addCurrencyExchange() {
return {
url: 'press.api.regional_payments.mpesa.utils.create_exchange_rate',
params: {
from_currency: this.fromCurrency,
to_currency: this.toCurrency,
exchange_rate: this.exchangeRate,
date: this.date,
},
validate() {
if (
!this.fromCurrency ||
!this.toCurrency ||
!this.exchangeRate ||
!this.date
) {
toast.error('All fields are required');
return false;
}
},
async onSuccess() {
if (data) {
toast.success('Currency Exchange Added Successfully');
this.$emit('close');
} else {
toast.error('Failed to add currency exchange');
}
},
};
},
},
methods: {
async saveExchangeRate() {
try {
const response = await this.$resources.addCurrencyExchange.submit();
if (response) {
this.$toast.success('Currency Exchange Added Successfully');
this.fromCurrency = '';
this.toCurrency = '';
this.exchangeRate = '';
this.date = '';
}
this.$emit('closeDialog');
} catch (error) {
console.log(error);
this.$toast.error(`Error adding currency exchange: ${error.message}`);
}
},
async fetchCurrencySymbols() {
try {
const response = await frappeRequest({
url: '/api/method/press.api.regional_payments.mpesa.utils.fetch_currencies',
method: 'GET',
});
if (Array.isArray(response)) {
this.currencySymbols = response;
} else {
this.ErrorMessage = 'No currency symbols found';
}
} catch (error) {
this.ErrorMessage = `Error fetching currency symbols: ${error.message}`;
}
},
},
mounted() {
this.fetchCurrencySymbols();
},
};
</script>
179 changes: 179 additions & 0 deletions dashboard/src2/components/billing/mpesa/AddMpesaCredentials.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
<template>
<Dialog :options="{ title: 'Add M-Pesa Credentials', size: 'lg' }">
<template #body-content>
<div class="grid grid-cols-2 gap-4">
<FormControl
label="Payment Gatway Name"
v-model="paymentGatewayName"
name="consumer_key"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Mpesa setting Name"
required
/>

<FormControl
label="Consumer Key"
v-model="consumerKey"
name="consumer_key"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Consumer Key"
required
/>

<FormControl
label="Consumer Secret"
v-model="consumerSecret"
name="consumer_secret"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Consumer Secret"
required
/>

<FormControl
label="Pass Key"
v-model="passKey"
name="pass_key"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Pass Key"
required
/>

<FormControl
label="Short Code"
v-model="shortCode"
name="short_code"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Short Code"
required
/>

<FormControl
label="Initiator Name"
v-model="initiatorName"
name="initiator_name"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Initiator Name"
required
/>

<FormControl
label="Security Credential"
v-model="securityCredential"
name="security_credential"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Security Credential"
required
/>

<FormControl
label="Till Number"
v-model="tillNumber"
name="till_number"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Till Number"
required
/>

<div class="flex items-center">
<input v-model="sandBox" type="checkbox" class="mr-2" />
<label class="text-sm font-medium text-gray-700">Sandbox Mode</label>
</div>
</div>

<div class="mt-4 flex w-full bg-red-300 items-center justify-center">
<Button
@click="saveMpesaCredentials"
variant="solid"
class="justify-center w-full font-bold"
>Save</Button
>
</div>
</template>
</Dialog>
</template>

<script>
import { toast } from 'vue-sonner';
import { DashboardError } from '../../../utils/error';
import { ErrorMessage } from 'frappe-ui';
export default {
name: 'AddMpesaCredentials',
data() {
return {
consumerKey: '',
paymentGatewayName: '',
consumerSecret: '',
passKey: '',
shortCode: '',
initiatorName: '',
securityCredential: '',
tillNumber: '',
sandBox: false,
};
},
resources: {
createMpesaSetup() {
return {
url: 'press.api.regional_payments.mpesa.utils.create_mpesa_setup',
params: {
payment_gateway_name: this.paymentGatewayName,
consumer_key: this.consumerKey,
consumer_secret: this.consumerSecret,
pass_key: this.passKey,
short_code: this.shortCode,
initiator_name: this.initiatorName,
security_credential: this.securityCredential,
till_number: this.tillNumber,
sandbox: this.sandBox,
},
validate() {
if (
!this.paymentGatewayName ||
!this.consumerKey ||
!this.consumerSecret ||
!this.passKey ||
!this.shortCode ||
!this.initiatorName ||
!this.securityCredential
) {
return 'All fields are required';
}
},
async onSuccess(data) {
if (data) {
toast.success('M-Pesa credentials saved', data);
} else {
toast.error('Error saving M-Pesa credentials');
}
},
};
},
},
methods: {
async saveMpesaCredentials() {
try {
const response = await this.$resources.createMpesaSetup.submit();
this.$emit('closeDialog');
} catch (error) {
this.$toast.error(`Error saving M-Pesa credentials: ${error.message}`);
}
},
},
};
</script>
Loading

0 comments on commit 7e38127

Please sign in to comment.