Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make panel #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/app.tsx
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ import "semantic-ui-css/semantic.min.css";
import "react-toastify/dist/ReactToastify.min.css";
import Map from "./components/map";
import styles from "./app.module.scss";
import SidePanel from "./components/side-panel";

toast.configure({
position: "bottom-center",
@@ -15,7 +16,7 @@ toast.configure({
function App() {
return (
<div className={styles.app}>
<Map />
<SidePanel />
</div>
);
}
1 change: 1 addition & 0 deletions src/components/side-panel/my-groups/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./my-groups";
17 changes: 17 additions & 0 deletions src/components/side-panel/my-groups/my-groups.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.content_section {
max-height: 20vh;
word-wrap: break-word;
overflow: auto;
}

.title_section {
width: 100%;
display: flex;
align-items: center;
}

.leave_button {
flex: 1;
display: flex;
justify-content: flex-end;
}
65 changes: 65 additions & 0 deletions src/components/side-panel/my-groups/my-groups.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Fragment, useState } from "react";
import { Accordion, Button, Icon } from "semantic-ui-react";
import { Group } from "../../../types";
import styles from "./my-groups.module.scss";

type Props = {
myGroup: Group[];
removeFromMyGroup: (groupToRemove: number) => void;
};

function MyGroups({ myGroup, removeFromMyGroup }: Props) {
const [activeIndex, setActiveIndex] = useState(-1);
const [hasLeaveButton, setLeaveButton] = useState(false);

const handleClick = (e: any, titleProps: any) => {
const { index } = titleProps;
const newIndex = activeIndex === index ? -1 : index;
const hasLeaveButton = newIndex >= 0;

setLeaveButton(hasLeaveButton);
setActiveIndex(newIndex);
};

const leaveGroup = (index: number) => {
removeFromMyGroup(index);
};

return (
<Accordion fluid styled>
{myGroup.map(({ groupName, pins }, index) => (
<Fragment key={index}>
<Accordion.Title
active={index === activeIndex}
index={index}
onClick={handleClick}
className={styles.title_section}
>
<Icon name="dropdown" />
{groupName}
{hasLeaveButton && index === activeIndex && (
<div className={styles.leave_button}>
<Button color="orange" onClick={() => leaveGroup(index)}>
Leave
</Button>
</div>
)}
</Accordion.Title>
<Accordion.Content active={index === activeIndex}>
<div className={styles.content_section}>
<ul>
{pins?.map(({ title, description }) => (
<li>
<b>{title}</b>: {description}
</li>
))}
</ul>
</div>
</Accordion.Content>
</Fragment>
))}
</Accordion>
);
}

export default MyGroups;
1 change: 1 addition & 0 deletions src/components/side-panel/public-groups/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./public-groups";
21 changes: 21 additions & 0 deletions src/components/side-panel/public-groups/public-groups.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.top_section {
margin-bottom: 10px;
}

.title_section {
width: 100%;
display: flex;
align-items: center;
}

.join_button {
flex: 1;
display: flex;
justify-content: flex-end;
}

.content_section {
max-height: 20vh;
word-wrap: break-word;
overflow: auto;
}
116 changes: 116 additions & 0 deletions src/components/side-panel/public-groups/public-groups.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { Fragment, useState, useRef } from "react";
import {
Accordion,
Icon,
Button,
Modal,
Form,
TextArea,
} from "semantic-ui-react";
import { Group } from "../../../types";
import styles from "./public-groups.module.scss";

type Props = {
publicGroups: Group[];
addNewGroup: (groupToAdd: Group) => void;
addIndexToMyGroup: (indexToAdd: number) => void;
};

function PublicGroups({ publicGroups, addNewGroup, addIndexToMyGroup }: Props) {
const [activeIndex, setActiveIndex] = useState(-1);
const [hasJoinButton, setJoinButton] = useState(false);
const [isModalOpen, setModalOpen] = useState(false);
const inputRef = useRef<HTMLInputElement>();

const handleClick = (e: any, titleProps: any) => {
const { index } = titleProps;
const newIndex = activeIndex === index ? -1 : index;
const hasJoinButton = newIndex >= 0;

setJoinButton(hasJoinButton);
setActiveIndex(newIndex);
};

const joinGroup = (index: number) => {
addIndexToMyGroup(index);
};

const toggleModal = () => {
setModalOpen(!isModalOpen);
};

const startGroup = () => {
const newGroupName = inputRef?.current?.value;

console.log(newGroupName);
if (newGroupName) {
addNewGroup({ groupName: newGroupName, members: [""] }); // users own name
} else {
alert("Unsuccessful");
}
setModalOpen(!isModalOpen);
};

return (
<>
<Modal open={isModalOpen}>
<Modal.Header>Enter a unique group name</Modal.Header>
<Modal.Content>
<Form.Field>
<Form.Input
input={{ ref: inputRef }}
size="large"
placeholder="Group name"
/>
</Form.Field>
</Modal.Content>
<Modal.Actions>
<Button onClick={toggleModal}>Cancel</Button>
<Button positive type="submit" onClick={startGroup}>
Start
</Button>
</Modal.Actions>
</Modal>

<div className={styles.top_section}>
<Button primary onClick={toggleModal}>
Start a group
</Button>
</div>

<Accordion fluid styled>
{publicGroups.map(({ groupName, members }, index) => (
<Fragment key={index}>
<Accordion.Title
active={index === activeIndex}
index={index}
onClick={handleClick}
className={styles.title_section}
>
<Icon name="dropdown" />
{groupName}
{hasJoinButton && index === activeIndex && (
<div className={styles.join_button}>
<Button positive onClick={() => joinGroup(index)}>
Join
</Button>
</div>
)}
</Accordion.Title>
<Accordion.Content active={index === activeIndex}>
<div className={styles.content_section}>
<ul>
{members.map((member) => (
<li>{member}</li>
))}
</ul>
</div>
</Accordion.Content>
</Fragment>
))}
</Accordion>
</>
);
}

export default PublicGroups;
5 changes: 4 additions & 1 deletion src/components/side-panel/side-panel.module.scss
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
.sidePanel {
.section {
padding: 2% 5%;
height: 100%;
background-color: rgb(255, 245, 234);
}
113 changes: 112 additions & 1 deletion src/components/side-panel/side-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,118 @@
import { Tab } from "semantic-ui-react";
import styles from "./side-panel.module.scss";
import PublicGroups from "./public-groups";
import MyGroups from "./my-groups";
import { Group } from "../../types";

const myGroup: Group[] = [
{
groupName: "Family",
pins: [{ title: "pin1", description: "asfvafdv" }],
members: ["max"],
},
{
groupName: "dorm friends",
pins: [{ title: "pin2", description: "jcfdaskbcnkdusvb" }],
members: ["max"],
},
{
groupName: "gang gang",
pins: [{ title: "pin3", description: "asfvdsacajsblisdnlisafdv" }],
members: ["max"],
},
{
groupName: "hot girl summer",
pins: [{ title: "pin4", description: "asfvafdv" }],
members: ["max"],
},
];

const publicGroups: Group[] = [
{
groupName: "public group 1",
pins: [{ title: "pin4", description: "never wanna give u up" }],
members: ["max"],
},
{
groupName: "best date spots",
pins: [{ title: "pin4", description: "never gonna let u down" }],
members: ["max"],
},
{
groupName: "great food here",
pins: [{ title: "pin4", description: "never gonna turn around" }],
members: ["max"],
},
{
groupName: "Max's friends only",
pins: [{ title: "pin4", description: "and desert you" }],
members: ["max"],
},
{
groupName: "Family",
pins: [{ title: "pin4", description: "asfvafdv" }],
members: ["max"],
},
{
groupName: "dorm friends",
pins: [{ title: "pin4", description: "jcfdaskbcnkdusvb" }],
members: ["max"],
},
{
groupName: "gang gang",
pins: [{ title: "pin4", description: "asfvdsacajsblisdnlisafdv" }],
members: ["max"],
},
{
groupName: "hot girl summer",
pins: [{ title: "pin4", description: "asfvafdv" }],
members: ["max"],
},
];

const addNewGroup = (groupToAdd: Group) => {
myGroup.push(groupToAdd);
publicGroups.push(groupToAdd);
};
const addIndexToMyGroup = (indexToAdd: number) => {
publicGroups[indexToAdd].members.push(""); // users own name
myGroup.push(publicGroups[indexToAdd]);
};
const removeFromMyGroup = (groupToRemove: number) => {
const removeIndex = myGroup.findIndex(
(group) => group === myGroup[groupToRemove],
);
myGroup.splice(removeIndex, 1);
groupToRemove;
};

const panes = [
{
menuItem: "Public Groups",
render: () => (
<Tab.Pane attached={false}>
<PublicGroups
publicGroups={publicGroups}
addNewGroup={addNewGroup}
addIndexToMyGroup={addIndexToMyGroup}
/>
</Tab.Pane>
),
},
{
menuItem: "My Groups",
render: () => (
<Tab.Pane attached={false}>
<MyGroups myGroup={myGroup} removeFromMyGroup={removeFromMyGroup} />
</Tab.Pane>
),
},
];

function SidePanel() {
return <div />;
return (
<Tab menu={{ secondary: true }} panes={panes} className={styles.section} />
);
}

export default SidePanel;
10 changes: 10 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export type Group = {
groupName: string,
pins?: Pin[],
members: string[]
};

export type Pin = {
title: string,
description: string,
};