-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Zackaria-Slimane/edits
Routing fixes
- Loading branch information
Showing
7 changed files
with
217 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#!/bin/bash | ||
echo "cleaning up old files and cache >>>" | ||
cd . | ||
rm -rf ./node_modules | ||
rm -rf ./build | ||
|
||
echo "installing dependencies >>>" | ||
npm ci | ||
|
||
echo "starting project >>>" | ||
npm run dev |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,106 @@ | ||
import { useState, Fragment } from "react"; | ||
import { Dialog, Transition } from "@headlessui/react"; | ||
import { Form, Link } from "react-router-dom"; | ||
import { FaRegTrashCan, FaMoneyCheckDollar } from "react-icons/fa6"; | ||
import { EditBudget } from "../components/EditBudget"; | ||
import { FaRegTrashCan, FaMoneyCheckDollar, FaPen } from "react-icons/fa6"; | ||
import { calculateSpentByBudget, formatCurrency, formatPercentage } from "../helpers"; | ||
|
||
export function BudgetItem({ budget, showDelete = false }) { | ||
const { id, name, amount } = budget; | ||
const spent = calculateSpentByBudget(id); | ||
const [showBudgetForm, setShowBudgetForm] = useState(false); | ||
|
||
function toggleBudgetForm() { | ||
console.log("toggleBudgetForm"); | ||
setShowBudgetForm(!showBudgetForm); | ||
} | ||
|
||
return ( | ||
<div className='budget mt-6 grid auto-cols-fr gap-6 border-fluo rounded-2xl p-4 border-2 text-alice'> | ||
<div className='progress-text'> | ||
<h3>{name}</h3> | ||
<p>{formatCurrency(amount)} Budgeted</p> | ||
</div> | ||
<> | ||
<Transition appear show={showBudgetForm} as={Fragment}> | ||
<Dialog as='div' className='relative z-10 sm:w-[600px]' onClose={toggleBudgetForm}> | ||
<Transition.Child | ||
as={Fragment} | ||
enter='ease-out duration-300' | ||
enterFrom='opacity-0' | ||
enterTo='opacity-100' | ||
leave='ease-in duration-200' | ||
leaveFrom='opacity-100' | ||
leaveTo='opacity-0'> | ||
<div className='fixed inset-0 bg-black/25' /> | ||
</Transition.Child> | ||
|
||
<progress max={amount} value={spent}> | ||
{formatPercentage(spent / amount)} | ||
</progress> | ||
<div className='progress-text'> | ||
<small>{formatCurrency(spent)} spent</small> | ||
<small className={`${amount - spent < 0 ? "text-tomato" : "text-alice"}`}> | ||
{formatCurrency(amount - spent)} remaining | ||
</small> | ||
</div> | ||
{showDelete ? ( | ||
<div className='flex flex-wrap gap-4'> | ||
<Form | ||
method='post' | ||
action='delete' | ||
onSubmit={(event) => { | ||
if (!confirm("Are you sure you want to permanently delete this budget?")) { | ||
event.preventDefault(); | ||
} | ||
}}> | ||
<button | ||
type='submit' | ||
className='px-6 py-1 flex gap-2 bg-alice items-center rounded-md hover:bg-tomato transition-all duration-300 max-w-[230px]'> | ||
<span className='text-lg text-navy'>Delete Budget</span> | ||
<FaRegTrashCan className='w-5 h-5 text-navy' /> | ||
</button> | ||
</Form> | ||
<div className='fixed inset-0 overflow-y-auto'> | ||
<div className='flex min-h-full items-center justify-center p-4 text-center'> | ||
<Transition.Child | ||
as={Fragment} | ||
enter='ease-out duration-300' | ||
enterFrom='opacity-0 scale-95' | ||
enterTo='opacity-100 scale-100' | ||
leave='ease-in duration-200' | ||
leaveFrom='opacity-100 scale-100' | ||
leaveTo='opacity-0 scale-95'> | ||
<Dialog.Panel className='w-full max-w-[600px] transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all'> | ||
<EditBudget budgetId={id} /> | ||
</Dialog.Panel> | ||
</Transition.Child> | ||
</div> | ||
</div> | ||
</Dialog> | ||
</Transition> | ||
<div className='budget mt-6 grid auto-cols-fr gap-6 border-fluo rounded-2xl p-4 border-2 text-alice'> | ||
<div className='progress-text'> | ||
<h3>{name}</h3> | ||
<p>{formatCurrency(amount)} Budgeted</p> | ||
</div> | ||
) : ( | ||
<div className='flex flex-wrap gap-4'> | ||
<Link | ||
to={`/budget/${id}`} | ||
className='px-6 py-1 flex gap-2 bg-alice items-center rounded-md hover:bg-fluo transition-all duration-300 max-w-[230px]'> | ||
<span className='text-lg text-navy'>View Details</span> | ||
<FaMoneyCheckDollar className='w-5 h-5 text-navy' /> | ||
</Link> | ||
|
||
<progress max={amount} value={spent}> | ||
{formatPercentage(spent / amount)} | ||
</progress> | ||
<div className='progress-text'> | ||
<small>{formatCurrency(spent)} spent</small> | ||
<small className={`${amount - spent < 0 ? "text-tomato" : "text-alice"}`}> | ||
{formatCurrency(amount - spent)} remaining | ||
</small> | ||
</div> | ||
)} | ||
</div> | ||
{showDelete ? ( | ||
<div className='flex flex-wrap gap-4'> | ||
<Form | ||
method='post' | ||
action='delete' | ||
onSubmit={(event) => { | ||
if (!confirm("Are you sure you want to permanently delete this budget?")) { | ||
event.preventDefault(); | ||
} | ||
}}> | ||
<button | ||
type='submit' | ||
className='px-6 py-1 flex gap-2 bg-alice items-center rounded-md hover:bg-tomato transition-all duration-300 max-w-[230px]'> | ||
<span className='text-md text-navy'>Delete Budget</span> | ||
<FaRegTrashCan className='w-5 h-5 text-navy' /> | ||
</button> | ||
</Form> | ||
<div> | ||
<button | ||
onClick={toggleBudgetForm} | ||
type='button' | ||
className='px-6 py-1 flex gap-2 bg-alice items-center rounded-md hover:bg-sunny transition-all duration-300 max-w-[230px]'> | ||
<span className='text-md text-navy'>Edit Budget</span> | ||
<FaPen className='w-4 h-4 text-navy' /> | ||
</button> | ||
</div> | ||
</div> | ||
) : ( | ||
<div className='flex flex-wrap gap-4'> | ||
<Link | ||
to={`/budget/${id}`} | ||
className='px-6 py-1 flex gap-2 bg-alice items-center rounded-md hover:bg-fluo transition-all duration-300 max-w-[230px]'> | ||
<span className='text-lg text-navy'>View Details</span> | ||
<FaMoneyCheckDollar className='w-5 h-5 text-navy' /> | ||
</Link> | ||
</div> | ||
)} | ||
</div> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { useState, useEffect, useRef } from "react"; | ||
import { useFetcher } from "react-router-dom"; | ||
import { getAllMatchingItems } from "../helpers"; | ||
|
||
export function EditBudget({ budgetId }) { | ||
const fetcher = useFetcher(); | ||
const isSubmitting = fetcher.state === "submitting"; | ||
const formRef = useRef(); | ||
const focusRef = useRef(); | ||
const [budget, setBudget] = useState({}); | ||
|
||
useEffect(() => { | ||
console.log("budgetId", budgetId); | ||
async function getBudget() { | ||
let result = await getAllMatchingItems({ | ||
category: "budgets", | ||
key: "id", | ||
value: budgetId, | ||
})[0]; | ||
console.log("budget", budget); | ||
setBudget(result); | ||
} | ||
getBudget(); | ||
}, []); | ||
|
||
useEffect(() => { | ||
if (!isSubmitting) { | ||
formRef.current.reset(); | ||
focusRef.current.focus(); | ||
} | ||
}, [isSubmitting]); | ||
|
||
return ( | ||
<div className='font-jetBrain max-w-[600px] p-6 bg-white rounded-2xl flex-1'> | ||
<h2 className='text-navy text-2xl'>Edit budget</h2> | ||
<fetcher.Form method='post' className='grid gap-4 p-4' ref={formRef}> | ||
<div className='grid gap-4'> | ||
<label className='text-navy text-lg' htmlFor='newBudget'> | ||
Budget Name | ||
</label> | ||
<input | ||
className='text-navy rounded-lg ring-2 ring-navy py-2 px-4' | ||
type='text' | ||
name='newBudget' | ||
id='newBudget' | ||
placeholder={budget.name} | ||
required | ||
ref={focusRef} | ||
/> | ||
</div> | ||
<div className='grid gap-4'> | ||
<label className='text-navy text-lg' htmlFor='newBudgetAmount'> | ||
Amount | ||
</label> | ||
<input | ||
className='text-navy rounded-lg ring-2 ring-navy py-2 px-4' | ||
type='number' | ||
step='0.01' | ||
name='newBudgetAmount' | ||
id='newBudgetAmount' | ||
placeholder={budget.amount} | ||
required | ||
inputMode='decimal' | ||
/> | ||
</div> | ||
<input type='hidden' name='_action' value='editBudget' /> | ||
<button | ||
type='submit' | ||
className='px-6 py-2 mt-2 flex gap-2 bg-fluo items-center rounded-md hover:bg-fluo/80 transition-all duration-300 max-w-[230px]' | ||
disabled={isSubmitting}> | ||
{isSubmitting ? ( | ||
<span className='text-lg'>Submitting…</span> | ||
) : ( | ||
<> | ||
<span className='w-full text-md text-navy'>Edit budget</span> | ||
</> | ||
)} | ||
</button> | ||
</fetcher.Form> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters