diff --git a/frontend/src/assets/theme.js b/frontend/src/assets/theme.js
index 84f7c35e..9dbb0d14 100644
--- a/frontend/src/assets/theme.js
+++ b/frontend/src/assets/theme.js
@@ -1,6 +1,14 @@
import { createTheme } from "@mui/material";
const theme = createTheme({
+ palette: {
+ primary: {
+ main: "#7f56d9",
+ },
+ background: {
+ default: "#FFFFFF",
+ },
+ },
components: {
MuiAppBar: {
styleOverrides: {
diff --git a/frontend/src/components/List/List.jsx b/frontend/src/components/List/List.jsx
new file mode 100644
index 00000000..b6aa5797
--- /dev/null
+++ b/frontend/src/components/List/List.jsx
@@ -0,0 +1,28 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import ListItem from './ListItem/ListItem';
+
+const List = ({ items, onSelectItem }) => {
+ return (
+
+ {items.map(item => (
+ onSelectItem(item.idItem)}
+ onDelete={item.onDelete}
+ onEdit={item.onEdit}
+ />
+ ))}
+
+ );
+};
+
+List.propTypes = {
+ items: PropTypes.arrayOf(PropTypes.object),
+ onSelectItem: PropTypes.func,
+};
+
+export default List;
diff --git a/frontend/src/components/List/ListItem/ListItem.css b/frontend/src/components/List/ListItem/ListItem.css
new file mode 100644
index 00000000..2cda96e7
--- /dev/null
+++ b/frontend/src/components/List/ListItem/ListItem.css
@@ -0,0 +1,81 @@
+.list-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 758px;
+ height: 78px;
+ padding: 10px;
+ border: 1px solid var(--grey-border);
+ border-radius: 10px;
+ cursor: pointer;
+ margin-bottom: 30px;
+}
+
+.list-item:hover,
+.list-item:focus {
+ border: 1px solid var(--main-purple);
+}
+
+.list-item-info {
+ display: flex;
+ flex-direction: column;
+ margin-left: 10px;
+}
+
+.list-item-header {
+ display: flex;
+ align-items: center;
+}
+
+.list-item-icon-container {
+ display: flex;
+ align-items: center;
+ position: relative;
+ width: 24px;
+ height: 24px;
+ margin-right: 10px;
+}
+
+.list-item-icon {
+ width: 12px;
+ height: 12px;
+ color: #7F56D9;
+}
+
+.list-item-dot {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 10px;
+ height: 10px;
+ background-color: #FFFFFF;
+ border-radius: 50%;
+ transform: translate(-50%, -50%);
+}
+
+.list-item-info h4 {
+ margin: 0;
+ font-size: 16px;
+ color: #344054;
+}
+
+.list-item-info p {
+ margin: 2px 0 0 33px;
+ font-size: 14px;
+ color: #667085;
+}
+
+.item-id {
+ margin: 2px 0 0 0;
+ font-size: 12px;
+ color: #667085;
+}
+
+.list-item-actions {
+ display: flex;
+ align-items: center;
+}
+
+.list-item-actions .MuiIconButton-root {
+ color: #344054;
+}
diff --git a/frontend/src/components/List/ListItem/ListItem.jsx b/frontend/src/components/List/ListItem/ListItem.jsx
new file mode 100644
index 00000000..007eadde
--- /dev/null
+++ b/frontend/src/components/List/ListItem/ListItem.jsx
@@ -0,0 +1,46 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { IconButton, useTheme } from '@mui/material';
+import DeleteIcon from '@mui/icons-material/Delete';
+import SettingsIcon from '@mui/icons-material/Settings';
+import CircleIcon from '@mui/icons-material/Circle';
+import './ListItem.css';
+
+const ListItem = ({ title, text, id, onClick, onDelete, onEdit }) => {
+ const theme = useTheme();
+
+ return (
+
+
+
+ {text &&
{text}
}
+ {id &&
ID: {id}
}
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+ListItem.propTypes = {
+ title: PropTypes.string,
+ text: PropTypes.string,
+ id: PropTypes.string,
+ onClick: PropTypes.func,
+ onDelete: PropTypes.func,
+ onEdit: PropTypes.func,
+};
+
+export default ListItem;
diff --git a/frontend/src/components/TourComponents/ConfirmationPopup/ConfirmationPopup.jsx b/frontend/src/components/TourComponents/ConfirmationPopup/ConfirmationPopup.jsx
new file mode 100644
index 00000000..b02a919d
--- /dev/null
+++ b/frontend/src/components/TourComponents/ConfirmationPopup/ConfirmationPopup.jsx
@@ -0,0 +1,26 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Button } from '@mui/material';
+
+const ConfirmationPopup = ({ open, onConfirm, onCancel }) => {
+ return (
+
+ Confirm Action
+
+ Are you sure you want to perform this action?
+
+
+ Cancel
+ Confirm
+
+
+ );
+};
+
+ConfirmationPopup.propTypes = {
+ open: PropTypes.bool.isRequired,
+ onConfirm: PropTypes.func.isRequired,
+ onCancel: PropTypes.func.isRequired,
+};
+
+export default ConfirmationPopup;
diff --git a/frontend/src/components/TourComponents/ContentArea/ContentArea.jsx b/frontend/src/components/TourComponents/ContentArea/ContentArea.jsx
new file mode 100644
index 00000000..f2e4d5cc
--- /dev/null
+++ b/frontend/src/components/TourComponents/ContentArea/ContentArea.jsx
@@ -0,0 +1,13 @@
+
+import React from 'react';
+import PropTypes from 'prop-types';
+
+const ContentArea = ({ children }) => {
+ return {children}
;
+};
+
+ContentArea.propTypes = {
+ children: PropTypes.node,
+};
+
+export default ContentArea;
diff --git a/frontend/src/components/TourComponents/ContentHeader/ContentHeader.jsx b/frontend/src/components/TourComponents/ContentHeader/ContentHeader.jsx
new file mode 100644
index 00000000..424a0733
--- /dev/null
+++ b/frontend/src/components/TourComponents/ContentHeader/ContentHeader.jsx
@@ -0,0 +1,12 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+const ContentHeader = ({ title }) => {
+ return {title} ;
+};
+
+ContentHeader.propTypes = {
+ title: PropTypes.string,
+};
+
+export default ContentHeader;
diff --git a/frontend/src/components/TourComponents/InfoTooltip/InfoTooltip.jsx b/frontend/src/components/TourComponents/InfoTooltip/InfoTooltip.jsx
new file mode 100644
index 00000000..d291b127
--- /dev/null
+++ b/frontend/src/components/TourComponents/InfoTooltip/InfoTooltip.jsx
@@ -0,0 +1,21 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Tooltip, IconButton } from '@mui/material';
+import InfoIcon from '@mui/icons-material/Info';
+
+const InfoTooltip = ({ text, title }) => {
+ return (
+
+
+
+
+
+ );
+};
+
+InfoTooltip.propTypes = {
+ text: PropTypes.string,
+ title: PropTypes.string,
+};
+
+export default InfoTooltip;
diff --git a/frontend/src/components/TourComponents/TourDescriptionText/TourDescriptionText.jsx b/frontend/src/components/TourComponents/TourDescriptionText/TourDescriptionText.jsx
new file mode 100644
index 00000000..ce8a5a84
--- /dev/null
+++ b/frontend/src/components/TourComponents/TourDescriptionText/TourDescriptionText.jsx
@@ -0,0 +1,12 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+const TourDescriptionText = ({ description }) => {
+ return {description}
;
+};
+
+TourDescriptionText.propTypes = {
+ description: PropTypes.string,
+};
+
+export default TourDescriptionText;
diff --git a/frontend/src/scenes/home/Home.jsx b/frontend/src/scenes/home/Home.jsx
index 654d9d8d..aa066bc2 100644
--- a/frontend/src/scenes/home/Home.jsx
+++ b/frontend/src/scenes/home/Home.jsx
@@ -27,4 +27,4 @@ const Home = () => {
);
};
-export default Home;
+export default Home;
\ No newline at end of file
diff --git a/frontend/src/scenes/tours/ProductTour.jsx b/frontend/src/scenes/tours/ProductTour.jsx
new file mode 100644
index 00000000..f5fe9820
--- /dev/null
+++ b/frontend/src/scenes/tours/ProductTour.jsx
@@ -0,0 +1,81 @@
+import React, { useState, useEffect } from 'react';
+import List from '../../components/List/List';
+import ContentArea from '../../components/TourComponents/ContentArea/ContentArea';
+import ContentHeader from '../../components/TourComponents/ContentHeader/ContentHeader';
+import ConfirmationPopup from '../../components/TourComponents/ConfirmationPopup/ConfirmationPopup';
+import Button from '../../components/Button/Button';
+import './ProductTourStyles.css';
+import TourDescriptionText from '../../components/TourComponents/TourDescriptionText/TourDescriptionText';
+import InfoTooltip from '../../components/TourComponents/InfoTooltip/InfoTooltip';
+
+const TourPage = ({ items }) => {
+ const [selectedItem, setSelectedItem] = useState(null);
+ const [isPopupOpen, setPopupOpen] = useState(false);
+ const [showDemoItems, setShowDemoItems] = useState(false);
+
+ useEffect(() => {
+ setShowDemoItems(items.length === 0);
+ }, [items]);
+
+ const handleSelect = (idItem) => {
+ setSelectedItem(idItem);
+ };
+
+ const handleDelete = () => {
+ setPopupOpen(false);
+ };
+
+ const handleOpenPopup = () => {
+ setPopupOpen(true);
+ };
+
+ const handleClosePopup = () => {
+ setPopupOpen(false);
+ };
+
+ const handleCreateItem = () => {
+ };
+
+ const demoItems = [
+ {
+ title: 'Main dashboard - first login tour',
+ timestamp: '10:00 AM',
+ idItem: '12548',
+ text: 'This pops up the first time the user logins to the dashboard.',
+ onDelete: () => { },
+ onEdit: () => { }
+ },
+ ];
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
What is a product tour?
+
+ A product onboarding tour is a guided walkthrough or tutorial that introduces users to a new product or service.
+ It typically occurs when a user first signs up or logs into the product.
+ The purpose of the onboarding tour is to familiarize users with the key features, functionalities, and benefits of the product in order to enhance their understanding.
+ During the onboarding tour, users are typically shown around the interface, given demonstrations of how to perform key tasks, and provided with explanations of important features.
+
+
+
+
+ {/*
+
*/}
+
+
+ );
+};
+
+export default TourPage;
diff --git a/frontend/src/scenes/tours/ProductTourStyles.css b/frontend/src/scenes/tours/ProductTourStyles.css
new file mode 100644
index 00000000..89a8d827
--- /dev/null
+++ b/frontend/src/scenes/tours/ProductTourStyles.css
@@ -0,0 +1,45 @@
+.product-page-container {
+ padding: 2% 3%;
+}
+
+.product-page-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 100%;
+ margin-bottom: 20px;
+}
+
+.product-page {
+ display: flex;
+ align-items: flex-start;
+}
+
+.content-area {
+ flex: 2;
+ margin-right: 20px;
+}
+
+.tour-info-container {
+ flex: 1;
+}
+
+.tour-info-box {
+ padding: 16px;
+ border-radius: 8px;
+ border: 1px solid var(--grey-border);
+}
+
+.tour-info-box h4 {
+ margin-top: 0;
+ color: var(--main-purple);
+}
+
+.tour-info-box p {
+ margin-bottom: 0;
+ color: #6b7280;
+}
+
+.create-tour-button {
+ padding: 8px 16px;
+}
diff --git a/frontend/src/scenes/tours/ToursDefaultPage.jsx b/frontend/src/scenes/tours/ToursDefaultPage.jsx
index e8e5013c..a54a0318 100644
--- a/frontend/src/scenes/tours/ToursDefaultPage.jsx
+++ b/frontend/src/scenes/tours/ToursDefaultPage.jsx
@@ -1,26 +1,37 @@
-import CreateActivityButton from "../../components/CreateActivityButton/CreateActivityButton"
-import HomePageTemplate from "../../components/templates/HomePageTemplate"
+import React, { useState } from 'react';
+import CreateActivityButton from "../../components/CreateActivityButton/CreateActivityButton";
+import HomePageTemplate from "../../components/templates/HomePageTemplate";
import { ACTIVITY_TYPES } from "../../data/CreateActivityButtonData";
import ParagraphCSS from "../../components/ParagraphCSS/ParagraphCSS";
+import TourPage from './ProductTour';
const ToursDefaultPage = () => {
+ const [showTourPage, setShowTourPage] = useState(false);
+
+ const handleButtonClick = () => {
+ setShowTourPage(true);
+ };
+
const style = {
"display": "flex",
"flex-direction": "column",
"width": "100%",
"justify-content": "center",
"align-items": "center",
- }
+ };
+
return (
-
-
+ {showTourPage ? (
+
+ ) : (
+
+ )}
- )
-}
-
-export default ToursDefaultPage
+ );
+};
+export default ToursDefaultPage;