Skip to content

Commit

Permalink
restructured db + filter logic changed
Browse files Browse the repository at this point in the history
  • Loading branch information
ShinichiShi committed Sep 20, 2024
1 parent 7d463bc commit 4c306d4
Show file tree
Hide file tree
Showing 14 changed files with 357 additions and 260 deletions.
11 changes: 8 additions & 3 deletions client/src/components/Buyer/Contract/ContractList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { db } from '../../../../firebase';
import { doc, getDoc } from 'firebase/firestore';
import ContractStatus from './ContractStatus';
import { useTranslation } from 'react-i18next';

import ReactLoading from 'react-loading';
const ContractList = () => {
const [contracts, setContracts] = useState([]);
const [loading, setLoading] = useState(true);
Expand All @@ -21,7 +21,7 @@ const ContractList = () => {
}

try {
const buyerRef = doc(db, 'buyers', currentUser.uid);
const buyerRef = doc(db, 'users', currentUser.uid);
const docSnap = await getDoc(buyerRef);

if (docSnap.exists()) {
Expand All @@ -42,7 +42,12 @@ const ContractList = () => {
}, [currentUser,t]);

if (loading) {
return <div className="text-center py-4">{t('loading_contracts')}....</div>;
return (
<div className="text-center py-4 flex items-center h-full justify-center">
<ReactLoading type={'spinningBubbles'} color={'#00b300'} height={'5%'} width={'5%'} />
Loading...
</div>
);
}

if (error) {
Expand Down
41 changes: 22 additions & 19 deletions client/src/components/Buyer/Contract/ContractStatus.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ToastContainer, toast } from 'react-toastify';
import { useTranslation } from 'react-i18next';
import { loadStripe } from '@stripe/stripe-js';
import { Elements } from '@stripe/react-stripe-js';
import { FaCcStripe } from "react-icons/fa6";

const stripePromise = loadStripe(import.meta.env.VITE_STRIPE_PUBLISH_KEY); // Publishable Key from your Stripe dashboard
const SERVER_PORT = import.meta.env.VITE_SERVER_PORT;
Expand Down Expand Up @@ -64,12 +65,12 @@ export default function ContractStatus({ contract }) {
};

// Initialize web3
// initWeb3();
initWeb3();

// Listen for account changes
// if (window.ethereum) {
// window.ethereum.on('accountsChanged', handleAccountChange);
// }
if (window.ethereum) {
window.ethereum.on('accountsChanged', handleAccountChange);
}

// Cleanup event listener on unmount
return () => {
Expand Down Expand Up @@ -136,7 +137,7 @@ export default function ContractStatus({ contract }) {

const updateContractStatusInFirebase = async (contractId) => {
try {
const buyerRef = doc(db, 'buyers', currentUser.uid);
const buyerRef = doc(db, 'users', currentUser.uid);
const docSnap = await getDoc(buyerRef);

if (!docSnap.exists()) {
Expand Down Expand Up @@ -243,7 +244,7 @@ export default function ContractStatus({ contract }) {

const updateContractPaymentInFirebase = async (contractId) => {
try {
const buyerRef = doc(db, 'buyers', currentUser.uid);
const buyerRef = doc(db, 'users', currentUser.uid);
const docSnap = await getDoc(buyerRef);

if (!docSnap.exists()) {
Expand Down Expand Up @@ -319,11 +320,11 @@ export default function ContractStatus({ contract }) {
<div className="absolute w-full inset-0 bg-black opacity-50"></div>
<div className="bg-white p-6 w-full rounded-lg shadow-lg z-10">
<div>
<strong>{t('contract_id')}:</strong>{' '}
<strong>{t('contract_id')}</strong>{' '}
{contract.contractId || 'N/A'}
</div>
<div>
<strong>{t('crop')}:</strong> {contract.crop || 'N/A'}
<strong>{t('crop')}</strong> {contract.crop || 'N/A'}
</div>
<div>
<strong>{t('farmer_name')}:</strong>{' '}
Expand All @@ -333,42 +334,42 @@ export default function ContractStatus({ contract }) {
<strong>{t('farmer_name')}</strong> {contract.farmerId || 'N/A'}
</div>
<div>
<strong>{t('buyer_name')}:</strong> {contract.buyerName || 'N/A'}
<strong>{t('buyer_name')}</strong> {contract.buyerName || 'N/A'}
</div>
<div>
<strong>{t('buyer_id')}:</strong> {contract.buyerId || 'N/A'}
<strong>{t('buyer_id')}</strong> {contract.buyerId || 'N/A'}
</div>
<div>
<strong>{t('final_date')}:</strong> {contract.date || 'N/A'}
</div>
<div>
<strong>{t('total_amount')}:</strong>{' '}
<strong>{t('total_amount')}</strong>{' '}
{contract.totalAmt + ' ' + contract.unit || 'N/A'}
</div>
<div>
<strong>{t('installment_amount')}:</strong>{' '}
<strong>{t('installment_amount')}</strong>{' '}
{contract.installmentAmt + ' ' + contract.unit || 'N/A'}
</div>
<div>
<strong>{t('location')}:</strong> {contract.location || 'N/A'}
<strong>{t('location')}</strong> {contract.location || 'N/A'}
</div>
<div>
<strong>{t('status')}:</strong> {localContract.status || 'N/A'}
<strong>{t('status')}</strong> {localContract.status || 'N/A'}
</div>
<div>
<strong>{t('created_at')}:</strong>{' '}
<strong>{t('created_at')}</strong>{' '}
{formatDate(contract.createdAt)}
</div>
<div className="flex gap-2">
<button
className="mt-4 px-4 py-2 bg-blue-500 text-white rounded"
className="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
onClick={() => setShowModal(false)}
>
{t('close')}
</button>
{localContract.status === 'Created' && (
<button
className="mt-4 px-4 py-2 bg-blue-500 text-white rounded"
className="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
onClick={handleSignContract}
>
{t('sign_contract')}
Expand All @@ -377,10 +378,12 @@ export default function ContractStatus({ contract }) {
{localContract.status === 'Signed' && (
<Elements stripe={stripePromise}>
<button
className="mt-4 px-4 py-2 bg-blue-500 text-white rounded"
className="mt-4 px-4 py-2 bg-blue-500 flex items-center justify-center gap-2 text-white rounded hover:bg-blue-600 "
onClick={makeStripePayment}
>
{t('make_payment')}
<FaCcStripe />

Make Payment
</button>
</Elements>
)}
Expand Down
198 changes: 113 additions & 85 deletions client/src/components/Buyer/Contract/Download.jsx
Original file line number Diff line number Diff line change
@@ -1,94 +1,122 @@
import jsPDF from 'jspdf';
import PropTypes from 'prop-types';
function Download({formData}) {

const generatePDF = () => {
const doc = new jsPDF();

doc.setFontSize(16);
doc.text('BILATERAL CONTRACT AGREEMENT', 50, 20);

doc.setFontSize(12);

const lineHeight = 10; // Spacing between lines
const pageHeight = doc.internal.pageSize.height; // Get page height
let y = 30; // Starting y position for text

// Helper function to handle page breaks
const addText = (text, x, yPosition) => {
const textLines = doc.splitTextToSize(text, 180); // Wrap text within 180 units
textLines.forEach(line => {
if (yPosition + lineHeight > pageHeight - 10) { // Check if space is available
doc.addPage(); // Add a new page
yPosition = 20; // Reset y position for new page
}
doc.text(line, x, yPosition);
yPosition += lineHeight;
});
return yPosition; // Return updated y position
};

y = addText('THIS AGREEMENT is made on the 9th day of September, 2024, between:', 10, y);
y = addText(`${formData.buyerName}, an individual/entity with ID ${formData.buyerId},`, 10, y);
y = addText('hereafter referred to as the "Buyer/Investor," and', 10, y);
y = addText(`${formData.farmerName}, an individual with ID ${formData.farmerId},`, 10, y);
y = addText('hereafter referred to as the "Farmer."', 10, y);

y = addText(`Whereas the Buyer/Investor is involved in promoting and producing high-quality ${formData.crop}`, 10, y);
y = addText(`in ${formData.location} and is committed to supporting the agricultural sector for improved`, 10, y);
y = addText('quality and yield.', 10, y);

y = addText(`The Farmer, ${formData.farmerName}, seeks technical and financial assistance from the`, 10, y);
y = addText('Buyer/Investor for growing wheat, ensuring quality crops and fulfilling agreed terms.', 10, y);

y = addText('Now, Therefore, in consideration of the mutual covenants and promises contained herein,', 10, y);
y = addText('the parties agree as follows:', 10, y);

doc.setFontSize(14);
y = addText('Obligations of the Buyer/Investor', 10, y);
doc.setFontSize(12);

y = addText('Technical Support:', 10, y);
y = addText('The Buyer will provide the Farmer with agricultural advice on modern farming practices, crop', 10, y);
y = addText('management, and pest control to boost productivity.', 10, y);

y = addText('Supply of Inputs:', 10, y);
y = addText(`The Buyer agrees to provide all necessary inputs for ${formData.crop} production during the growing season,`, 10, y);
y = addText('subject to the following conditions:', 10, y);
y = addText(`- Loan Limits: Inputs will be supplied within pre-agreed limits, tailored to the Farmer's needs.`, 10, y);
y = addText(`- Category-Based Assistance: Fertilizers, seeds, and pesticides provided based on land size and needs.`, 10, y);

// doc.setFontSize(14);
doc.setFontSize(12);
y = addText('Pricing and Payment:', 10, y);
y = addText(`The Buyer shall offer an indicative price of Rupees ${formData.totalAmt} per quintal for the ${formData.crop} crop,`, 10, y);
y = addText(`and pay an installment of Rupees ${formData.installmentAmt} at specified intervals to cover input costs.`, 10, y);

doc.setFontSize(14);
y = addText('Obligations of the Farmer', 10, y);
doc.setFontSize(12);
y = addText(`Cultivation of ${formData.crop}:`, 10, y);
y = addText(`The Farmer agrees to cultivate ${formData.crop} on their farmland under the guidance of the Buyer.`, 10, y);
y = addText('Sustainable farming practices, timely sowing, weeding, and harvesting will be ensured.', 10, y);

y = addText('Exclusive Sale of Produce:', 10, y);
y = addText(`The Farmer agrees to sell the entire ${formData.crop} crop exclusively to the Buyer/Investor unless`, 10, y);
y = addText('authorized in writing to sell to a third party.', 10, y);

doc.setFontSize(14);
y = addText('Mutual Agreements', 10, y);
doc.setFontSize(12);
y = addText('Monitoring and Reporting:', 10, y);
y = addText('The Buyer will conduct regular field visits. The Farmer will provide progress reports as requested.', 10, y);

y = addText('Conflict Resolution:', 10, y);
y = addText(`Disputes will be resolved through mutual discussion or mediation. Jurisdiction: ${formData.location}.`, 10, y);

doc.setFontSize(14);
y = addText('Term of Agreement', 10, y);
doc.setFontSize(12);
y = addText(`This agreement is valid for the current ${formData.crop} growing season, with an option for renewal.`, 10, y);

doc.setFontSize(14);
y = addText('Signed:', 10, y);
doc.setFontSize(12);
y = addText(`${formData.buyerName} __________________`, 10, y);
y = addText('Buyer/Investor', 10, y);

y = addText(`${formData.farmerName} ________________`, 10, y);
y = addText('Farmer', 10, y);

doc.save(`Contract_Agreement_${formData.date}.pdf`);
};


import { useTranslation } from 'react-i18next';
function Download({ formData }) {
const { t } = useTranslation(); // Initialize translation function

const generatePDF = () => {
const doc = new jsPDF();

doc.setFontSize(12);
doc.text('BILATERAL CONTRACT AGREEMENT', 50, 20);
doc.text(`THIS AGREEMENT made on this ${formData.date}`, 20, 40);
doc.text(
`between ${formData.buyerName} with id ${formData.buyerId}`,
20,
50
);
doc.text(
`(hereafter described as the Buyer/Investor)`,
20,
60
);
doc.text(
`AND ${formData.farmerName} with id ${formData.farmerId} (hereafter described as the Farmer).`,
20,
70
);
doc.text(
`(hereafter described as the Farmer).`,
20,
80
);
doc.text(
`WHEREAS the Buyer/Investor is interested in the promotion of quality ${formData.crop}`,
20,
90
);
doc.text(`in ${formData.location}.`, 20, 80);
doc.text(
`AND WHEREAS the Farmer/Cooperative/Association requires assistance in growing ${formData.crop}`,
20,
100
);

doc.text(
`NOW THEREFORE THE Buyer and the Farmer/Cooperative/Association agree as follows:`,
20,
120
);

doc.text(`1. The Buyer agrees to provide the following:`, 20, 130);
doc.text(`a) Technical extension and research services.`, 30, 140);
doc.text(
`b) All inputs required during the growing season within loan limits.`,
30,
150
);
doc.text(
`c) An indicative price for the season's crop is ${formData.totalAmt}.`,
30,
160
);
doc.text(
`d) Pay an installment amount of ${formData.installmentAmt}.`,
30,
170
);
doc.text(
`2. The Farmer agrees to grow ${formData.crop} as per the Buyer's advice and not sell to another buyer.`,
20,
180
return(
<div className="max-w-md mx-auto p-8 bg-white shadow-md rounded-md mt-10">
<h2 className="text-2xl font-bold mb-4">Download Contract Pdf</h2>
<button
type="button"
className="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600"
onClick={generatePDF}
>
Generate Pdf
</button>
</div>
);
}

// Save or open the generated PDF
doc.save('Contract_Agreement.pdf');
};

return (
<div className="max-w-md mx-auto p-8 bg-white shadow-md rounded-md mt-10">
<h2 className="text-2xl font-bold mb-4">{t('download_contract_pdf')}</h2>
<button
type="button"
className="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600"
onClick={generatePDF}
>
{t('generate_pdf')}
</button>
</div>
);
}

Download.propTypes = {
formData: PropTypes.shape({
Expand Down
2 changes: 1 addition & 1 deletion client/src/components/Buyer/Contract/GenerateContract.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export default function GenerateContract() {
)}
{steps[currentStep - 1] === 'Sign via Metamask' && (
<>
<Metamask formData={formData} />
<Metamask formData={formData} setFormData={setFormData}/>
</>
)}
{steps[currentStep - 1] === 'Download Pdf' && (
Expand Down
Loading

0 comments on commit 4c306d4

Please sign in to comment.