upd
This commit is contained in:
+2
-2
@@ -1,4 +1,4 @@
|
||||
# VITE_API_URL=http://localhost:3001
|
||||
VITE_API_URL=http://192.168.1.171:3001
|
||||
# VITE_API_URL=https://crm.stream.graff.tech/api
|
||||
# VITE_API_URL=http://192.168.1.171:3001
|
||||
VITE_API_URL=https://crm.stream.graff.tech/api
|
||||
VITE_STREAM_URL=https://stream.graff.tech
|
||||
|
||||
@@ -60,13 +60,17 @@ function Card({
|
||||
|
||||
return (
|
||||
<div className="relative flex flex-col gap-2">
|
||||
<div className="w-[264px] h-[128px] px-3 py-2 bg-white border-r border-b border-[#DAE0E5] flex flex-col gap-2">
|
||||
<div className="w-[264px] h-[164px] px-3 py-2 bg-white border-r border-b border-[#DAE0E5] flex flex-col justify-between gap-2">
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between">
|
||||
<p className="text-sm font-semibold">{client.name}</p>
|
||||
<div className="">
|
||||
<p className="text-[10px] font-semibold text-[#77828C]">Клиент</p>
|
||||
<p className="text-sm">{client.name}</p>
|
||||
</div>
|
||||
{manager ? (
|
||||
<div className="bg-[#E6F2FE] rounded-full px-2 h-[20px] flex items-center gap-1">
|
||||
<div className="w-1 h-1 rounded-full bg-[#49A1F5]"></div>
|
||||
<p className="text-[10px] font-semibold text-[#49A1F5] pt-0.5">
|
||||
<p className="text-[10px] font-semibold text-[#49A1F5]">
|
||||
Готов
|
||||
</p>
|
||||
</div>
|
||||
@@ -80,8 +84,13 @@ function Card({
|
||||
)}
|
||||
</div>
|
||||
<div className="border-b border-[#DAE0E5] pb-2">
|
||||
<p className="text-xs text-[#77828C] leading-tight">{client.phone}</p>
|
||||
<p className="text-xs text-[#77828C] leading-tight">{client.email}</p>
|
||||
<p className="text-xs text-[#77828C] leading-tight">
|
||||
{client.phone}
|
||||
</p>
|
||||
<p className="text-xs text-[#77828C] leading-tight">
|
||||
{client.email}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex justify-between items-center py-1">
|
||||
<div className=" flex items-center gap-2">
|
||||
@@ -105,7 +114,9 @@ function Card({
|
||||
<div className="flex gap-2">
|
||||
{manager && (
|
||||
<Link
|
||||
to={`${import.meta.env.VITE_STREAM_URL}/scheduled/${scheduledSessionId}`}
|
||||
to={`${
|
||||
import.meta.env.VITE_STREAM_URL
|
||||
}/scheduled/${scheduledSessionId}?admin=true`}
|
||||
target="_blank"
|
||||
>
|
||||
<Button>Начать</Button>
|
||||
|
||||
@@ -51,7 +51,7 @@ function DatePicker({ defaultValue, startDate, onChange }: Props) {
|
||||
|
||||
function handleClick(date: Date) {
|
||||
setValue(date);
|
||||
onChange && onChange(value);
|
||||
onChange && onChange(date);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -3,7 +3,7 @@ import PlusIcon from "./icons/PlusIcon";
|
||||
|
||||
function EmptyCard() {
|
||||
return (
|
||||
<div className="w-[264px] h-[128px] text-sm font-semibold bg-[#F0F1F2] border-r border-b border-[#DAE0E5] flex items-center justify-center group">
|
||||
<div className="w-[264px] h-[164px] text-sm font-semibold bg-[#F0F1F2] border-r border-b border-[#DAE0E5] flex items-center justify-center group">
|
||||
<Button
|
||||
color="tertiary"
|
||||
icon={<PlusIcon />}
|
||||
|
||||
@@ -8,36 +8,29 @@ import { useEffect, useState } from "react";
|
||||
import Select from "../Select";
|
||||
import useModalStore from "../../stores/useModalStore";
|
||||
import Input from "../Input";
|
||||
import {
|
||||
eachMinuteOfInterval,
|
||||
isAfter,
|
||||
isBefore,
|
||||
parse,
|
||||
parseISO,
|
||||
startOfDay,
|
||||
} from "date-fns";
|
||||
import { eachMinuteOfInterval, parse, parseISO, startOfDay } from "date-fns";
|
||||
import api from "../../utils/api";
|
||||
import ChoiceChips from "../ChoiceChips";
|
||||
import ISchedule from "../../types/ISchedule";
|
||||
// import ISchedule from "../../types/ISchedule";
|
||||
import DatePicker from "../DatePicker";
|
||||
import IScheduledSession from "../../types/IScheduledSession";
|
||||
|
||||
interface Props {
|
||||
companyId: string;
|
||||
buildId: string;
|
||||
schedules: ISchedule[];
|
||||
// schedules: ISchedule[];
|
||||
handleCreate: () => void;
|
||||
}
|
||||
|
||||
function CreateScheduleModal({
|
||||
companyId,
|
||||
buildId,
|
||||
schedules,
|
||||
// schedules,
|
||||
handleCreate,
|
||||
}: Props) {
|
||||
const setModal = useModalStore((state) => state.setModal);
|
||||
const [date, setDate] = useState<Date>(new Date());
|
||||
const [startDate, setStartDate] = useState<Date>();
|
||||
const [date, setDate] = useState<Date>(startOfDay(new Date()));
|
||||
const [startDate, setStartDate] = useState<Date>(startOfDay(new Date()));
|
||||
const [sessionDuration, setSessionDuration] = useState<number>(30);
|
||||
const [sessionBreak, setSessionBreak] = useState<number>(5);
|
||||
const [startTime, setStartTime] = useState<string>("10:00");
|
||||
@@ -47,17 +40,15 @@ function CreateScheduleModal({
|
||||
|
||||
async function getLastScheduledSessionDate() {
|
||||
try {
|
||||
const { startAt }: IScheduledSession = await api
|
||||
const result: IScheduledSession | null = await api
|
||||
.get(`companies/${companyId}/builds/${buildId}/last_scheduled_session`)
|
||||
.json();
|
||||
|
||||
if (!startAt) return;
|
||||
if (!result || !result.startAt) return;
|
||||
|
||||
setStartDate(startOfDay(parseISO(startAt)));
|
||||
setStartDate(startOfDay(parseISO(result.startAt)));
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
alert(error.message);
|
||||
}
|
||||
alert((error as Error).message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +57,7 @@ function CreateScheduleModal({
|
||||
}, []);
|
||||
|
||||
function calculateSessionsPerDay() {
|
||||
if (!startDate) return;
|
||||
// if (!startDate) return;
|
||||
|
||||
const sessionsPerDay = eachMinuteOfInterval(
|
||||
{
|
||||
@@ -88,7 +79,7 @@ function CreateScheduleModal({
|
||||
async function createSchedule() {
|
||||
await api.post(`companies/${companyId}/builds/${buildId}/schedules`, {
|
||||
json: {
|
||||
startDate,
|
||||
startDate: date,
|
||||
startTime,
|
||||
endTime,
|
||||
weekends,
|
||||
@@ -100,7 +91,7 @@ function CreateScheduleModal({
|
||||
}
|
||||
|
||||
async function handleClickCreateSchedule() {
|
||||
if (!startDate) return;
|
||||
// if (!startDate) return;
|
||||
|
||||
await createSchedule();
|
||||
handleCreate();
|
||||
@@ -141,8 +132,8 @@ function CreateScheduleModal({
|
||||
<div className="flex flex-col">
|
||||
<Label value="Начало" />
|
||||
<DatePicker
|
||||
startDate={startDate || new Date()}
|
||||
onChange={(date) => setDate(date)}
|
||||
startDate={startDate}
|
||||
onChange={(date) => (setDate(date), console.log(date))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -422,11 +422,7 @@ function DashboardPage() {
|
||||
scheduleSessionStartAt={
|
||||
scheduledSession.startAt
|
||||
}
|
||||
client={{
|
||||
name: scheduledSession.clientName,
|
||||
phone: scheduledSession.clientPhone,
|
||||
email: scheduledSession.clientEmail,
|
||||
}}
|
||||
client={scheduledSession.client}
|
||||
manager={selectedManager}
|
||||
managers={selectedBuildManagers || []}
|
||||
handleSelect={(scheduledSessionId, managerId) =>
|
||||
@@ -523,7 +519,7 @@ function DashboardPage() {
|
||||
<CreateScheduleModal
|
||||
companyId={company?.id}
|
||||
buildId={selectedBuild?.id}
|
||||
schedules={schedules}
|
||||
// schedules={schedules}
|
||||
handleCreate={getSchedules}
|
||||
/>
|
||||
)
|
||||
|
||||
+3
-3
@@ -21,15 +21,15 @@ connectDB();
|
||||
app.use(json());
|
||||
app.use(cors({ origin: "*" }));
|
||||
|
||||
app.use("/app", authMiddleware, appRouter);
|
||||
app.use("/companies", authMiddleware, companiesRouter);
|
||||
app.use("/users", authMiddleware, usersRouter);
|
||||
app.use("/login", loginRouter);
|
||||
app.use("/registration", registrationRouter);
|
||||
app.use("/actions", actionsRouter);
|
||||
app.use("/builds", buildsRouter);
|
||||
app.use("/scheduled_sessions", scheduledSessionsRouter);
|
||||
app.use("/schedules", schedulesRouter);
|
||||
app.use("/app", authMiddleware, appRouter);
|
||||
app.use("/companies", authMiddleware, companiesRouter);
|
||||
app.use("/users", authMiddleware, usersRouter);
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server listening on port ${port}`);
|
||||
|
||||
@@ -258,9 +258,6 @@ router.get(
|
||||
async (req, res) => {
|
||||
const { companyId, buildId } = req.params;
|
||||
|
||||
console.log("companyId", companyId);
|
||||
console.log("buildId", buildId);
|
||||
|
||||
try {
|
||||
const lastScheduledSession = await ScheduledSession.findOne({
|
||||
companyId,
|
||||
|
||||
@@ -5,13 +5,11 @@ import Schedule from "../models/Schedule";
|
||||
import {
|
||||
addMinutes,
|
||||
areIntervalsOverlapping,
|
||||
differenceInMinutes,
|
||||
endOfDay,
|
||||
isValid,
|
||||
parseISO,
|
||||
startOfDay,
|
||||
} from "date-fns";
|
||||
import { isValidObjectId } from "mongoose";
|
||||
|
||||
const scheduledSessionsRouter = Router();
|
||||
|
||||
@@ -26,50 +24,33 @@ scheduledSessionsRouter.get("/", async (_req, res) => {
|
||||
|
||||
scheduledSessionsRouter.get("/:id", async (req, res) => {
|
||||
const scheduledSessionId = req.params.id;
|
||||
|
||||
if (!isValidObjectId(scheduledSessionId)) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Invalid session ID value",
|
||||
});
|
||||
}
|
||||
|
||||
const scheduledSession = await ScheduledSession.findById(req.params.id);
|
||||
const scheduledSession = await ScheduledSession.findById(scheduledSessionId);
|
||||
|
||||
res.json(scheduledSession);
|
||||
});
|
||||
|
||||
scheduledSessionsRouter.get("/builds/:buildId", async (req, res) => {
|
||||
if (!req.params.buildId) {
|
||||
res.json({ error: "Parameter `buildId` is required" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!req.query.date) {
|
||||
res.json({ error: "Query parameter `date` is required" });
|
||||
return;
|
||||
}
|
||||
|
||||
const buildId = req.params.buildId;
|
||||
const date = req.query.date as string;
|
||||
|
||||
if (!isValidObjectId(buildId)) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Invalid build ID value",
|
||||
});
|
||||
}
|
||||
scheduledSessionsRouter.get(
|
||||
"/companies/:companyId/builds/:buildId",
|
||||
async (req, res) => {
|
||||
const { companyId, buildId } = req.params;
|
||||
const { date } = req.query;
|
||||
|
||||
try {
|
||||
const scheduledSessions = await ScheduledSession.find({
|
||||
companyId,
|
||||
buildId,
|
||||
startAt: {
|
||||
$gte: startOfDay(parseISO(date)),
|
||||
$lt: endOfDay(parseISO(date)),
|
||||
$gte: startOfDay(parseISO(date as string)),
|
||||
$lt: endOfDay(parseISO(date as string)),
|
||||
},
|
||||
});
|
||||
|
||||
res.json(scheduledSessions);
|
||||
});
|
||||
} catch (error) {
|
||||
res.json({ error: (error as Error).message });
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
scheduledSessionsRouter.get("/:buildId", async (req, res) => {
|
||||
if (!req.params.buildId) {
|
||||
@@ -98,13 +79,6 @@ scheduledSessionsRouter.get("/:buildId", async (req, res) => {
|
||||
scheduledSessionsRouter.post("/", async (req, res) => {
|
||||
const { buildId, startAt, client, duration } = req.body;
|
||||
|
||||
if (!isValidObjectId(buildId)) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Invalid build ID value",
|
||||
});
|
||||
}
|
||||
|
||||
if (!buildId || !startAt) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
@@ -183,7 +157,7 @@ scheduledSessionsRouter.post("/", async (req, res) => {
|
||||
const schedule = await Schedule.findOne({
|
||||
buildId,
|
||||
startDate: { $lte: startAtISO },
|
||||
endDate: { $gte: startAtISO },
|
||||
// endDate: { $gte: startAtISO },
|
||||
});
|
||||
|
||||
if (!schedule) {
|
||||
@@ -246,16 +220,13 @@ scheduledSessionsRouter.post("/", async (req, res) => {
|
||||
scheduledSessionsRouter.put("/:id", async (req, res) => {
|
||||
const scheduledSessionId = req.params.id;
|
||||
|
||||
if (!isValidObjectId(scheduledSessionId)) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Invalid session ID value",
|
||||
});
|
||||
}
|
||||
let {
|
||||
startAt,
|
||||
endAt,
|
||||
activeSessionId,
|
||||
}: { startAt: string; endAt: string; activeSessionId: string } = req.body;
|
||||
|
||||
let { startAt, duration }: { startAt: string; duration: number } = req.body;
|
||||
|
||||
if (!startAt && !duration) {
|
||||
if (!startAt && !endAt) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Parameter `startAt` or `duration` is required, or both",
|
||||
@@ -269,16 +240,9 @@ scheduledSessionsRouter.put("/:id", async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
function isInteger(num: number) {
|
||||
return (num ^ 0) === num;
|
||||
}
|
||||
|
||||
if (duration && !isInteger(duration)) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Parameter `duration` is not an integer",
|
||||
});
|
||||
}
|
||||
// function isInteger(num: number) {
|
||||
// return (num ^ 0) === num;
|
||||
// }
|
||||
|
||||
const scheduledSession = await ScheduledSession.findById(scheduledSessionId);
|
||||
|
||||
@@ -289,22 +253,10 @@ scheduledSessionsRouter.put("/:id", async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
if (!duration) {
|
||||
duration = differenceInMinutes(
|
||||
scheduledSession.endAt,
|
||||
scheduledSession.startAt
|
||||
);
|
||||
}
|
||||
|
||||
const endAt = addMinutes(
|
||||
(startAt && parseISO(startAt.toString())) || scheduledSession.startAt,
|
||||
duration
|
||||
);
|
||||
|
||||
try {
|
||||
const scheduledSession = await ScheduledSession.findByIdAndUpdate(
|
||||
scheduledSessionId,
|
||||
{ startAt, endAt },
|
||||
{ startAt, endAt, activeSessionId },
|
||||
{ new: true }
|
||||
);
|
||||
|
||||
@@ -319,13 +271,6 @@ scheduledSessionsRouter.put("/:id", async (req, res) => {
|
||||
scheduledSessionsRouter.delete("/:id", async (req, res) => {
|
||||
const scheduledSessionId = req.params.id;
|
||||
|
||||
if (!isValidObjectId(scheduledSessionId)) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Invalid session ID value",
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await ScheduledSession.findByIdAndDelete(scheduledSessionId);
|
||||
|
||||
|
||||
@@ -3,14 +3,16 @@ import Schedule from "../models/Schedule";
|
||||
|
||||
const schedulesRouter = Router();
|
||||
|
||||
schedulesRouter.get("/builds/:buildId", async (req, res) => {
|
||||
const buildId = req.params.buildId;
|
||||
schedulesRouter.get(
|
||||
"/companies/:companyId/builds/:buildId",
|
||||
async (req, res) => {
|
||||
const { companyId, buildId } = req.params;
|
||||
const date = new Date();
|
||||
|
||||
const schedules = await Schedule.find({
|
||||
companyId,
|
||||
buildId,
|
||||
startDate: { $lte: date },
|
||||
endDate: { $gte: date },
|
||||
});
|
||||
|
||||
if (!schedules.length) {
|
||||
@@ -20,9 +22,9 @@ schedulesRouter.get("/builds/:buildId", async (req, res) => {
|
||||
|
||||
if (req.query.date) {
|
||||
const schedule = await Schedule.findOne({
|
||||
companyId,
|
||||
buildId,
|
||||
startDate: { $lte: date },
|
||||
endDate: { $gte: date },
|
||||
});
|
||||
|
||||
res.json(schedule);
|
||||
@@ -30,6 +32,7 @@ schedulesRouter.get("/builds/:buildId", async (req, res) => {
|
||||
}
|
||||
|
||||
res.json(schedules);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
export default schedulesRouter;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"skipLibCheck": true
|
||||
"skipLibCheck": true,
|
||||
},
|
||||
"ts-node": {
|
||||
"transpileOnly": true
|
||||
|
||||
Reference in New Issue
Block a user