Migrate from Firebase to file-based storage system
- Remove Firebase dependency and all Firebase code - Implement local file-based storage with encryption - Create custom authentication system with password hashing - Add API routes for auth (register/login) and data operations - Create FileStorageService for server-side file I/O - Add AuthService for client-side authentication wrapper - Update all components to use new storage system - Add comprehensive documentation (FILE_STORAGE.md, MIGRATION_SUMMARY.md) - Improve security with AES-GCM encryption and SHA-256 password hashing - Add ErrorBoundary component for better error handling - Fix multiple bugs: date serialization, transaction deletion, envelope calculations
This commit is contained in:
1 parent
174b247c6d
commit
959249ab22
22 files changed
+1538
-1157
No files matched your search
@@ -107,7 +107,7 @@ export default function GetPaid({ accounts, envelopes, onIncomeAdded, onAccountU
|
||||
|
||||
// Add the main paycheck transaction to the account
|
||||
transactions.push({
|
||||
id: `paycheck-${Date.now()}`,
|
||||
id: crypto.randomUUID(),
|
||||
amount: paycheckAmount,
|
||||
description: description || 'Paycheck',
|
||||
date: new Date(),
|
||||
@@ -118,7 +118,7 @@ export default function GetPaid({ accounts, envelopes, onIncomeAdded, onAccountU
|
||||
Object.entries(distribution).forEach(([envelopeId, allocatedAmount]) => {
|
||||
if (allocatedAmount > 0) {
|
||||
transactions.push({
|
||||
id: `allocation-${envelopeId}-${Date.now()}`,
|
||||
id: crypto.randomUUID(),
|
||||
envelopeId,
|
||||
amount: allocatedAmount,
|
||||
description: `Paycheck allocation - ${envelopes.find(e => e.id === envelopeId)?.name}`,
|
||||
@@ -374,52 +374,6 @@ export default function GetPaid({ accounts, envelopes, onIncomeAdded, onAccountU
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Default Amount */}
|
||||
{selectedAccountId && (
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowDefaultAmountField(!showDefaultAmountField)}
|
||||
className="text-sm text-blue-600 hover:underline mb-2"
|
||||
>
|
||||
{showDefaultAmountField ? 'Hide' : 'Set'} Default Paycheck Amount
|
||||
</button>
|
||||
|
||||
{showDefaultAmountField && (
|
||||
<div className="bg-gray-50 rounded-lg p-4 mb-4">
|
||||
<h4 className="font-medium text-gray-900 mb-3">Default Paycheck Amount</h4>
|
||||
<div className="flex items-center space-x-2">
|
||||
<input
|
||||
type="number"
|
||||
step="0.01"
|
||||
value={defaultAmountInput}
|
||||
onChange={(e) => setDefaultAmountInput(e.target.value)}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||
placeholder="0.00"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleSetDefaultAmount}
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"
|
||||
>
|
||||
Set Default
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="mt-3">
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleUseDefaultAmount}
|
||||
className="w-full px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700"
|
||||
>
|
||||
Use Default Amount
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Actions */}
|
||||
<div className="flex justify-end space-x-3 pt-4 border-t">
|
||||
<button
|
||||
|
||||
Reference in new issue
Block a user