Skip to content

Commit

Permalink
Add fully booked flag to cars in backend ; Add full to full and full …
Browse files Browse the repository at this point in the history
…to empty fuel policies
  • Loading branch information
aelassas committed Jan 22, 2025
1 parent b7a1ebc commit 0be204e
Show file tree
Hide file tree
Showing 22 changed files with 436 additions and 103 deletions.
3 changes: 3 additions & 0 deletions api/__tests__/car.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ describe('POST /api/create-car', () => {
multimedia: [bookcarsTypes.CarMultimedia.Bluetooth],
rating: 3,
comingSoon: true,
fullyBooked: true,
}
let res = await request(app)
.post('/api/create-car')
Expand Down Expand Up @@ -209,6 +210,7 @@ describe('PUT /api/update-car', () => {
multimedia: [bookcarsTypes.CarMultimedia.AndroidAuto],
rating: 4,
comingSoon: false,
fullyBooked: false,
}
let res = await request(app)
.put('/api/update-car')
Expand Down Expand Up @@ -247,6 +249,7 @@ describe('PUT /api/update-car', () => {
expect(car.multimedia).toStrictEqual(payload.multimedia)
expect(car.rating).toBe(payload.rating)
expect(car.comingSoon).toBe(payload.comingSoon)
expect(car.fullyBooked).toBe(payload.fullyBooked)

// test success (booking not found)
payload._id = testHelper.GetRandromObjectIdAsString()
Expand Down
3 changes: 2 additions & 1 deletion api/src/config/env.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,8 @@ export interface Car extends Document {

deposit: number
available: boolean
fullyBooked?: boolean
comingSoon?: boolean
type: bookcarsTypes.CarType
gearbox: bookcarsTypes.GearboxType
aircon: boolean
Expand All @@ -522,7 +524,6 @@ export interface Car extends Document {
rating?: number
trips: number
co2?: number
comingSoon?: boolean
}

/**
Expand Down
20 changes: 16 additions & 4 deletions api/src/controllers/carController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ export const update = async (req: Request, res: Response) => {
name,
minimumAge,
available,
fullyBooked,
comingSoon,
type,
locations,
dailyPrice,
Expand Down Expand Up @@ -105,14 +107,15 @@ export const update = async (req: Request, res: Response) => {
multimedia,
rating,
co2,
comingSoon,
} = body

car.supplier = new mongoose.Types.ObjectId(supplier)
car.minimumAge = minimumAge
car.locations = locations.map((l) => new mongoose.Types.ObjectId(l))
car.name = name
car.available = available
car.fullyBooked = fullyBooked
car.comingSoon = comingSoon
car.type = type as bookcarsTypes.CarType
car.dailyPrice = dailyPrice
car.discountedDailyPrice = discountedDailyPrice
Expand All @@ -139,7 +142,6 @@ export const update = async (req: Request, res: Response) => {
car.multimedia = multimedia
car.rating = rating
car.co2 = co2
car.comingSoon = comingSoon

await car.save()
return res.json(car)
Expand Down Expand Up @@ -663,11 +665,21 @@ export const getFrontendCars = async (req: Request, res: Response) => {
}

if (!includeAlreadyBookedCars) {
$match.$and!.push({ available: true })
$match.$and!.push({
$or: [
{ $and: [{ $or: [{ fullyBooked: false }, { fullyBooked: null }] }, { available: true }] },
{ $and: [{ $or: [{ fullyBooked: false }, { fullyBooked: null }] }, { available: false }] },
],
})
}

if (!includeComingSoonCars) {
$match.$and!.push({ $or: [{ comingSoon: false }, { comingSoon: null }] })
$match.$and!.push({
$or: [
{ $and: [{ $or: [{ comingSoon: false }, { comingSoon: null }] }, { available: true }] },
{ $and: [{ $or: [{ comingSoon: false }, { comingSoon: null }] }, { available: false }] },
],
})
}

if (fuelPolicy) {
Expand Down
11 changes: 10 additions & 1 deletion api/src/models/Car.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ const carSchema = new Schema<env.Car>(
required: [true, "can't be blank"],
index: true,
},
fullyBooked: {
type: Boolean,
default: false,
},
comingSoon: {
type: Boolean,
default: false,
Expand Down Expand Up @@ -111,7 +115,12 @@ const carSchema = new Schema<env.Car>(
},
fuelPolicy: {
type: String,
enum: [bookcarsTypes.FuelPolicy.LikeForLike, bookcarsTypes.FuelPolicy.FreeTank],
enum: [
bookcarsTypes.FuelPolicy.LikeForLike,
bookcarsTypes.FuelPolicy.FreeTank,
bookcarsTypes.FuelPolicy.FullToFull,
bookcarsTypes.FuelPolicy.FullToEmpty,
],
required: [true, "can't be blank"],
},
mileage: {
Expand Down
4 changes: 2 additions & 2 deletions backend/src/assets/css/car-list.css
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ section.car-list .empty-list {
}

section.car-list article div.car-info ul.extras-list li.car-coming-soon {
color: #0064c8;
color: #1f9201;
}

section.car-list article div.car-info ul.extras-list li.car-unavailable,
Expand Down Expand Up @@ -463,7 +463,7 @@ section.car-list .empty-list {
}

section.car-list article div.car-info ul.extras-list li.car-coming-soon {
color: #0064c8;
color: #1f9201;
}

section.car-list article div.car-info ul.extras-list li.car-unavailable,
Expand Down
12 changes: 12 additions & 0 deletions backend/src/common/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ export const getFuelPolicy = (type: string) => {
case bookcarsTypes.FuelPolicy.FreeTank:
return strings.FUEL_POLICY_FREE_TANK

case bookcarsTypes.FuelPolicy.FullToFull:
return strings.FUEL_POLICY_FULL_TO_FULL

case bookcarsTypes.FuelPolicy.FullToEmpty:
return strings.FUEL_POLICY_FULL_TO_EMPTY

default:
return ''
}
Expand Down Expand Up @@ -222,6 +228,12 @@ export const getFuelPolicyTooltip = (fuelPolicy: string) => {
case bookcarsTypes.FuelPolicy.FreeTank:
return strings.FUEL_POLICY_FREE_TANK_TOOLTIP

case bookcarsTypes.FuelPolicy.FullToFull:
return strings.FUEL_POLICY_FULL_TO_FULL_TOOLTIP

case bookcarsTypes.FuelPolicy.FullToEmpty:
return strings.FUEL_POLICY_FULL_TO_EMPTY_TOOLTIP

default:
return ''
}
Expand Down
8 changes: 8 additions & 0 deletions backend/src/components/CarList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,14 @@ const CarList = ({
</div>
</Tooltip>
</li>
{car.fullyBooked && (
<li className="car-unavailable">
<div className="car-info-list-item">
<UncheckIcon />
<span className="car-info-list-text">{strings.FULLY_BOOKED}</span>
</div>
</li>
)}
{car.comingSoon && (
<li className="car-coming-soon">
<div className="car-info-list-item">
Expand Down
132 changes: 115 additions & 17 deletions backend/src/components/FuelPolicyFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@ const FuelPolicyFilter = ({
const [allChecked, setAllChecked] = useState(false)
const [values, setValues] = useState<bookcarsTypes.FuelPolicy[]>([])

const automaticRef = useRef<HTMLInputElement>(null)
const manualRef = useRef<HTMLInputElement>(null)
const freeTankRef = useRef<HTMLInputElement>(null)
const likeForLikeRef = useRef<HTMLInputElement>(null)
const fullToFullRef = useRef<HTMLInputElement>(null)
const fullToEmptyRef = useRef<HTMLInputElement>(null)

useEffect(() => {
if (allChecked && automaticRef.current && manualRef.current) {
automaticRef.current.checked = true
manualRef.current.checked = true
if (allChecked && freeTankRef.current && likeForLikeRef.current && fullToFullRef.current && fullToEmptyRef.current) {
freeTankRef.current.checked = true
likeForLikeRef.current.checked = true
fullToFullRef.current.checked = true
fullToEmptyRef.current.checked = true
}
}, [allChecked])

Expand All @@ -43,7 +47,7 @@ const FuelPolicyFilter = ({
if ('checked' in e.currentTarget && e.currentTarget.checked) {
values.push(bookcarsTypes.FuelPolicy.FreeTank)

if (values.length === 2) {
if (values.length === allTypes.length) {
setAllChecked(true)
}
} else {
Expand Down Expand Up @@ -74,7 +78,7 @@ const FuelPolicyFilter = ({
if ('checked' in e.currentTarget && e.currentTarget.checked) {
values.push(bookcarsTypes.FuelPolicy.LikeForLike)

if (values.length === 2) {
if (values.length === allTypes.length) {
setAllChecked(true)
}
} else {
Expand All @@ -101,25 +105,99 @@ const FuelPolicyFilter = ({
handleCheckLikeForLikeChange(event)
}

const handleCheckFullToFullChange = (e: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLElement>) => {
if ('checked' in e.currentTarget && e.currentTarget.checked) {
values.push(bookcarsTypes.FuelPolicy.FullToFull)

if (values.length === allTypes.length) {
setAllChecked(true)
}
} else {
values.splice(
values.findIndex((v) => v === bookcarsTypes.FuelPolicy.FullToFull),
1,
)

if (values.length === 0) {
setAllChecked(false)
}
}

setValues(values)

handleOnChange(values)
}

const handleFullToFullClick = (e: React.MouseEvent<HTMLElement>) => {
const checkbox = e.currentTarget.previousSibling as HTMLInputElement
checkbox.checked = !checkbox.checked
const event = e
event.currentTarget = checkbox
handleCheckFullToFullChange(event)
}

const handleCheckFullToEmptyChange = (e: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLElement>) => {
if ('checked' in e.currentTarget && e.currentTarget.checked) {
values.push(bookcarsTypes.FuelPolicy.FullToEmpty)

if (values.length === allTypes.length) {
setAllChecked(true)
}
} else {
values.splice(
values.findIndex((v) => v === bookcarsTypes.FuelPolicy.FullToEmpty),
1,
)

if (values.length === 0) {
setAllChecked(false)
}
}

setValues(values)

handleOnChange(values)
}

const handleFullToEmptyClick = (e: React.MouseEvent<HTMLElement>) => {
const checkbox = e.currentTarget.previousSibling as HTMLInputElement
checkbox.checked = !checkbox.checked
const event = e
event.currentTarget = checkbox
handleCheckFullToEmptyChange(event)
}

const handleUncheckAllChange = () => {
if (allChecked) {
// uncheck all
if (automaticRef.current) {
automaticRef.current.checked = false
if (freeTankRef.current) {
freeTankRef.current.checked = false
}
if (likeForLikeRef.current) {
likeForLikeRef.current.checked = false
}
if (manualRef.current) {
manualRef.current.checked = false
if (fullToFullRef.current) {
fullToFullRef.current.checked = false
}
if (fullToEmptyRef.current) {
fullToEmptyRef.current.checked = false
}

setAllChecked(false)
setValues([])
} else {
// check all
if (automaticRef.current) {
automaticRef.current.checked = true
if (freeTankRef.current) {
freeTankRef.current.checked = true
}
if (likeForLikeRef.current) {
likeForLikeRef.current.checked = true
}
if (fullToFullRef.current) {
fullToFullRef.current.checked = true
}
if (manualRef.current) {
manualRef.current.checked = true
if (fullToEmptyRef.current) {
fullToEmptyRef.current.checked = true
}

const _values = allTypes
Expand All @@ -137,7 +215,7 @@ const FuelPolicyFilter = ({
<Accordion title={strings.FUEL_POLICY} collapse={collapse} className={`${className ? `${className} ` : ''}fuel-policy-filter`}>
<div className="filter-elements">
<div className="filter-element">
<input ref={automaticRef} type="checkbox" className="fuel-policy-checkbox" onChange={handleCheckFreeTankChange} />
<input ref={freeTankRef} type="checkbox" className="fuel-policy-checkbox" onChange={handleCheckFreeTankChange} />
<span
onClick={handleFreeTankClick}
role="button"
Expand All @@ -147,7 +225,7 @@ const FuelPolicyFilter = ({
</span>
</div>
<div className="filter-element">
<input ref={manualRef} type="checkbox" className="fuel-policy-checkbox" onChange={handleCheckLikeForLikeChange} />
<input ref={likeForLikeRef} type="checkbox" className="fuel-policy-checkbox" onChange={handleCheckLikeForLikeChange} />
<span
onClick={handleLikeForLikeClick}
role="button"
Expand All @@ -156,6 +234,26 @@ const FuelPolicyFilter = ({
{strings.FUEL_POLICY_LIKE_FOR_LIKE}
</span>
</div>
<div className="filter-element">
<input ref={fullToFullRef} type="checkbox" className="fuel-policy-checkbox" onChange={handleCheckFullToFullChange} />
<span
onClick={handleFullToFullClick}
role="button"
tabIndex={0}
>
{strings.FUEL_POLICY_FULL_TO_FULL}
</span>
</div>
<div className="filter-element">
<input ref={fullToEmptyRef} type="checkbox" className="fuel-policy-checkbox" onChange={handleCheckFullToEmptyChange} />
<span
onClick={handleFullToEmptyClick}
role="button"
tabIndex={0}
>
{strings.FUEL_POLICY_FULL_TO_EMPTY}
</span>
</div>
</div>
<div className="filter-actions">
<span
Expand Down
2 changes: 2 additions & 0 deletions backend/src/components/FuelPolicyList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ const FuelPolicyList = ({
<Select label={label} value={value} onChange={handleChange} variant={variant || 'standard'} required={required} fullWidth>
<MenuItem value={bookcarsTypes.FuelPolicy.LikeForLike}>{strings.FUEL_POLICY_LIKE_FOR_LIKE}</MenuItem>
<MenuItem value={bookcarsTypes.FuelPolicy.FreeTank}>{strings.FUEL_POLICY_FREE_TANK}</MenuItem>
<MenuItem value={bookcarsTypes.FuelPolicy.FullToFull}>{strings.FUEL_POLICY_FULL_TO_FULL}</MenuItem>
<MenuItem value={bookcarsTypes.FuelPolicy.FullToEmpty}>{strings.FUEL_POLICY_FULL_TO_EMPTY}</MenuItem>
</Select>
</div>
)
Expand Down
Loading

0 comments on commit 0be204e

Please sign in to comment.