mirror of
https://github.com/idanoo/GoScrobble.git
synced 2024-11-22 08:25:14 +00:00
0.0.22
- Rework navbar + user pages
This commit is contained in:
parent
fb9ebef49c
commit
3f3296e649
@ -3,7 +3,7 @@ stages:
|
|||||||
- bundle
|
- bundle
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
VERSION: 0.0.21
|
VERSION: 0.0.22
|
||||||
|
|
||||||
build-go:
|
build-go:
|
||||||
image: golang:1.16.2
|
image: golang:1.16.2
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
# 0.0.22
|
||||||
|
- Rework navbar + user pages
|
||||||
|
|
||||||
# 0.0.21
|
# 0.0.21
|
||||||
- Add ez deploy script
|
- Add ez deploy script
|
||||||
- Half implemented JWT refresh tokens, need to finish JS implementation
|
- Half implemented JWT refresh tokens, need to finish JS implementation
|
||||||
|
@ -587,7 +587,7 @@ func getServerInfo(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
info := ServerInfo{
|
info := ServerInfo{
|
||||||
Version: "0.0.21",
|
Version: "0.0.22",
|
||||||
RegistrationEnabled: cachedRegistrationEnabled,
|
RegistrationEnabled: cachedRegistrationEnabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import jwt from 'jwt-decode'
|
import jwt from 'jwt-decode'
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
import AuthContext from '../Contexts/AuthContext';
|
|
||||||
import { useContext } from 'react';
|
|
||||||
|
|
||||||
function getHeaders() {
|
function getHeaders() {
|
||||||
const user = JSON.parse(localStorage.getItem('user'));
|
const user = JSON.parse(localStorage.getItem('user'));
|
||||||
|
@ -35,7 +35,7 @@ html, body {
|
|||||||
|
|
||||||
.pageWrapper {
|
.pageWrapper {
|
||||||
background-color: #282c34;
|
background-color: #282c34;
|
||||||
padding: 100px 15px 0 15px;
|
padding: 90px 15px 0 15px;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Route, Switch, withRouter } from 'react-router-dom';
|
import { Route, Switch, withRouter } from 'react-router-dom';
|
||||||
import Home from './Pages/Home';
|
import Home from './Pages/Home';
|
||||||
import About from './Pages/About';
|
import About from './Pages/About';
|
||||||
import Dashboard from './Pages/Dashboard';
|
|
||||||
import Profile from './Pages/Profile';
|
import Profile from './Pages/Profile';
|
||||||
import Artist from './Pages/Artist';
|
import Artist from './Pages/Artist';
|
||||||
import Album from './Pages/Album';
|
import Album from './Pages/Album';
|
||||||
@ -33,7 +32,6 @@ const App = () => {
|
|||||||
<Route exact={boolTrue} path={["/", "/home"]} component={Home} />
|
<Route exact={boolTrue} path={["/", "/home"]} component={Home} />
|
||||||
<Route path="/about" component={About} />
|
<Route path="/about" component={About} />
|
||||||
|
|
||||||
<Route path="/dashboard" component={Dashboard} />
|
|
||||||
<Route path="/user" component={User} />
|
<Route path="/user" component={User} />
|
||||||
<Route path="/u/:uuid" component={Profile} />
|
<Route path="/u/:uuid" component={Profile} />
|
||||||
<Route path="/artist/:uuid" component={Artist} />
|
<Route path="/artist/:uuid" component={Artist} />
|
||||||
|
@ -12,8 +12,9 @@ const menuItems = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
const loggedInMenuItems = [
|
const loggedInMenuItems = [
|
||||||
'Dashboard',
|
'Home',
|
||||||
'Docs',
|
'My Profile',
|
||||||
|
// 'Docs',
|
||||||
]
|
]
|
||||||
|
|
||||||
const isMobile = () => {
|
const isMobile = () => {
|
||||||
@ -50,8 +51,7 @@ const Navigation = () => {
|
|||||||
key={menuItem}
|
key={menuItem}
|
||||||
className="navLinkMobile"
|
className="navLinkMobile"
|
||||||
style={active === menuItem.toLowerCase() ? activeStyle : {}}
|
style={active === menuItem.toLowerCase() ? activeStyle : {}}
|
||||||
to={menuItem.toLowerCase()}
|
to={menuItem === "My Profile" ? "/u/" + user.username : "/" + menuItem.toLowerCase()} onClick={toggleCollapsed}
|
||||||
onClick={toggleCollapsed}
|
|
||||||
>{menuItem}</Link>
|
>{menuItem}</Link>
|
||||||
</NavItem>
|
</NavItem>
|
||||||
)}
|
)}
|
||||||
@ -60,7 +60,7 @@ const Navigation = () => {
|
|||||||
style={active === "user" ? activeStyle : {}}
|
style={active === "user" ? activeStyle : {}}
|
||||||
className="navLinkMobile"
|
className="navLinkMobile"
|
||||||
onClick={toggleCollapsed}
|
onClick={toggleCollapsed}
|
||||||
>{user.username}</Link>
|
>Settings</Link>
|
||||||
{user.admin &&
|
{user.admin &&
|
||||||
<Link
|
<Link
|
||||||
to="/admin"
|
to="/admin"
|
||||||
@ -115,7 +115,7 @@ const Navigation = () => {
|
|||||||
key={menuItem}
|
key={menuItem}
|
||||||
className="navLink"
|
className="navLink"
|
||||||
style={active === menuItem.toLowerCase() ? activeStyle : {}}
|
style={active === menuItem.toLowerCase() ? activeStyle : {}}
|
||||||
to={"/" + menuItem.toLowerCase()}
|
to={menuItem === "My Profile" ? "/u/" + user.username : "/" + menuItem.toLowerCase()}
|
||||||
>
|
>
|
||||||
{menuItem}
|
{menuItem}
|
||||||
</Link>
|
</Link>
|
||||||
@ -140,7 +140,7 @@ const Navigation = () => {
|
|||||||
to="/user"
|
to="/user"
|
||||||
style={active === "user" ? activeStyle : {}}
|
style={active === "user" ? activeStyle : {}}
|
||||||
className="navLink"
|
className="navLink"
|
||||||
>{user.username}</Link>
|
>Settings</Link>
|
||||||
{user.admin &&
|
{user.admin &&
|
||||||
<Link
|
<Link
|
||||||
to="/admin"
|
to="/admin"
|
||||||
|
@ -4,7 +4,7 @@ import { Link } from 'react-router-dom';
|
|||||||
const ScrobbleTable = (props) => {
|
const ScrobbleTable = (props) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<table border={1} cellPadding={5}>
|
<table width={900} border={1} cellPadding={5}>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Timestamp</td>
|
<td>Timestamp</td>
|
||||||
|
11
web/src/Components/TopTable.css
Normal file
11
web/src/Components/TopTable.css
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
.biggestWrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.biggestBox {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 300px;
|
||||||
|
height: 300px;
|
||||||
|
}
|
47
web/src/Components/TopTable.js
Normal file
47
web/src/Components/TopTable.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import React from "react";
|
||||||
|
import './TopTable.css'
|
||||||
|
import TopTableBox from './TopTableBox';
|
||||||
|
|
||||||
|
const TopTable = (props) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<span>Top {props.type}</span>
|
||||||
|
<div className="biggestWrapper">
|
||||||
|
<div className="biggestBox">
|
||||||
|
<TopTableBox
|
||||||
|
size={300}
|
||||||
|
number="1"
|
||||||
|
title="hot milk"
|
||||||
|
uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316"
|
||||||
|
img="https://i.scdn.co/image/a397625e38fb671f1baa81997b4c1fd2670fcb10"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="biggestBox">
|
||||||
|
<TopTableBox
|
||||||
|
size={150}
|
||||||
|
number="2"
|
||||||
|
title="Pendulum"
|
||||||
|
uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316"
|
||||||
|
img="https://i.scdn.co/image/0f476171f283207656e95e1005cea7040be475d7"
|
||||||
|
/>
|
||||||
|
<TopTableBox size={150} number="3" title="Illenium" uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316" />
|
||||||
|
<TopTableBox size={150} number="4" title="As It is" uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316" />
|
||||||
|
<TopTableBox size={150} number="5" title="CHVRCHES" uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316" />
|
||||||
|
</div>
|
||||||
|
<div className="biggestBox">
|
||||||
|
<TopTableBox size={100} number="6" title="tester" uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316" />
|
||||||
|
<TopTableBox size={100} number="7" title="tester" uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316" />
|
||||||
|
<TopTableBox size={100} number="8" title="tester" uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316" />
|
||||||
|
<TopTableBox size={100} number="9" title="tester" uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316" />
|
||||||
|
<TopTableBox size={100} number="10" title="tester" uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316" />
|
||||||
|
<TopTableBox size={100} number="11" title="tester" uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316" />
|
||||||
|
<TopTableBox size={100} number="12" title="tester" uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316" />
|
||||||
|
<TopTableBox size={100} number="13" title="tester" uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316" />
|
||||||
|
<TopTableBox size={100} number="14" title="tester" uuid="a2bcc230-f7be-4087-b49a-8c43d19ed316" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TopTable;
|
22
web/src/Components/TopTableBox.css
Normal file
22
web/src/Components/TopTableBox.css
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
.topTableBox:hover {
|
||||||
|
opacity: 0.7;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
background-size: cover;
|
||||||
|
background-position: top center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topOverlay {
|
||||||
|
position: absolute;
|
||||||
|
margin: 5px;
|
||||||
|
padding: 0 5px 0 5px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.topText {
|
||||||
|
margin: -2px 0 0 0;
|
||||||
|
font-size: 11pt;
|
||||||
|
color: #FFF;
|
||||||
|
}
|
32
web/src/Components/TopTableBox.js
Normal file
32
web/src/Components/TopTableBox.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import './TopTableBox.css'
|
||||||
|
|
||||||
|
const TopTableBox = (props) => {
|
||||||
|
let img = 'https://www.foot.com/wp-content/uploads/2017/06/placeholder-square-300x300.jpg';
|
||||||
|
if (props.img && props.img !== '') {
|
||||||
|
img = props.img
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link to={"/artist/"+props.uuid} float="left" >
|
||||||
|
<div
|
||||||
|
className="topTableBox"
|
||||||
|
style={{
|
||||||
|
backgroundImage: `url(${img})`,
|
||||||
|
backgroundSize: `cover`,
|
||||||
|
backgroundPosition: `top center`,
|
||||||
|
width: `${props.size}px`,
|
||||||
|
height: `${props.size}px`,
|
||||||
|
float: `left`,
|
||||||
|
}} >
|
||||||
|
<div className="topOverlay">
|
||||||
|
<span className="topText">#{props.number} {props.title}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TopTableBox;
|
@ -23,7 +23,7 @@ const AuthContextProvider = ({ children }) => {
|
|||||||
localStorage.setItem('user', JSON.stringify(user));
|
localStorage.setItem('user', JSON.stringify(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
setUser(user)
|
setUser(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
import React, { useState, useEffect, useContext } from 'react';
|
|
||||||
import '../App.css';
|
|
||||||
import './Dashboard.css';
|
|
||||||
import { useHistory } from "react-router";
|
|
||||||
import { getRecentScrobbles } from '../Api/index';
|
|
||||||
import ScaleLoader from 'react-spinners/ScaleLoader';
|
|
||||||
import ScrobbleTable from "../Components/ScrobbleTable";
|
|
||||||
import AuthContext from '../Contexts/AuthContext';
|
|
||||||
|
|
||||||
const Dashboard = () => {
|
|
||||||
const history = useHistory();
|
|
||||||
let { user } = useContext(AuthContext);
|
|
||||||
let [loading, setLoading] = useState(true);
|
|
||||||
let [dashboardData, setDashboardData] = useState({});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!user) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
getRecentScrobbles(user.uuid)
|
|
||||||
.then(data => {
|
|
||||||
setDashboardData(data);
|
|
||||||
setLoading(false);
|
|
||||||
})
|
|
||||||
}, [user])
|
|
||||||
|
|
||||||
|
|
||||||
if (!user) {
|
|
||||||
history.push("/login")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loading) {
|
|
||||||
return (
|
|
||||||
<div className="pageWrapper">
|
|
||||||
<ScaleLoader color="#6AD7E5" />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="pageWrapper">
|
|
||||||
<h1>
|
|
||||||
{user.username}'s Dashboard!
|
|
||||||
</h1>
|
|
||||||
<div className="pageBody">
|
|
||||||
{loading
|
|
||||||
? <ScaleLoader color="#6AD7E5" size={60} />
|
|
||||||
: <ScrobbleTable data={dashboardData.items} />
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Dashboard;
|
|
@ -13,7 +13,7 @@ const Login = () => {
|
|||||||
let { Login, loading, user } = useContext(AuthContext);
|
let { Login, loading, user } = useContext(AuthContext);
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
history.push("/dashboard");
|
history.push("/u/" + user.username);
|
||||||
}
|
}
|
||||||
|
|
||||||
const redirectReset = () => {
|
const redirectReset = () => {
|
||||||
|
@ -4,6 +4,7 @@ import './Profile.css';
|
|||||||
import ScaleLoader from 'react-spinners/ScaleLoader';
|
import ScaleLoader from 'react-spinners/ScaleLoader';
|
||||||
import { getProfile } from '../Api/index'
|
import { getProfile } from '../Api/index'
|
||||||
import ScrobbleTable from '../Components/ScrobbleTable'
|
import ScrobbleTable from '../Components/ScrobbleTable'
|
||||||
|
import TopTable from '../Components/TopTable'
|
||||||
|
|
||||||
const Profile = (route) => {
|
const Profile = (route) => {
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
@ -50,6 +51,8 @@ const Profile = (route) => {
|
|||||||
{profile.username}'s Profile
|
{profile.username}'s Profile
|
||||||
</h1>
|
</h1>
|
||||||
<div className="pageBody">
|
<div className="pageBody">
|
||||||
|
<TopTable type="Artists" />
|
||||||
|
<br/>
|
||||||
Last 10 scrobbles...<br/>
|
Last 10 scrobbles...<br/>
|
||||||
<ScrobbleTable data={profile.scrobbles}/>
|
<ScrobbleTable data={profile.scrobbles}/>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user