Skip to content

Commit

Permalink
Merge pull request #108 from bluewave-labs/feature/Issue-75-Develop-a…
Browse files Browse the repository at this point in the history
…-page-for-creating-new-product-tour-items

Feature/issue 75 develop a page for creating new product tour items
  • Loading branch information
SimerdeepSinghGrewal authored Aug 12, 2024
2 parents 9edc0a5 + 163fdd1 commit cc17d26
Show file tree
Hide file tree
Showing 13 changed files with 397 additions and 13 deletions.
8 changes: 8 additions & 0 deletions frontend/src/assets/theme.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import { createTheme } from "@mui/material";

const theme = createTheme({
palette: {
primary: {
main: "#7f56d9",
},
background: {
default: "#FFFFFF",
},
},
components: {
MuiAppBar: {
styleOverrides: {
Expand Down
28 changes: 28 additions & 0 deletions frontend/src/components/List/List.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import PropTypes from 'prop-types';
import ListItem from './ListItem/ListItem';

const List = ({ items, onSelectItem }) => {
return (
<div>
{items.map(item => (
<ListItem
key={item.idItem}
title={item.title}
text={item.text}
id={item.idItem}
onClick={() => onSelectItem(item.idItem)}
onDelete={item.onDelete}
onEdit={item.onEdit}
/>
))}
</div>
);
};

List.propTypes = {
items: PropTypes.arrayOf(PropTypes.object),
onSelectItem: PropTypes.func,
};

export default List;
81 changes: 81 additions & 0 deletions frontend/src/components/List/ListItem/ListItem.css
Original file line number Diff line number Diff line change
@@ -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;
}
46 changes: 46 additions & 0 deletions frontend/src/components/List/ListItem/ListItem.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="list-item" onClick={onClick}>
<div className="list-item-info">
<div className="list-item-header">
<div className="list-item-icon-container">
<CircleIcon className="list-item-icon" style={{ fill: theme.palette.primary.main }} />
<div className="list-item-dot" style={{ backgroundColor: theme.palette.background.default }}></div>
</div>
<h4>{title}</h4>
</div>
{text && <p>{text}</p>}
{id && <p className="item-id">ID: {id}</p>}
</div>
<div className="list-item-actions">
<IconButton onClick={onEdit}>
<SettingsIcon />
</IconButton>
<IconButton onClick={onDelete}>
<DeleteIcon />
</IconButton>
</div>
</div>
);
};

ListItem.propTypes = {
title: PropTypes.string,
text: PropTypes.string,
id: PropTypes.string,
onClick: PropTypes.func,
onDelete: PropTypes.func,
onEdit: PropTypes.func,
};

export default ListItem;
Original file line number Diff line number Diff line change
@@ -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 (
<Dialog open={open} onClose={onCancel}>
<DialogTitle>Confirm Action</DialogTitle>
<DialogContent>
<DialogContentText>Are you sure you want to perform this action?</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={onCancel}>Cancel</Button>
<Button onClick={onConfirm} color="primary">Confirm</Button>
</DialogActions>
</Dialog>
);
};

ConfirmationPopup.propTypes = {
open: PropTypes.bool.isRequired,
onConfirm: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired,
};

export default ConfirmationPopup;
13 changes: 13 additions & 0 deletions frontend/src/components/TourComponents/ContentArea/ContentArea.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

import React from 'react';
import PropTypes from 'prop-types';

const ContentArea = ({ children }) => {
return <div className="content-area">{children}</div>;
};

ContentArea.propTypes = {
children: PropTypes.node,
};

export default ContentArea;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';

const ContentHeader = ({ title }) => {
return <h2 className="content-header">{title}</h2>;
};

ContentHeader.propTypes = {
title: PropTypes.string,
};

export default ContentHeader;
21 changes: 21 additions & 0 deletions frontend/src/components/TourComponents/InfoTooltip/InfoTooltip.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<Tooltip title={text}>
<IconButton>
<InfoIcon />
</IconButton>
</Tooltip>
);
};

InfoTooltip.propTypes = {
text: PropTypes.string,
title: PropTypes.string,
};

export default InfoTooltip;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';

const TourDescriptionText = ({ description }) => {
return <p className="tour-description-text">{description}</p>;
};

TourDescriptionText.propTypes = {
description: PropTypes.string,
};

export default TourDescriptionText;
2 changes: 1 addition & 1 deletion frontend/src/scenes/home/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ const Home = () => {
);
};

export default Home;
export default Home;
81 changes: 81 additions & 0 deletions frontend/src/scenes/tours/ProductTour.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="product-page-container">
<div className="product-page-header">
<ContentHeader title={showDemoItems ? "Demo Tours" : "All Tours"} />
<Button text="Create a new tour" variant="contained" className="button-primary create-tour-button" />
</div>
<div className="product-page">
<ContentArea className="content-area">
<List items={showDemoItems ? demoItems : items} onSelectItem={handleSelect} />
<List items={showDemoItems ? demoItems : items} onSelectItem={handleSelect} />
<List items={showDemoItems ? demoItems : items} onSelectItem={handleSelect} />
</ContentArea>
<div className="tour-info-container">
<div className="tour-info-box">
<h4>What is a product tour?</h4>
<p>
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.
</p>
</div>
</div>
</div>
{/* <TourDescriptionText description="A product onboarding tour is a guided walkthrough or tutorial..." />
<InfoTooltip text="More info here" title="What is a product tour?" /> */}
<ConfirmationPopup open={isPopupOpen} onConfirm={handleDelete} onCancel={handleClosePopup} />
</div>
);
};

export default TourPage;
45 changes: 45 additions & 0 deletions frontend/src/scenes/tours/ProductTourStyles.css
Original file line number Diff line number Diff line change
@@ -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;
}
Loading

0 comments on commit cc17d26

Please sign in to comment.