diff --git a/packages/frontend/package.json b/packages/frontend/package.json index a0971035..3acac447 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -18,6 +18,7 @@ "react-router-dom": "^6.20.1", "react-scripts": "5.0.1", "react-tabs": "^6.0.2", + "react-timer-hook": "^3.0.7", "typescript": "^4.9.5", "web-vitals": "^2.1.4" }, diff --git a/packages/frontend/src/components/DeployStep.tsx b/packages/frontend/src/components/DeployStep.tsx new file mode 100644 index 00000000..6848cf0b --- /dev/null +++ b/packages/frontend/src/components/DeployStep.tsx @@ -0,0 +1,67 @@ +import React, { useState } from 'react'; + +import { Stopwatch, setStopWatchOffset } from './StopWatch'; +import FormatMillisecond from './FormatMilliSecond'; + +const PROCESS_LOG = + "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book."; + +enum DeployStatus { + PROCESSING = 'progress', + COMPLETE = 'complete', + NOT_STARTED = 'notStarted', +} + +interface DeployStepsProps { + status: DeployStatus; + title: string; + step?: string; + startTime?: string; + processTime?: string; +} + +const DeployStep = ({ + step, + status, + title, + startTime, + processTime, +}: DeployStepsProps) => { + const [collapse, setCollapse] = useState(false); + + return ( + <> +
+ {status === DeployStatus.NOT_STARTED &&
{step}
} + {status === DeployStatus.PROCESSING &&
O
} + {status === DeployStatus.COMPLETE && ( +
+ +
+ )} +
{title}
+ {status === DeployStatus.PROCESSING && ( + <> + ^ + + )} + {status === DeployStatus.COMPLETE && ( + <> + ^{' '} + + )} +
+
+ {PROCESS_LOG} +
+ + ); +}; + +export { DeployStep, DeployStatus }; diff --git a/packages/frontend/src/components/FormatMilliSecond.tsx b/packages/frontend/src/components/FormatMilliSecond.tsx new file mode 100644 index 00000000..ead654bf --- /dev/null +++ b/packages/frontend/src/components/FormatMilliSecond.tsx @@ -0,0 +1,18 @@ +import { Duration } from 'luxon'; +import React from 'react'; + +const FormatMillisecond = ({ time }: { time: number }) => { + const formatTime = Duration.fromMillis(time) + .shiftTo('days', 'hours', 'minutes', 'seconds') + .toObject(); + return ( +
+ {formatTime.days !== 0 && {formatTime.days}d } + {formatTime.hours !== 0 && {formatTime.hours}h } + {formatTime.minutes !== 0 && {formatTime.minutes}m } + {formatTime.seconds}s +
+ ); +}; + +export default FormatMillisecond; diff --git a/packages/frontend/src/components/StopWatch.tsx b/packages/frontend/src/components/StopWatch.tsx new file mode 100644 index 00000000..4e70f9b0 --- /dev/null +++ b/packages/frontend/src/components/StopWatch.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import { useStopwatch } from 'react-timer-hook'; + +import FormatMillisecond from './FormatMilliSecond'; + +const setStopWatchOffset = (time: string) => { + const providedTime = new Date(time); + const currentTime = new Date(); + const timeDifference = currentTime.getTime() - providedTime.getTime(); + currentTime.setMilliseconds(currentTime.getMilliseconds() + timeDifference); + return currentTime; +}; + +const Stopwatch = ({ offsetTimestamp }: { offsetTimestamp: Date }) => { + const { totalSeconds } = useStopwatch({ + autoStart: true, + offsetTimestamp: offsetTimestamp, + }); + + return ; +}; + +export { Stopwatch, setStopWatchOffset }; diff --git a/packages/frontend/src/pages/projects/Create.tsx b/packages/frontend/src/pages/projects/Create.tsx index 18758ad4..048d76cc 100644 --- a/packages/frontend/src/pages/projects/Create.tsx +++ b/packages/frontend/src/pages/projects/Create.tsx @@ -3,6 +3,7 @@ import { Outlet, useNavigate } from 'react-router-dom'; const CreateProject = () => { const navigate = useNavigate(); + return (
diff --git a/packages/frontend/src/pages/projects/create/Template.tsx b/packages/frontend/src/pages/projects/create/Template.tsx index efde9fec..199a68f2 100644 --- a/packages/frontend/src/pages/projects/create/Template.tsx +++ b/packages/frontend/src/pages/projects/create/Template.tsx @@ -1,6 +1,5 @@ import React from 'react'; - -import CreateRepo from '../../../components/CreateRepo'; +import { Outlet } from 'react-router-dom'; const CreateWithTemplate = () => { return ( @@ -16,7 +15,7 @@ const CreateWithTemplate = () => {
2 Deploy
- +
diff --git a/packages/frontend/src/pages/projects/create/routes.tsx b/packages/frontend/src/pages/projects/create/routes.tsx index d8e1d2b7..ce3d245d 100644 --- a/packages/frontend/src/pages/projects/create/routes.tsx +++ b/packages/frontend/src/pages/projects/create/routes.tsx @@ -2,6 +2,7 @@ import React from 'react'; import NewProject from './index'; import CreateWithTemplate from './Template'; +import { templateRoutes } from './template/routes'; export const createProjectRoutes = [ { @@ -11,5 +12,6 @@ export const createProjectRoutes = [ { path: 'template', element: , + children: templateRoutes, }, ]; diff --git a/packages/frontend/src/pages/projects/create/template/Deploy.tsx b/packages/frontend/src/pages/projects/create/template/Deploy.tsx new file mode 100644 index 00000000..ede4c8e2 --- /dev/null +++ b/packages/frontend/src/pages/projects/create/template/Deploy.tsx @@ -0,0 +1,52 @@ +import React from 'react'; + +import { DeployStep, DeployStatus } from '../../../../components/DeployStep'; +import { + Stopwatch, + setStopWatchOffset, +} from '../../../../components/StopWatch'; + +const Deploy = () => { + return ( +
+
+
+

Deployment started ...

+
+ ^  + +
+
+
+ +
+
+ + + + +
+ ); +}; + +export default Deploy; diff --git a/packages/frontend/src/components/CreateRepo.tsx b/packages/frontend/src/pages/projects/create/template/index.tsx similarity index 90% rename from packages/frontend/src/components/CreateRepo.tsx rename to packages/frontend/src/pages/projects/create/template/index.tsx index 80740b1c..389992cb 100644 --- a/packages/frontend/src/components/CreateRepo.tsx +++ b/packages/frontend/src/pages/projects/create/template/index.tsx @@ -1,7 +1,8 @@ import React from 'react'; import { useForm, Controller } from 'react-hook-form'; +import { Link } from 'react-router-dom'; -import Dropdown from './Dropdown'; +import Dropdown from '../../../../components/Dropdown'; const USER_OPTIONS = [ { value: 'saugatyadav1', label: 'saugatyadav1' }, @@ -88,9 +89,11 @@ const CreateRepo = () => {
- + + +
); diff --git a/packages/frontend/src/pages/projects/create/template/routes.tsx b/packages/frontend/src/pages/projects/create/template/routes.tsx new file mode 100644 index 00000000..81149f08 --- /dev/null +++ b/packages/frontend/src/pages/projects/create/template/routes.tsx @@ -0,0 +1,15 @@ +import React from 'react'; + +import CreateRepo from './index'; +import Deploy from './Deploy'; + +export const templateRoutes = [ + { + index: true, + element: , + }, + { + path: 'deploy', + element: , + }, +]; diff --git a/yarn.lock b/yarn.lock index cf009c44..d5519a4e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10280,6 +10280,11 @@ react-tabs@^6.0.2: clsx "^2.0.0" prop-types "^15.5.0" +react-timer-hook@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/react-timer-hook/-/react-timer-hook-3.0.7.tgz#ac42c43d0034b873cbf97b44eb34ccb2b11fe5e0" + integrity sha512-ATpNcU+PQRxxfNBPVqce2+REtjGAlwmfoNQfcEBMZFxPj0r3GYdKhyPHdStvqrejejEi0QvqaJZjy2lBlFvAsA== + react@^18.2.0: version "18.2.0" resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"