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

🚀 Implement New UI for Dataverse Companion for Demo #588

Merged
merged 4 commits into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
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
Binary file added src/assets/font/Audiowide-Regular.ttf
Binary file not shown.
8 changes: 8 additions & 0 deletions src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@
font-display: auto;
}

@font-face {
font-family: 'Audiowide';
src: url('./assets/font/Audiowide-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}

.content {
padding-top: 14px;
margin-left: 110px;
Expand Down
77 changes: 9 additions & 68 deletions src/pages/public/Companion/components/dataverse/Dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,12 @@ import React, {
import {
useLocation, useHistory
} from "react-router-dom";
import {
Typography
} from "@material-ui/core";
import Quiz from "./Quiz";
import Leaderboard from "./Leaderboard";

const useStyles = {
root: {
position: "relative",
minHeight: "180vh",
background: "linear-gradient(135deg, #3C1F62, #5A3D89, #2F3C53, #121C2C)",
color: "white",
padding: "20px",
textAlign: "center", // Centering the content
},
heading: {
fontSize: "6rem", // Making the main heading bigger
fontWeight: "bold", // Making the text bold
marginTop: "40px", // Adding space above the heading
},
subheading: {
fontSize: "1.5rem", // Increasing the font size for subheadings
fontWeight: "500", // Optional: make the subheading a bit lighter
},
text: {
fontSize: "1.2rem", // Make other text a bit larger
},
infoRow: {
display: "flex", // Align items in a row
justifyContent: "center", // Center the row
gap: "30px", // Space between the items
marginBottom: "20px", // Space below the row
},
label: {
color: "#B0B0B0", // Gray color for labels
fontWeight: "500", // Optional: make labels a bit lighter
},
value: {
background: "linear-gradient(to bottom, #FFFFFF, #7B7DFF)", // Gradient from white to light purple
WebkitBackgroundClip: "text", // Clip the background to the text
color: "transparent", // Make the text color transparent so the gradient shows through
fontWeight: "700", // Optional: make values bold
},
};

const Dashboard = () => {
const startTime = new Date();
const endTime = new Date(startTime.getTime() + 5 * 60000);
const location = useLocation();
const history = useHistory();
const {
Expand All @@ -64,32 +24,13 @@ const Dashboard = () => {
}, [teamPoints, teamName, history]);

return (
<div style={useStyles.root}>
{!teamPoints || !teamName ? (
<Typography>Redirecting to Companion...</Typography>
) : (
<>
<Typography style={useStyles.heading}>Team Dashboard</Typography>
{/* Flex container for the Team Name and Current Points */}
<div style={useStyles.infoRow}>
<Typography style={useStyles.label} variant="h6">
Team Name:
</Typography>
<Typography style={useStyles.value} variant="h6">
{teamName}
</Typography>
<Typography style={useStyles.label} variant="h6">
Current Points:
</Typography>
<Typography style={useStyles.value} variant="h6">
{teamPoints}
</Typography>
</div>
<Quiz teamData={teamData} userRegistration={userRegistration} />
<Leaderboard teamName={teamName} teamScore={teamPoints} />
</>
)}
</div>
<Quiz
teamName={teamName}
teamPoints={teamPoints}
startTime={startTime}
endTime={endTime}
userRegistration={userRegistration}
/>
);
};

Expand Down
272 changes: 222 additions & 50 deletions src/pages/public/Companion/components/dataverse/Leaderboard.js
Original file line number Diff line number Diff line change
@@ -1,64 +1,236 @@
import React from "react";
import { Box, Typography, Button } from "@material-ui/core";
import React, { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { ThemeProvider, createTheme } from "@mui/material/styles";
import {
CssBaseline,
Box,
Typography,
List,
ListItem,
Button
} from "@mui/material";
import EmojiEventsIcon from "@mui/icons-material/EmojiEvents";
import MilitaryTechIcon from "@mui/icons-material/MilitaryTech";
import WorkspacePremiumIcon from "@mui/icons-material/WorkspacePremium";

const theme = createTheme({
components: {
MuiCssBaseline: {
styleOverrides: {
body: {
background: "linear-gradient(135deg, #3C1F62, #5A3D89, #2F3C53, #121C2C)",
minHeight: "100vh",
margin: 0,
},
},
},
},
palette: {
primary: {
main: "#8b5cf6"
},
secondary: {
main: "#6366f1"
}
},
});

function Leaderboard({ teams: initialTeams }) {
const [teams, setTeams] = useState(initialTeams);

const updateRandomTeams = () => {
setTeams((prevTeams) => {
const newTeams = [...prevTeams];
const indices = new Set();
while (indices.size < 2) {
indices.add(Math.floor(Math.random() * newTeams.length));
}

indices.forEach((index) => {
newTeams[index] = {
...newTeams[index],
score: Math.floor(Math.random() * 150)
};
});

return newTeams.sort((a, b) => b.score - a.score);
});
};

const getRankIcon = (index) => {
switch (index) {
case 0:
return <EmojiEventsIcon sx={{ color: "#FFD700" }} />;
case 1:
return <MilitaryTechIcon sx={{ color: "#C0C0C0" }} />;
case 2:
return <WorkspacePremiumIcon sx={{ color: "#CD7F32" }} />;
default:
return null;
}
};

const LeaderboardRow = ({ placement, teamName, score, isTeam }) => {
return (
<Box
display="flex"
justifyContent="space-between"
alignItems="center"
sx={{
padding: "10px 20px",
marginY: "10px",
maxWidth: "1000px",
backgroundColor: isTeam ? "#7163BC" : "#1B1746", // Background color
color: "#fff", // Text color: black for team row
borderRadius: "8px",
width: "100%", // Ensures the row takes full width
maxWidth: 400,
margin: "0 auto",
bgcolor: "background.paper",
borderRadius: 2,
overflow: "hidden",
boxShadow: 3
}}
>
<Typography variant="h6">{placement}</Typography>
<Typography variant="body1">{teamName}</Typography>
<Typography variant="body1">{score}</Typography>
<Box
sx={{
background: "linear-gradient(to right, #8b5cf6, #6366f1)",
p: 2.5
}}
>
<Typography
variant="h4"
component="h2"
sx={{ color: "white", fontWeight: "bold", textAlign: "center" }}
>
Leaderboard
</Typography>
</Box>
<List sx={{ p: 0 }}>
<AnimatePresence>
{teams.map((team, index) => (
<motion.div
key={team.id}
layout
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{
type: "spring",
stiffness: 200,
damping: 50,
mass: 1
}}
>
<ListItem
sx={{
display: "flex",
alignItems: "center",
borderBottom: "1px solid",
borderColor: "divider",
py: 1.5
}}
>
<Box
component={motion.div}
layout
sx={{
display: "flex",
alignItems: "center",
justifyContent: "center",
width: 32,
height: 32,
bgcolor: "action.hover",
borderRadius: "50%",
mr: 1.5,
fontWeight: "bold",
color: "text.secondary"
}}
>
<AnimatePresence mode="popLayout">
<motion.div
key={index}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0, transition: { duration: 0 } }}
transition={{ duration: 0.1 }}
>
{getRankIcon(index) || index + 1}
</motion.div>
</AnimatePresence>
</Box>
<Typography
component={motion.span}
layout
variant="body1"
sx={{
flexGrow: 1,
fontWeight: "bold",
color: "text.primary"
}}
>
{team.name}
</Typography>
<Typography
component={motion.span}
layout
variant="body1"
sx={{ fontWeight: "bold", color: "text.secondary" }}
initial={{ scale: 1 }}
animate={{ scale: [1, 1.2, 1] }}
transition={{ duration: 0.3 }}
>
{team.score}
</Typography>
</ListItem>
</motion.div>
))}
</AnimatePresence>
</List>
<Box sx={{ display: "flex", justifyContent: "center", mt: 2, mb: 2 }}>
<Button variant="contained" color="primary" onClick={updateRandomTeams}>
Update Random Teams
</Button>
</Box>
</Box>
);
};
}

function GlobalLeaderboardExample() {
const initialTeams = [
{ id: "1", name: "Team Alpha", score: 100 },
{ id: "2", name: "Team Beta", score: 85 },
{ id: "3", name: "Team Gamma", score: 95 },
{ id: "4", name: "Team Delta", score: 70 },
{ id: "5", name: "Team Epsilon", score: 110 },
{ id: "6", name: "Team Zeta", score: 90 },
{ id: "7", name: "Team Eta", score: 75 },
{ id: "8", name: "Team Theta", score: 105 },
{ id: "9", name: "Team Iota", score: 80 },
{ id: "10", name: "Team Omega", score: 95 },
];

const Leaderboard = ({ teamName, teamScore }) => {
return (
<div style={{ textAlign: "center", marginTop: "200px" }}>
<Typography variant="h4" gutterBottom>
Leaderboard
</Typography>
<Typography variant="subtitle1" gutterBottom>
Check out how your team is doing:
</Typography>
<ThemeProvider theme={theme}>
<CssBaseline />
<Box sx={{ p: 2 }}>
<Leaderboard teams={initialTeams} />
</Box>
</ThemeProvider>
);
}

<div
style={{
marginBottom: "20px",
marginTop: "20px",
display: "flex", // Enable Flexbox layout
flexDirection: "column", // Stack rows vertically
alignItems: "center", // Center content horizontally
justifyContent: "center", // Optional: centers content vertically (if container height is defined)
width: "100%", // Ensures the div takes up full available width
}}
>
<LeaderboardRow placement={1} teamName="Team A" score={1500} />
<LeaderboardRow placement={2} teamName="Team B" score={1200} />
<LeaderboardRow placement={3} teamName="Team C" score={1000} />
...
<LeaderboardRow placement={11} teamName="Team mogged" score={1000} />
<LeaderboardRow placement={12} teamName={teamName} score={teamScore} isTeam />
<LeaderboardRow placement={13} teamName="Team shitters" score={1000} />
</div>
function LocalLeaderboardExample() {
const initialTeams = [
{ id: "1", name: "Team Alpha", score: 100 },
{ id: "2", name: "Team Beta", score: 85 },
{ id: "3", name: "Team Gamma", score: 95 },
{ id: "4", name: "Team Delta", score: 70 },
{ id: "5", name: "Team Epsilon", score: 110 },
{ id: "6", name: "Team Zeta", score: 90 },
{ id: "7", name: "Team Eta", score: 75 },
{ id: "8", name: "Team Theta", score: 105 },
{ id: "9", name: "Team Iota", score: 80 },
{ id: "10", name: "Team Omega", score: 95 },
];

<Button variant="contained" color="secondary" style={{ margin: "10px", minWidth: "1000px", minHeight: "40px" }}>
Check out the full leaderboard
</Button>
</div>
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Box sx={{ p: 2 }}>
<Leaderboard teams={initialTeams} />
</Box>
</ThemeProvider>
);
};
}

export default Leaderboard;
export { GlobalLeaderboardExample, LocalLeaderboardExample };
Loading
Loading