Skip to content

Commit

Permalink
Merge pull request #92 from chingu-voyages/sort-algo
Browse files Browse the repository at this point in the history
Sort algo
  • Loading branch information
kristi-h authored Jan 6, 2025
2 parents a1780e0 + 27e5440 commit 555ce00
Show file tree
Hide file tree
Showing 19 changed files with 271 additions and 204 deletions.
84 changes: 42 additions & 42 deletions .github/workflows/serverBuildDeploy.yml
Original file line number Diff line number Diff line change
@@ -1,50 +1,50 @@
name: Build and Deploy Server

on:
push:
branches: ["main"]
workflow_dispatch:
push:
branches: ["main"]
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
env:
SSH_USER: ec2-user
SSH_HOST: ec2-52-53-202-98.us-west-1.compute.amazonaws.com
WEB_ROOT: /home/www
build:
runs-on: ubuntu-latest
env:
SSH_USER: ec2-user
SSH_HOST: ec2-52-53-202-98.us-west-1.compute.amazonaws.com
WEB_ROOT: /home/www

steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci --prefix server
- name: Copy server files to EC2 server
uses: burnett01/[email protected]
with:
switches: --verbose --human-readable --archive --delete --exclude "addresses.db"
path: server/
remote_user: ${{ env.SSH_USER }}
remote_host: ${{ env.SSH_HOST }}
remote_path: ${{ env.WEB_ROOT}}
remote_key: ${{ secrets.SERVER_DEPLOYMENT_KEY }}
- name: Execute commands on server
uses: appleboy/[email protected]
with:
username: ${{ env.SSH_USER }}
host: ${{ env.SSH_HOST }}
key: ${{ secrets.SERVER_DEPLOYMENT_KEY }}
script: |
echo "Checking if pm2 installed"
if [ ! "$(which pm2 2>/dev/null)" ]; then
echo "Not found. Installing pm2"
sudo npm i -g pm2
fi
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci --prefix server
- name: Copy server files to EC2 server
uses: burnett01/[email protected]
with:
switches: --verbose --human-readable --archive --delete --exclude "addresses.db"
path: server/
remote_user: ${{ env.SSH_USER }}
remote_host: ${{ env.SSH_HOST }}
remote_path: ${{ env.WEB_ROOT}}
remote_key: ${{ secrets.SERVER_DEPLOYMENT_KEY }}
- name: Execute commands on server
uses: appleboy/[email protected]
with:
username: ${{ env.SSH_USER }}
host: ${{ env.SSH_HOST }}
key: ${{ secrets.SERVER_DEPLOYMENT_KEY }}
script: |
echo "Checking if pm2 installed"
if [ ! "$(which pm2 2>/dev/null)" ]; then
echo "Not found. Installing pm2"
sudo npm i -g pm2
fi
echo "Deleting node server if exists"
pm2 delete ${{ env.WEB_ROOT}}/src/app.js 2> /dev/null
echo "Deleting node server if exists"
pm2 delete ${{ env.WEB_ROOT}}/src/app.js 2> /dev/null
echo "Starting node server"
cd ${{ env.WEB_ROOT}}
PORT=4000 DATABASE_CONNECTION_STRING='${{ secrets.DATABASE_CONNECTION_STRING }}' MOCK_EMAIL_USER='${{secrets.MOCK_EMAIL_USER}}' MOCK_EMAIL_PASS='${{secrets.MOCK_EMAIL_PASS}}' MY_TEST_DB=test pm2 start src/app.js
echo "Starting node server"
cd ${{ env.WEB_ROOT}}
PORT=4000 DATABASE_CONNECTION_STRING='${{ secrets.DATABASE_CONNECTION_STRING }}' MOCK_EMAIL_USER='${{secrets.MOCK_EMAIL_USER}}' MOCK_EMAIL_PASS='${{secrets.MOCK_EMAIL_PASS}}' MY_TEST_DB=test pm2 start src/app.js
10 changes: 8 additions & 2 deletions client/actions/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ export async function fetchAppointments() {
cache: "no-store",
});

if (!response.ok) throw error;
if (!response.ok)
throw new Error(
`Failed to fetch appointments: ${response.status} ${response.statusText}`
);

const data = await response.json();

Expand All @@ -38,7 +41,10 @@ export async function fetchAppointments() {
email: item.email,
address: item.location.address,
location: { lat: item.location.lat, lng: item.location.lng },
schedule: item.schedule,
schedule: {
order: item.schedule.order,
scheduledDate: new Date(item.schedule.scheduledDate),
},
}));
} catch (error) {
console.error(error);
Expand Down
8 changes: 4 additions & 4 deletions client/app/admin-dashboard/page.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Suspense } from "react";
import { Typography, Box } from "@mui/material";
import ReservationTable from "../../components/admin_dashboard/ReservationTable";
import Map from "../../components/admin_dashboard/Map";
import ReservationTable from "../../components/admin-dashboard/ReservationTable";
import Map from "../../components/admin-dashboard/Map";
import Spinner from "@/components/Spinner";
import { fetchAppointments } from "@/actions/form";

Expand All @@ -13,10 +13,10 @@ async function Dashboard() {
return (
<Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
<Box sx={{ flex: 1, height: "50vh" }}>
<ReservationTable initAppointments={initAppointments} />
<ReservationTable appointments={initAppointments} />
</Box>
<Box sx={{ flex: 1, height: "50vh" }}>
<Map initAppointments={initAppointments} />
<Map appointments={initAppointments} />
</Box>
</Box>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,54 +1,37 @@
"use client";

import { useState, useMemo } from "react";
import {
DataGrid,
GridToolbarExport,
GridToolbarContainer,
} from "@mui/x-data-grid";
import { Paper, Box, Tooltip } from "@mui/material";
import SearchBar from "./SearchBar";
import { DataGrid } from "@mui/x-data-grid";
import { Paper, Box } from "@mui/material";
import { getColumns } from "./grid-components/columns";
import { updateStatusOnServer } from "@/actions/form";
import { Toolbar } from "./grid-components/toolbar";
import SearchBar from "./SearchBar";

const paginationModel = { page: 0, pageSize: 15 };

const Toolbar = () => (
<GridToolbarContainer sx={{ justifyContent: "flex-end" }}>
<GridToolbarExport />
</GridToolbarContainer>
);
const columns = getColumns();

export default function Grid({ rows, refreshData }) {
export default function Grid({ rows }) {
const [searchText, setSearchText] = useState("");

const toggleVisited = async (id, status) => {
await updateStatusOnServer(id, status);
await refreshData();
};

const columns = useMemo(
() => getColumns(refreshData, toggleVisited),
[refreshData]
);

const filteredRows = useMemo(() => {
if (!searchText) return rows;

const needToFormat = {
dateCreated: (value) => formatDateCreated(new Date(value)),
timeRange: (value) => formatTimeRange(value),
markVisited: (value, row) =>
row.markVisited ? "Visited" : "Need to Visit",
};

return rows.filter((row) =>
columns.some((col) => {
const value = row[col.field];
const formattedValue = needToFormat[col.field]
? needToFormat[col.field](value, row)
: value;
return formattedValue

if (col.field === "dateCreated") {
const formattedDate = formatDateCreated(new Date(value));
return formattedDate.toLowerCase().includes(searchText.toLowerCase());
}
if (col.field === "timeRange") {
const formattedTimeRange = formatTimeRange(value);
return formattedTimeRange
.toLowerCase()
.includes(searchText.toLowerCase());
}

return value
?.toString()
.toLowerCase()
.includes(searchText.toLowerCase());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { GoogleMap, LoadScript } from "@react-google-maps/api";
import { googleApiKey, appointmentsMapId } from "@/constants";
import React, { useRef } from "react";

export default function Map({ initAppointments }) {
if (!initAppointments.length) {
export default function Map({ appointments }) {
if (!appointments.length) {
return <p>No map data available</p>;
}

Expand All @@ -15,7 +15,7 @@ export default function Map({ initAppointments }) {
height: "400px",
};

const startCoords = initAppointments.map((item) => ({
const startCoords = appointments.map((item) => ({
location: item.location,
visitOrder: item.schedule.order,
customerName: item.name,
Expand All @@ -36,7 +36,7 @@ export default function Map({ initAppointments }) {
map: mapInstance,
title: customerName,
content: pin.element,
zIndex: 100000 - visitOrder, // Keeps earlier markers visible above later overlapping ones
zIndex: 100000 - visitOrder,
});
});
};
Expand Down
12 changes: 12 additions & 0 deletions client/components/admin-dashboard/ReservationTable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"use client";

import Box from "@mui/material/Box";
import Grid from "./Grid";

export default function ReservationTable({ appointments = [] }) {
return (
<Box sx={{ height: "100%", width: "100%" }}>
<Grid rows={appointments} />
</Box>
);
}
34 changes: 34 additions & 0 deletions client/components/admin-dashboard/SearchBar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useState } from "react";
import { TextField, Box, InputAdornment } from "@mui/material";
import SearchIcon from "@mui/icons-material/Search";

const SearchBar = ({ onSearchChange, searchText }) => {
const handleSearch = (e) => {
const value = e.target.value;
onSearchChange(value);
};

return (
<Box sx={{ display: "flex", justifyContent: "center", width: "100%" }}>
<TextField
label=""
variant="outlined"
margin="normal"
value={searchText}
onChange={handleSearch}
sx={{
flex: 0.55,
}}
InputProps={{
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
/>
</Box>
);
};

export default SearchBar;
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import React from "react";
import { Box, InputLabel, MenuItem, FormControl, Select } from "@mui/material";
import { updateStatusOnServer } from "@/actions/form";

export default function StatusChange({ id, refreshData, currentStatus }) {
export default function StatusChange({ id, currentStatus }) {
const handleChange = async (e, id) => {
const newStatus = e.target.value;
await updateStatusOnServer(id, newStatus);
await refreshData();
};
return (
<Box sx={{ minWidth: 120 }}>
Expand Down
26 changes: 26 additions & 0 deletions client/components/admin-dashboard/grid-components/VisitedChip.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Button } from "@mui/material";
import { updateStatusOnServer } from "@/actions/form";

const VisitedChip = ({ id, status }) => {
const visited = status === "Visited" || status === "Completed";

const toggleVisited = async (id, newStatus) => {
try {
await updateStatusOnServer(id, newStatus);
} catch (error) {
console.error("Failed to update status:", error);
}
};

return (
<Button
variant={visited ? "contained" : "outlined"}
color="primary"
onClick={(e) => toggleVisited(id, visited ? "Scheduled" : "Completed")}
>
{visited ? "Visited" : "Not Visited"}
</Button>
);
};

export default VisitedChip;
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
formatPhone,
} from "./formatters";

export const getColumns = (refreshData, toggleVisited) => [
export const getColumns = (toggleVisited) => [
{
field: "visitOrder",
headerName: "Visit Order",
Expand All @@ -22,7 +22,7 @@ export const getColumns = (refreshData, toggleVisited) => [
<VisitedChip
id={params.row.id}
status={params.row.status}
toggleVisited={toggleVisited}
currentStatus={status}
/>
),
},
Expand All @@ -32,13 +32,7 @@ export const getColumns = (refreshData, toggleVisited) => [
width: 190,
renderCell: (params) => {
const { id, status } = params.row;
return (
<StatusChange
id={id}
refreshData={refreshData}
currentStatus={status}
/>
);
return <StatusChange id={id} currentStatus={status} />;
},
},
{
Expand Down
7 changes: 7 additions & 0 deletions client/components/admin-dashboard/grid-components/toolbar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { GridToolbarExport, GridToolbarContainer } from "@mui/x-data-grid";

const Toolbar = () => (
<GridToolbarContainer sx={{ justifyContent: "flex-end" }}>
<GridToolbarExport />
</GridToolbarContainer>
);
24 changes: 0 additions & 24 deletions client/components/admin_dashboard/ReservationTable.jsx

This file was deleted.

Loading

0 comments on commit 555ce00

Please sign in to comment.