Skip to content

Commit

Permalink
Merge pull request #158 from osu-tournament-rating/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
hburn7 authored Apr 16, 2024
2 parents 52edd14 + 88a2c72 commit 6de09fe
Show file tree
Hide file tree
Showing 60 changed files with 1,415 additions and 304 deletions.
156 changes: 89 additions & 67 deletions app/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ export async function getSession(onlyData: boolean = false) {
return {
isLogged: session?.isLogged,
id: session?.id,
userId: session?.userId,
playerId: session?.playerId,
osuId: session?.osuId,
osuCountry: session?.osuCountry,
osuPlayMode: session?.osuPlayMode,
osuPlayModeSelected: session?.osuPlayModeSelected,
username: session?.username,
roles: session?.roles,
scopes: session?.scopes,
accessToken: session?.accessToken,
};

Expand All @@ -40,7 +40,7 @@ export async function getSession(onlyData: boolean = false) {

export async function login(cookie: {
accessToken: string;
refreshToken: string;
refreshToken?: string;
accessExpiration?: number;
}) {
const session = await getSession();
Expand All @@ -56,12 +56,15 @@ export async function login(cookie: {

session.accessToken = cookie.accessToken;

await cookies().set('OTR-Refresh-Token', cookie.refreshToken, {
httpOnly: true,
path: '/',
sameSite: 'strict',
secure: process.env.NODE_ENV === 'production',
});
if (cookie?.refreshToken) {
await cookies().set('OTR-Refresh-Token', cookie.refreshToken, {
httpOnly: true,
path: '/',
sameSite: 'strict',
secure: process.env.NODE_ENV === 'production',
maxAge: 1209600,
});
}

const loggedUser = await getLoggedUser(cookie.accessToken);

Expand All @@ -72,21 +75,27 @@ export async function login(cookie: {
}

session.id = loggedUser.id;
session.userId = loggedUser.userId;
session.playerId = loggedUser.playerId;
session.osuId = loggedUser.osuId;
session.osuCountry = loggedUser.osuCountry;
session.osuPlayMode = loggedUser.osuPlayMode;
session.osuPlayModeSelected = loggedUser.osuPlayMode;
session.username = loggedUser.username;
session.roles = loggedUser.roles;
session.osuPlayModeSelected = loggedUser.osuPlayMode; // maybe to delete
session.username = loggedUser.osuUsername;
session.scopes = loggedUser.scopes;
session.isLogged = true;

await cookies().set('OTR-user-selected-osu-mode', loggedUser.osuPlayMode, {
httpOnly: true,
path: '/',
sameSite: 'strict',
secure: process.env.NODE_ENV === 'production',
maxAge: 1209600,
});

await session.save();

/* await changeOsuModeCookie(res.osuPlayMode); */
return NextResponse.redirect(
new URL('/', process.env.REACT_APP_ORIGIN_URL)
);
return NextResponse.redirect(new URL('/', process.env.REACT_APP_ORIGIN_URL));
}

export async function getLoggedUser(accessToken: string) {
Expand Down Expand Up @@ -169,7 +178,7 @@ export async function saveTournamentMatches(
const session = await getSession(true);

/* IF USER IS UNAUTHORIZED REDIRECT TO HOMEPAGE */
if (!session.userId) return redirect('/');
if (!session.id) return redirect('/');

try {
/* REGEX TO REMOVE ALL SPACES AND ENTERS */
Expand Down Expand Up @@ -199,15 +208,15 @@ export async function saveTournamentMatches(
rankRangeLowerBound: parseInt(formData.get('rankRestriction')),
teamSize: parseInt(formData.get('teamSize')),
mode: parseInt(formData.get('gameMode')),
submitterId: session?.userId ?? 0,
submitterId: session?.id ?? 0,
ids: matchIDs,
});

let isSubmissionVerified =
formData.get('verifierCheckBox') == 'on' ?? false;

await fetch(
`${process.env.REACT_APP_API_URL}/matches/batch?verified=${isSubmissionVerified}`,
let tournamentSubmit = await fetch(
`${process.env.REACT_APP_API_URL}/tournaments?verify=${isSubmissionVerified}`,
{
method: 'POST',
headers: {
Expand All @@ -218,32 +227,26 @@ export async function saveTournamentMatches(
credentials: 'include',
body: JSON.stringify(data),
}
)
.then((response) => {
if (response.status !== 200) {
throw new Error({
issues: [
{
path: ['serverError'],
message: response.body,
},
],
});
}
);

return {
status: 'success',
};
})
.then((data) => {
console.log(data);
})
.catch((error) => {
console.log(JSON.parse(error.message));
});
if (!tournamentSubmit?.ok) {
const errorMessage = await tournamentSubmit.text();

return {
error: {
status: tournamentSubmit.status,
text: tournamentSubmit.statusText,
message: errorMessage,
},
};
}

return {
status: 'success',
success: {
status: tournamentSubmit.status,
text: tournamentSubmit.statusText,
message: 'Tournament submitted successfully',
},
};
} catch (error) {
let errors = {};
Expand Down Expand Up @@ -292,7 +295,7 @@ export async function applyLeaderboardFilters(params: {}) {
let string = '';

params[key].forEach((value, index) => {
string += `${value}${index === 0 ? `&${key}=` : ''}`;
string += `${value}${index < params[key].length - 1 ? `&${key}=` : ''}`;
});

return (urlStringObject[key] = string);
Expand All @@ -312,8 +315,7 @@ export async function fetchLeaderboard(params: {}) {

/* MISSING MODE, PLAYERID */

const { type, page, rank, rating, matches, winrate, inclTier, exclTier } =
params;
const { type, page, rank, rating, matches, winrate, tiers } = params;

const tierFilters = {
bronze: 'bronze',
Expand Down Expand Up @@ -367,16 +369,10 @@ export async function fetchLeaderboard(params: {}) {
.sort(compareNumbers))
: undefined;

inclTier
? Array.isArray(inclTier)
? (paramsToProcess.inclTier = inclTier)
: (paramsToProcess.inclTier = Array(inclTier))
: undefined;

exclTier
? Array.isArray(exclTier)
? (paramsToProcess.exclTier = exclTier)
: (paramsToProcess.exclTier = Array(exclTier))
tiers
? Array.isArray(tiers)
? (paramsToProcess.tiers = tiers)
: (paramsToProcess.tiers = Array(tiers))
: undefined;

const queryCheck = await LeaderboardsQuerySchema.safeParse({
Expand Down Expand Up @@ -451,19 +447,12 @@ export async function fetchLeaderboard(params: {}) {
}

/* Check included tiers filter */
if (queryCheck.data.inclTier) {
queryCheck.data.inclTier.forEach((tier) => {
if (queryCheck.data.tiers) {
queryCheck.data.tiers.forEach((tier) => {
backendObject[tierFilters[tier]] = true;
});
}

/* Check included tiers filter */
if (queryCheck.data.exclTier) {
queryCheck.data.exclTier.forEach((tier) => {
backendObject[tierFilters[tier]] = false;
});
}

let backendString = new URLSearchParams(backendObject).toString();

let data = await fetch(
Expand Down Expand Up @@ -528,7 +517,7 @@ export async function fetchUserPage(player: string | number) {

let res = await fetch(
`${process.env.REACT_APP_API_URL}/stats/${player}${
session?.userId ? `?comparerId=${session?.userId}` : ''
session?.playerId ? `?comparerId=${session?.playerId}` : ''
}`,
{
headers: {
Expand Down Expand Up @@ -563,7 +552,9 @@ export async function paginationParamsToURL(params: {}) {
let string = `${index !== 0 ? '&' : ''}${key}=`;

params[key].forEach((value, index) => {
string += `${value}${index === 0 ? `&${key}=` : ''}`;
string += `${value}${
index < params[key].length - 1 ? `&${key}=` : ''
}`;
});

return (url += `${string}`);
Expand All @@ -577,3 +568,34 @@ export async function paginationParamsToURL(params: {}) {

return url;
}

export async function fetchSearchData(prevState: any, formData: FormData) {
const session = await getSession(true);

if (!session.id) return redirect('/');

let searchText = formData.get('search');

let searchData = await fetch(
`${process.env.REACT_APP_API_URL}/search?searchKey=${searchText}`,
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': `${process.env.REACT_APP_ORIGIN_URL}`,
Authorization: `Bearer ${session.accessToken}`,
},
}
);

if (!searchData?.ok) {
throw new Error('Error from server on search!');
}

searchData = await searchData.json();

return {
status: 'success',
search: searchData,
};
}
3 changes: 2 additions & 1 deletion app/auth/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ export async function GET(request: Request) {
const refreshToken = searchParams.get('refreshToken');
const accessToken = searchParams.get('accessToken');

// Refresh session if refreshToken is set
if (refreshToken && accessToken) {
return await login({ accessToken, refreshToken });
return await login({ accessToken });
}

if (code) {
Expand Down
47 changes: 47 additions & 0 deletions app/dashboard/error.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
.errorDiv {
position: relative;
min-height: 60dvh;
height: 70dvh;
max-height: 70dvh;
margin: var(--main-padding);
margin-top: 0;
}

.errorDiv .content {
height: 100%;
width: 100%;
position: absolute;
display: flex;
flex-flow: column;
align-items: center;
justify-content: center;
padding: var(--internal-gap);
gap: var(--internal-gap);
z-index: 2;
}

.errorDiv img {
z-index: 1;
}

.errorDiv h1 {
font-size: 4rem;
}

.errorDiv span {
font-size: 3.5rem;
letter-spacing: -2%;
text-align: center;
max-width: 40vw;
}

.errorDiv button {
margin-top: 1.3rem;
padding: 1rem 3rem;
width: fit-content;
font-weight: 500;
cursor: pointer;
border-radius: 0.4rem;
font-size: 1rem;
transition: background-color 0.2s ease-out;
}
57 changes: 57 additions & 0 deletions app/dashboard/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use client';

import backgroundError from '@/public/images/error-background.svg';
import Image from 'next/image';
import { useEffect } from 'react';
import Balancer from 'react-wrap-balancer';
import styles from './error.module.css';

const errors = {
'4': {
title: 'No data',
message: "You don't have any data for the selected ruleset",
reloadBtn: true,
},
'404': {
title: '404',
message: "We don't have that page",
reloadBtn: false,
},
};

export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
useEffect(() => {
// Log the error to an error reporting service
console.error(error);
}, [error]);

let errorContent = !isNaN(error.message)
? errors[error.message]
: errors['404'];

return (
<div className={styles.errorDiv}>
<Image src={backgroundError} alt="Error background" fill />
<div className={styles.content}>
<h1>{errorContent.title}</h1>
<span>{errorContent.message}</span>
{errorContent.reloadBtn && (
<button
onClick={
// Attempt to recover by trying to re-render the segment
() => reset()
}
>
Try again
</button>
)}
</div>
</div>
);
}
Loading

0 comments on commit 6de09fe

Please sign in to comment.