Skip to content

Commit

Permalink
Add Property Scheduler
Browse files Browse the repository at this point in the history
  • Loading branch information
aelassas committed Jan 28, 2025
1 parent 04f3d00 commit c526ec6
Show file tree
Hide file tree
Showing 64 changed files with 5,784 additions and 3 deletions.
23 changes: 21 additions & 2 deletions api/src/controllers/bookingController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,7 @@ export const getBookings = async (req: Request, res: Response) => {
} = body
const location = (body.filter && body.filter.location) || null
const from = (body.filter && body.filter.from && new Date(body.filter.from)) || null
const dateBetween = (body.filter && body.filter.dateBetween && new Date(body.filter.dateBetween)) || null
const to = (body.filter && body.filter.to && new Date(body.filter.to)) || null
let keyword = (body.filter && body.filter.keyword) || ''
const options = 'i'
Expand All @@ -676,10 +677,28 @@ export const getBookings = async (req: Request, res: Response) => {
}
if (from) {
$match.$and!.push({ from: { $gte: from } })
} // $from > from
} // $from >= from

if (dateBetween) {
const dateBetweenStart = new Date(dateBetween)
dateBetweenStart.setHours(0, 0, 0, 0)
const dateBetweenEnd = new Date(dateBetween)
dateBetweenEnd.setHours(23, 59, 59, 999)

$match.$and!.push({
$and: [
{ from: { $lte: dateBetweenEnd } },
{ to: { $gte: dateBetweenStart } },
],
})
} else if (from) {
$match.$and!.push({ from: { $gte: from } }) // $from >= from
}

if (to) {
$match.$and!.push({ to: { $lte: to } })
} // $to < to
} // $to <= to

if (keyword) {
const isObjectId = helper.isValidObjectId(keyword)
if (isObjectId) {
Expand Down
11 changes: 10 additions & 1 deletion backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"react-draft-wysiwyg": "^1.15.0",
"react-router-dom": "^7.1.3",
"react-toastify": "^11.0.3",
"rrule": "^2.8.1",
"typescript": "^5.7.3",
"validator": "^13.12.0",
"vite": "^6.0.11"
Expand Down
2 changes: 2 additions & 0 deletions backend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const NoMatch = lazy(() => import('@/pages/NoMatch'))
const Countries = lazy(() => import('@/pages/Countries'))
const CreateCountry = lazy(() => import('@/pages/CreateCountry'))
const UpdateCountry = lazy(() => import('@/pages/UpdateCountry'))
const Scheduler = lazy(() => import('@/pages/Scheduler'))

const App = () => (
<BrowserRouter>
Expand Down Expand Up @@ -79,6 +80,7 @@ const App = () => (
<Route path="/countries" element={<Countries />} />
{/* <Route path="/create-country" element={<CreateCountry />} /> */}
{/* <Route path="/update-country" element={<UpdateCountry />} /> */}
<Route path="/scheduler" element={<Scheduler />} />

<Route path="*" element={<NoMatch />} />
</Routes>
Expand Down
14 changes: 14 additions & 0 deletions backend/src/assets/css/property-scheduler-filter.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
div.property-scheduler-filter {
background: #fafafa;
margin: 10px 10px 0 0;
border: 1px solid #dadada;
font-size: 13px;
}

div.property-scheduler-filter .bf-search {
margin-top: 7px;
}

div.property-scheduler-filter .btn-search {
margin: 20px 0;
}
104 changes: 104 additions & 0 deletions backend/src/assets/css/scheduler.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
div.scheduler {
position: absolute;
bottom: 0;
right: 0;
left: 0;
}

@media only screen and (width <=960px) {
div.scheduler {
top: 56px;
overflow-y: auto;
}

div.scheduler div.col-1 {
display: flex;
flex-direction: column;
align-items: center;
}

div.scheduler div.col-2 {
display: flex;
}

div.scheduler div.col-1 .cl-supplier-filter label.accordion,
div.scheduler div.col-1 .cl-status-filter label.accordion,
div.scheduler div.col-1 .cl-scheduler-filter label.accordion {
background: #fff;
}

div.scheduler div.col-1 .cl-supplier-filter,
div.scheduler div.col-1 .cl-status-filter,
div.scheduler div.col-1 .cl-scheduler-filter {
margin: 5px 10px;
background-color: #fff;
max-width: 480px;
width: calc(100% - 20px);
}

div.scheduler div.col-1 .cl-scheduler-filter div.panel,
div.scheduler div.col-1 .cl-scheduler-filter div.panel-collapse {
padding-right: 15px;
padding-left: 15px;
}

div.scheduler div.col-1 .cl-new-booking {
width: calc(100% - 20px);
max-width: 480px;
margin: 15px 10px 5px;
}
}

@media only screen and (width >=960px) {
div.scheduler {
top: 64px;
}

div.scheduler div.col-1 {
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 300px;
padding: 12px 0 0 12px;
background: #fefefe;
overflow: auto;
}

div.scheduler div.col-2 {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 300px;
}

div.scheduler div.col-1 .cl-supplier-filter label.accordion,
div.scheduler div.col-1 .cl-status-filter label.accordion,
div.scheduler div.col-1 .cl-scheduler-filter label.accordion {
background: #fafafa;
}

div.scheduler div.col-1 .cl-supplier-filter,
div.scheduler div.col-1 .cl-status-filter,
div.scheduler div.col-1 .cl-scheduler-filter {
margin: 10px 10px 10px 0;
background-color: #fafafa;
}

div.scheduler div.col-1 .cl-scheduler-filter div.panel,
div.scheduler div.col-1 .cl-scheduler-filter div.panel-collapse {
padding-right: 15px;
padding-left: 15px;
}

div.scheduler div.col-1 .cl-status-filter,
div.scheduler div.col-1 .cl-scheduler-filter {
margin-bottom: 10px;
}

div.scheduler div.col-1 .cl-new-booking {
width: 265px;
margin-left: 5px;
}
}
62 changes: 62 additions & 0 deletions backend/src/common/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,68 @@ export const getPropertyType = (type: string) => {
export const admin = (user?: movininTypes.User): boolean =>
(user && user.type === movininTypes.RecordType.Admin) ?? false

/**
* Get booking status background color.
*
* @param {string} status
* @returns {string}
*/
export const getBookingStatusBackgroundColor = (status?: movininTypes.BookingStatus) => {
switch (status) {
case movininTypes.BookingStatus.Void:
return '#D9D9D9'

case movininTypes.BookingStatus.Pending:
return '#FBDCC2'

case movininTypes.BookingStatus.Deposit:
return '#CDECDA'

case movininTypes.BookingStatus.Paid:
return '#D1F9D1'

case movininTypes.BookingStatus.Reserved:
return '#D9E7F4'

case movininTypes.BookingStatus.Cancelled:
return '#FBDFDE'

default:
return ''
}
}

/**
* Get booking status text color.
*
* @param {string} status
* @returns {string}
*/
export const getBookingStatusTextColor = (status?: movininTypes.BookingStatus) => {
switch (status) {
case movininTypes.BookingStatus.Void:
return '#6E7C86'

case movininTypes.BookingStatus.Pending:
return '#EF6C00'

case movininTypes.BookingStatus.Deposit:
return '#3CB371'

case movininTypes.BookingStatus.Paid:
return '#77BC23'

case movininTypes.BookingStatus.Reserved:
return '#1E88E5'

case movininTypes.BookingStatus.Cancelled:
return '#E53935'

default:
return ''
}
}

/**
* Get booking status label.
*
Expand Down
5 changes: 5 additions & 0 deletions backend/src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
DescriptionTwoTone as TosIcon,
ExitToApp as SignoutIcon,
Flag as CountriesIcon,
CalendarMonth as SchedulerIcon,
} from '@mui/icons-material'
import { useNavigate } from 'react-router-dom'
import * as movininTypes from ':movinin-types'
Expand Down Expand Up @@ -292,6 +293,10 @@ const Header = ({
<ListItemIcon><DashboardIcon /></ListItemIcon>
<ListItemText primary={strings.DASHBOARD} />
</ListItemLink>
<ListItemLink href="/scheduler">
<ListItemIcon><SchedulerIcon /></ListItemIcon>
<ListItemText primary={strings.SCHEDULER} />
</ListItemLink>
<ListItemLink href="/agencies">
<ListItemIcon><AgenciesIcon /></ListItemIcon>
<ListItemText primary={strings.AGENCIES} />
Expand Down
Loading

0 comments on commit c526ec6

Please sign in to comment.