Skip to content

Commit

Permalink
Merge pull request #6 from winwanwon/card-ui-revamp
Browse files Browse the repository at this point in the history
Card UI revamp + make it responsive
  • Loading branch information
winwanwon committed May 28, 2023
2 parents 0a71f77 + 1be26dd commit 9f2c1a3
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 159 deletions.
95 changes: 95 additions & 0 deletions src/components/PlayArea.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React from 'react';
import { Box } from '@mui/material';
import DoneIcon from '@mui/icons-material/Done';
import QuestionMarkIcon from '@mui/icons-material/QuestionMark';
import ClearIcon from '@mui/icons-material/Clear';

import { UserDatabase } from '../types';
import { AppState } from '../enum';

interface OwnProps {
appState: AppState;
users: UserDatabase;
uuid: string;
showDeleteButton: boolean;
onRemove: (uuid: string) => void;
}

const PlayArea: React.FC<OwnProps> = (props: OwnProps) => {
const { appState, uuid, users, onRemove } = props;
const userCount = Object.keys(users).length;

const renderAttendees = Object.keys(users).map((key) => {
const selected = users[key].selectedOption > -1;
const isRevealed = appState === AppState.Revealed;
const confirmedValue = selected || isRevealed;

const removePlayer = () => {
onRemove(key)
}

const nonSelectedCardStyles = "border-slate-500";
const selectedCardStyles = "border-teal-400 shadow-teal-500/40";
const circleBorderStyles = "hidden md:flex w-16 h-16 py-3 border-2 rounded-full justify-center items-center";

const renderStatusMarker = () => {
if (!selected) {
return (
<>
<div className={`md:hidden w-2 h-2 rounded-full mx-4 animate-pulse bg-slate-500`} />
<div className={`${circleBorderStyles} border-slate-500 animate-pulse`}>
<QuestionMarkIcon color="secondary" sx={{ fontSize: 44 }} />
</div>
</>
);
}
return (
<>
<div className="md:hidden w-2 h-2 ml-3 mr-5 flex items-center">
<DoneIcon color="primary" sx={{ fontSize: 22 }} />
</div>
<div className={`${circleBorderStyles} border-teal-500`}>
<DoneIcon color="primary" sx={{ fontSize: 44 }} />
</div>
</>
);
}

const renderPoint = () => {
return (
<div className="w-10 h-2 md:w-16 md:h-16 flex justify-center items-center text-2xl md:text-4xl ƒont-black text-teal-600 text-center">
<div className="md:hidden">
{selected ? users[key].selectedOption : "-"}
</div>
<div className={`${circleBorderStyles} border-teal-500`}>
{selected ? users[key].selectedOption : "-"}
</div>
</div>
);
}

return (
<div className={`h-12 md:h-32 md:w-28 md:py-3 border rounded-lg shadow-md bg-white flex md:flex-col md:justify-between items-center ${confirmedValue ? selectedCardStyles : nonSelectedCardStyles}`}>
{isRevealed ? renderPoint() : renderStatusMarker()}
<div className={`text-slate-900 text-sm ${key === uuid ? 'font-bold' : ''}`}>
{users[key].name}
{props.showDeleteButton && key !== uuid && <button className="text-red-500" onClick={removePlayer}><ClearIcon sx={{ fontSize: 16 }} /></button>}
</div>
</div>
);
});

return (
<>
<div className={`md:hidden w-5/6 md:w-auto grid grid-cols-1 gap-2`}>
{renderAttendees}
</div>
<Box className="hidden md:grid" gridTemplateColumns={`repeat(${userCount <= 6 ? userCount : Math.ceil(userCount / 2)}, ${userCount <= 6 ? 1 : 2}fr)`} gap={1} >
{renderAttendees}
</Box>
</>
);

}

export default PlayArea;
8 changes: 2 additions & 6 deletions src/components/PopUpModal.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from "react";
import { Box, Button, Modal, Stack, TextField, Typography } from "@mui/material";
import { Container } from "@mui/material";
import { isValidUserName } from "../utils";

interface OwnProps {
title: string;
label: string;
open: boolean;
value: string;
onInputChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
onSubmit: () => void;
onClose?: () => void;
setValue?: (s: string) => void;
Expand All @@ -27,10 +27,6 @@ const style = {
};

const PopUpModal: React.FC<OwnProps> = (props: OwnProps) => {
const onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
props.setValue && isValidUserName(e.target.value) && props.setValue(e.target.value);
}

const onKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
props.onSubmit();
Expand All @@ -49,7 +45,7 @@ const PopUpModal: React.FC<OwnProps> = (props: OwnProps) => {
<Typography variant="h5" gutterBottom component="div">
{props.title}
</Typography>
<TextField label={props.label} variant="filled" onChange={onInputChange} onKeyPress={onKeyPress} value={props.value} autoFocus={true} />
<TextField label={props.label} variant="filled" onChange={props.onInputChange} onKeyPress={onKeyPress} value={props.value} autoFocus={true} />
<Button variant="contained" onClick={props.onSubmit} disabled={!props.value}>Enter</Button>
</Stack>
</Box>
Expand Down
111 changes: 0 additions & 111 deletions src/components/Summary.tsx

This file was deleted.

72 changes: 31 additions & 41 deletions src/pages/Room.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import { v4 as uuidv4 } from "uuid";
import { FirebaseApp } from "firebase/app";
import { getAnalytics, logEvent } from "firebase/analytics";
import { get, getDatabase, onValue, ref, remove, set, update } from "firebase/database";
import { Box, Snackbar, Stack } from "@mui/material";
import { Snackbar, Stack } from "@mui/material";

import { AppState, PokerMode } from "../enum";
import { User, UserDatabase } from "../types";
import { getAverageFromResult, getModeFromResult, isValidRoomName } from "../utils";
import { getAverageFromResult, getModeFromResult, isValidRoomName, isValidUserName } from "../utils";

import PopUpModal from "../components/PopUpModal";
import OptionButtonGroup from "../components/OptionButtonGroup";
import CommandButton from "../components/CommandButton";
import Summary from "../components/Summary";
import PlayArea from "../components/PlayArea";
import Result from "../components/Result";
import RoomDetail from "../components/RoomDetail";
import Header from "../components/Header";
Expand All @@ -27,8 +27,7 @@ const InRoom: React.FC<Props> = (props: Props) => {
const app = props.firebaseApp;
const analytics = getAnalytics();
const database = getDatabase(app);
const uuid = window.sessionStorage.getItem("uuid") || uuidv4();
window.sessionStorage.setItem("uuid", uuid);
const uuid = window.localStorage.getItem("uuid") || uuidv4();
window.localStorage.setItem("uuid", uuid);

const params = useParams();
Expand All @@ -46,7 +45,7 @@ const InRoom: React.FC<Props> = (props: Props) => {

const usersDbPath = roomName + '/users/';
const stateDbPath = roomName + '/state/';
const thisUserDbPath = roomName + '/users/' + uuid;
const thisUserDbPath = usersDbPath + uuid;
const navigate = useNavigate();

useEffect(() => {
Expand Down Expand Up @@ -213,40 +212,30 @@ const InRoom: React.FC<Props> = (props: Props) => {
};

const content = (
<>
<Box
display="flex"
alignItems="center"
justifyContent="center"
width="100%"
height="95%"
>
{!modalOpen && <Summary appState={appState} uuid={uuid} users={users} showDeleteButton={sudoMode} onRemove={onRemove} />}
</Box>
<Box
position="absolute"
bottom={20}
left={0}
right={0}
display="flex"
justifyContent="center"
<div className="flex flex-col h-full w-full justify-between items-center">
<div />
<PlayArea
appState={appState}
uuid={uuid}
users={users}
showDeleteButton={sudoMode}
onRemove={onRemove}
/>
<Stack
spacing={1}
minWidth={420}
>
<Stack
spacing={1}
minWidth={420}
>
{appState === AppState.Revealed && <Result average={averageEsimation} mode={modeEstimation} />}
{appState === AppState.Init && optionButtons}
{/* {appState === AppState.Init && selectedUserDisplay} */}
<CommandButton
content={getButtonContent()}
color={getButtonColor()}
onClick={onButtonClick}
resetAppState={resetAppState}
/>
</Stack>
</Box>
</>
{appState === AppState.Revealed && <Result average={averageEsimation} mode={modeEstimation} />}
{appState === AppState.Init && optionButtons}
{/* {appState === AppState.Init && selectedUserDisplay} */}
<CommandButton
content={getButtonContent()}
color={getButtonColor()}
onClick={onButtonClick}
resetAppState={resetAppState}
/>
</Stack>
</div>
);

return (
Expand All @@ -266,7 +255,7 @@ const InRoom: React.FC<Props> = (props: Props) => {
}
/>
<div className="w-full max-w-none h-screen bg-slate-50 pt-20">
<div className="container max-w-6xl mx-auto flex h-full pb-20 justify-center items-center">
<div className="container mx-auto flex h-full pb-12">
{!modalOpen && content}
</div>
<PopUpModal
Expand All @@ -276,13 +265,14 @@ const InRoom: React.FC<Props> = (props: Props) => {
value={name}
setValue={setName}
onSubmit={onSubmitName}
onInputChange={(e) => isValidUserName(e.target.value) && setName(e.target.value)}
/>
<Snackbar
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
open={snackBarOpen}
autoHideDuration={2000}
onClose={() => setSnackBarOpen(false)}
message="Invitation URL copied!"
message="Room URL copied!"
/>
<SettingsModal
open={settingsOpen}
Expand Down
2 changes: 1 addition & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ export const getAverageFromResult = (selectedUser: User[]): number => {
};

export const isValidRoomName = (roomName: string): boolean => !!(roomName.match("^[a-zA-Z0-9-]*$") != null && roomName.length <= 16);
export const isValidUserName = (userName: string): boolean => !!(userName.match("^[a-zA-Z0-9]*$") != null && userName.length <= 12);
export const isValidUserName = (userName: string): boolean => !!(userName.match("^[a-zA-Z0-9]*$") != null && userName.length <= 10);

0 comments on commit 9f2c1a3

Please sign in to comment.