v3 release #75
@ -5,7 +5,6 @@ import { Loader } from "./components/mini/loaders/PageLoader.tsx";
|
||||
import { PageTitle } from "./components/mini/util/PageTitle.tsx";
|
||||
import Chart from "./old/Chart.tsx";
|
||||
import { Home } from "./pages/Home";
|
||||
import Settings from "./old/Settings.tsx";
|
||||
import Alerts from "./old/UiElements/Alerts.tsx";
|
||||
import Buttons from "./old/UiElements/Buttons.tsx";
|
||||
import DefaultLayout from "./layout/DefaultLayout";
|
||||
@ -15,12 +14,17 @@ import { StationLeaderboard } from "./pages/leaderboard/StationsLeaderboard.tsx"
|
||||
import { TrainLogs } from "./pages/logs/TrainLogs.tsx";
|
||||
import { StationLogs } from "./pages/logs/StationLogs.tsx";
|
||||
import { Profile } from "./pages/profile/Profile.tsx";
|
||||
import { Log } from "./pages/log/Log.tsx";
|
||||
|
||||
import "react-toastify/dist/ReactToastify.css";
|
||||
import { ToastContainer } from "react-toastify";
|
||||
import useColorMode from "./hooks/useColorMode.tsx";
|
||||
|
||||
function App()
|
||||
{
|
||||
const [ loading, setLoading ] = useState<boolean>(true);
|
||||
const { pathname } = useLocation();
|
||||
|
||||
const [ theme ] = useColorMode();
|
||||
useEffect(() =>
|
||||
{
|
||||
window.scrollTo(0, 0);
|
||||
@ -34,105 +38,119 @@ function App()
|
||||
return loading ? (
|
||||
<Loader/>
|
||||
) : (
|
||||
<DefaultLayout>
|
||||
<Routes>
|
||||
<Route
|
||||
index
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Home"/>
|
||||
<Home/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/leaderboard/trains"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Train Leaderboard"/>
|
||||
<TrainLeaderboard/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<>
|
||||
<ToastContainer
|
||||
position="bottom-right"
|
||||
autoClose={ 1500 }
|
||||
hideProgressBar={ false }
|
||||
newestOnTop={ false }
|
||||
closeOnClick
|
||||
rtl={ false }
|
||||
pauseOnHover
|
||||
theme={ theme as "light" | "dark" }
|
||||
/>
|
||||
<DefaultLayout>
|
||||
<Routes>
|
||||
<Route
|
||||
index
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Home"/>
|
||||
<Home/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/leaderboard/trains"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Train Leaderboard"/>
|
||||
<TrainLeaderboard/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/logs/trains"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Train logs"/>
|
||||
<TrainLogs/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/logs/trains"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Train logs"/>
|
||||
<TrainLogs/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/logs/stations"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Station logs"/>
|
||||
<StationLogs/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/logs/stations"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Station logs"/>
|
||||
<StationLogs/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/leaderboard/stations"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Stations Leaderboard"/>
|
||||
<StationLeaderboard/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/leaderboard/stations"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Stations Leaderboard"/>
|
||||
<StationLeaderboard/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/profile/:id"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Stations Leaderboard"/>
|
||||
<Profile/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/profile/:id"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | User Profile"/>
|
||||
{/* page title is modified after API response */ }
|
||||
<Profile/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/settings"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="Settings | TailAdmin - Tailwind CSS Admin Dashboard Template"/>
|
||||
<Settings/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/chart"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="Basic Chart | TailAdmin - Tailwind CSS Admin Dashboard Template"/>
|
||||
<Chart/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/ui/alerts"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="Alerts | TailAdmin - Tailwind CSS Admin Dashboard Template"/>
|
||||
<Alerts/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/ui/buttons"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="Buttons | TailAdmin - Tailwind CSS Admin Dashboard Template"/>
|
||||
<Buttons/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
</DefaultLayout>
|
||||
<Route
|
||||
path="/log/:id"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Log"/>
|
||||
{/* page title is modified after API response */ }
|
||||
<Log/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/chart"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="Basic Chart | TailAdmin - Tailwind CSS Admin Dashboard Template"/>
|
||||
<Chart/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/ui/alerts"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="Alerts | TailAdmin - Tailwind CSS Admin Dashboard Template"/>
|
||||
<Alerts/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/ui/buttons"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="Buttons | TailAdmin - Tailwind CSS Admin Dashboard Template"/>
|
||||
<Buttons/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
</DefaultLayout>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -18,11 +18,11 @@ export const LoadError = () =>
|
||||
</div>
|
||||
<div className="w-full">
|
||||
<h5 className="mb-3 font-semibold text-[#B45454]">
|
||||
{ t("contentloader.error.header") }
|
||||
{ t("content_loader.error.header") }
|
||||
</h5>
|
||||
<ul>
|
||||
<li className="leading-relaxed text-[#CD5D5D]">
|
||||
{ t("contentloader.error.description") }
|
||||
{ t("content_loader.error.description") }
|
||||
</li>
|
||||
<li className="leading-relaxed text-[#CD5D5D]">
|
||||
<div className="pt-4">
|
||||
@ -30,12 +30,12 @@ export const LoadError = () =>
|
||||
<div className="mb-7.5 flex flex-wrap gap-4">
|
||||
<Link
|
||||
className="inline-flex items-center justify-center rounded-md bg-primary py-2 px-8 text-center font-medium text-white hover:bg-opacity-70 lg:px-6 xl:px-8"
|
||||
to="https://git.alekswilc.dev/simrail/simrail.alekswilc.dev/issues/new">{ t("contentloader.error.report") }</Link>
|
||||
to="https://git.alekswilc.dev/simrail/simrail.alekswilc.dev/issues/new">{ t("content_loader.error.report") }</Link>
|
||||
|
||||
<Link
|
||||
className="inline-flex items-center justify-center rounded-md bg-primary py-2 px-8 text-center font-medium text-white hover:bg-opacity-70 lg:px-6 xl:px-8"
|
||||
to="#"
|
||||
onClick={ () => window.location.reload() }>{ t("contentloader.error.refresh") }</Link>
|
||||
onClick={ () => window.location.reload() }>{ t("content_loader.error.refresh") }</Link>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -13,8 +13,8 @@ export const StationTable = ({ stations, error }: { stations: TLeaderboardRecord
|
||||
return (
|
||||
<>
|
||||
|
||||
{ error === 2 && <WarningAlert title={ t("contentloader.notfound.header") }
|
||||
description={ t("contentloader.notfound.description") }/> }
|
||||
{ error === 2 && <WarningAlert title={ t("content_loader.notfound.header") }
|
||||
description={ t("content_loader.notfound.description") }/> }
|
||||
{ error === 0 && <ContentLoader/> }
|
||||
{ error === 1 && <div
|
||||
className="rounded-sm border border-stroke bg-white px-5 pt-6 pb-2.5 shadow-default dark:border-strokedark dark:bg-boxdark sm:px-7.5 xl:pb-1">
|
||||
|
@ -11,8 +11,8 @@ export const TrainTable = ({ trains, error }: { trains: TLeaderboardRecord[], er
|
||||
|
||||
return (
|
||||
<>
|
||||
{ error === 2 && <WarningAlert title={ t("contentloader.notfound.header") }
|
||||
description={ t("contentloader.notfound.description") }/> }
|
||||
{ error === 2 && <WarningAlert title={ t("content_loader.notfound.header") }
|
||||
description={ t("content_loader.notfound.description") }/> }
|
||||
{ error === 0 && <ContentLoader/> }
|
||||
{ error === 1 && <div
|
||||
className="rounded-sm border border-stroke bg-white px-5 pt-6 pb-2.5 shadow-default dark:border-strokedark dark:bg-boxdark sm:px-7.5 xl:pb-1">
|
||||
|
89
packages/frontend/src/components/pages/log/StationLog.tsx
Normal file
89
packages/frontend/src/components/pages/log/StationLog.tsx
Normal file
@ -0,0 +1,89 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { TLogStationData } from "../../../types/log.ts";
|
||||
import dayjs from "dayjs";
|
||||
import { toast } from "react-toastify";
|
||||
|
||||
export const StationLog = ({ data }: { data: TLogStationData }) =>
|
||||
{
|
||||
const copyLink = () =>
|
||||
{
|
||||
void navigator.clipboard.writeText(location.href);
|
||||
toast.success("Skopiowano link do schowka!");
|
||||
};
|
||||
|
||||
const report = () =>
|
||||
{
|
||||
toast.info("Do schowka skopiowano dane wyjścia z posterunku, możesz ich użyć do wysłania na kanale #multiplayer-help-requests na oficjalnym serwerze Discord gry simrail.", {
|
||||
autoClose: 5000,
|
||||
});
|
||||
void navigator.clipboard.writeText(`;user: \`${ data.userUsername }\`\n;steam: \`${ data.userSteamId }\`\n;left: <t:${ data.leftDate }>${ data.joinedDate ? `\n;joined: <t:${ data.joinedDate }>` : "" }\n;station: \`${ data.stationName }\`\n;link: ${ location.href }\n\n`);
|
||||
};
|
||||
|
||||
const { t } = useTranslation();
|
||||
return <div
|
||||
className="overflow-hidden rounded-sm border border-stroke bg-white shadow-default dark:border-strokedark dark:bg-boxdark">
|
||||
<div className="px-4 pt-6 text-center lg:pb-8 xl:pb-11.5">
|
||||
<div
|
||||
className="mx-auto w-full max-w-30 rounded-full bg-white/20 p-1 backdrop-blur sm:h-44 sm:max-w-44 sm:p-3">
|
||||
<div className="relative drop-shadow-2">
|
||||
<img className="rounded-full" src={ data.userAvatar } alt="profile"/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<h3 className="mb-1.5 text-2xl font-semibold text-black dark:text-white">
|
||||
{ data.userUsername }
|
||||
</h3>
|
||||
|
||||
{/*<div*/ }
|
||||
{/* className="mx-auto mt-4.5 mb-5.5 grid max-w-94 grid-cols-2 rounded-md border border-stroke py-2.5 shadow-1 dark:border-strokedark dark:bg-[#37404F]">*/ }
|
||||
{/* <div*/ }
|
||||
{/* className="flex flex-col items-center justify-center gap-1 border-r border-stroke px-4 dark:border-strokedark xsm:flex-row">*/ }
|
||||
{/* <span className="font-semibold text-black dark:text-white">*/ }
|
||||
{/* { Math.floor(data.player.trainDistance / 1000) }km*/ }
|
||||
{/* </span>*/ }
|
||||
{/* <span className="text-sm text-wrap">{ t("profile.stats.distance") }</span>*/ }
|
||||
{/* </div>*/ }
|
||||
{/* <div*/ }
|
||||
{/* className="flex flex-col items-center justify-center gap-1 border-r border-stroke px-4 dark:border-strokedark xsm:flex-row">*/ }
|
||||
{/* <span className="font-semibold text-black dark:text-white">*/ }
|
||||
{/* { Math.floor(data.player.dispatcherTime / 3600000) }h*/ }
|
||||
{/* </span>*/ }
|
||||
{/* <span className="text-sm text-wrap">{ t("profile.stats.time") }</span>*/ }
|
||||
{/* </div>*/ }
|
||||
{/*</div>*/ }
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white px-5 pt-6 pb-5 shadow-default dark:bg-boxdark sm:px-7.5">
|
||||
<div className="flex flex-col sm:flex-row sm:flex-wrap sm:justify-end">
|
||||
<div className="flex flex-col">
|
||||
<h1 className="text-xl text-black dark:text-white pb-5">{ t("log.station.header") }</h1>
|
||||
<p>{ t("log.station.server", { server: data.server.toUpperCase() }) }</p>
|
||||
<p>{ t("log.station.station", { name: data.stationName, short: data.stationShort }) }</p>
|
||||
|
||||
{ data.joinedDate &&
|
||||
<p>{ t("log.station.joined", { date: dayjs(data.joinedDate).format("DD/MM/YYYY HH:mm") }) }</p> }
|
||||
<p>{ t("log.station.left", { date: dayjs(data.leftDate).format("DD/MM/YYYY HH:mm") }) }</p>
|
||||
{ data.joinedDate &&
|
||||
<p>{ t("log.station.spent", { date: dayjs.duration(data.leftDate - data.joinedDate).format("H[h] m[m]") }) }</p> }
|
||||
</div>
|
||||
<div className="flex flex-col gap-5 mt-5 sm:mt-0 sm:ml-auto">
|
||||
<a
|
||||
onClick={ report }
|
||||
className="cursor-pointer inline-flex items-center justify-center rounded-md bg-meta-7 py-4 px-10 text-center font-medium text-white hover:bg-opacity-90 lg:px-8 xl:px-10"
|
||||
>
|
||||
Zgłoś
|
||||
</a>
|
||||
|
||||
<a
|
||||
onClick={ copyLink }
|
||||
className="cursor-pointer inline-flex items-center justify-center rounded-md bg-primary py-4 px-10 text-center font-medium text-white hover:bg-opacity-90 lg:px-8 xl:px-10"
|
||||
>
|
||||
|
||||
Kopiuj link
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
};
|
@ -15,8 +15,8 @@ export const StationTable = ({ stations, error }: {
|
||||
|
||||
return (
|
||||
<>
|
||||
{ error === 2 && <WarningAlert title={ t("contentloader.notfound.header") }
|
||||
description={ t("contentloader.notfound.description") }/> }
|
||||
{ error === 2 && <WarningAlert title={ t("content_loader.notfound.header") }
|
||||
description={ t("content_loader.notfound.description") }/> }
|
||||
{ error === 0 && <ContentLoader/> }
|
||||
|
||||
{ error === 1 && <div
|
||||
|
@ -15,8 +15,8 @@ export const TrainTable = ({ trains, error }: {
|
||||
|
||||
return (
|
||||
<>
|
||||
{ error === 2 && <WarningAlert title={ t("contentloader.notfound.header") }
|
||||
description={ t("contentloader.notfound.description") }/> }
|
||||
{ error === 2 && <WarningAlert title={ t("content_loader.notfound.header") }
|
||||
description={ t("content_loader.notfound.description") }/> }
|
||||
{ error === 0 && <ContentLoader/> }
|
||||
{ error === 1 && <div
|
||||
className="rounded-sm border border-stroke bg-white px-5 pt-6 pb-2.5 shadow-default dark:border-strokedark dark:bg-boxdark sm:px-7.5 xl:pb-1">
|
||||
|
@ -3,7 +3,7 @@ import useLocalStorage from "./useLocalStorage";
|
||||
|
||||
const useColorMode = () =>
|
||||
{
|
||||
const [ colorMode, setColorMode ] = useLocalStorage("color-theme", "light");
|
||||
const [ colorMode, setColorMode ] = useLocalStorage<"light" | "dark">("color-theme", "light");
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
|
@ -48,10 +48,10 @@
|
||||
"search": "Wpisz, aby wyszukać",
|
||||
"station": "Stacja"
|
||||
},
|
||||
"contentloader": {
|
||||
"content_loader": {
|
||||
"error": {
|
||||
"header": "Błąd ładowania strony",
|
||||
"description": "Sprawdź swoje połączenie z internetem i odśwież strone",
|
||||
"description": "Sprawdź swoje połączenie z internetem i odśwież stronę",
|
||||
"report": "Zgłoś błąd",
|
||||
"refresh": "Odśwież"
|
||||
},
|
||||
@ -83,9 +83,27 @@
|
||||
"description": "Profil gracza nie został znaleziony lub posiada on prywatny profil steam."
|
||||
},
|
||||
"blacklist": {
|
||||
"title": "Nie można wyświetlic profilu",
|
||||
"title": "Nie można wyświetlić profilu",
|
||||
"description": "Profil tego gracza został zablokowany."
|
||||
}
|
||||
}
|
||||
},
|
||||
"log": {
|
||||
"errors": {
|
||||
"title": "Nie znaleziono rekordu",
|
||||
"description": "Ten rekord nie został znaleziony."
|
||||
},
|
||||
"blacklist": {
|
||||
"title": "Nie można wyświetlić rekordu",
|
||||
"description": "Rekord został zablokowany."
|
||||
},
|
||||
"station": {
|
||||
"header": "Wyjście z posterunku",
|
||||
"server": "Serwer: {{server}}",
|
||||
"station": "Stacja: {{name}} - {{short}}",
|
||||
"joined": "Data wejścia: {{date}}",
|
||||
"left": "Data wyjścia: {{date}}",
|
||||
"spent": "Spędzony czas: {{date}}"
|
||||
}
|
||||
}
|
||||
}
|
@ -81,7 +81,8 @@ export const Home: React.FC = () =>
|
||||
i18nKey={ t("home.footer.thanks") }
|
||||
components={ {
|
||||
bahu: <Link className="color-orchid" to={ "https://bahu.pro/" }/>,
|
||||
simrailelite: <Link className="color-orchid" to={ "https://bahu.pro/" }/>,
|
||||
simrailelite: <Link className="color-orchid"
|
||||
to={ "https://discord.gg/yDhy3pDrVr" }/>,
|
||||
} }
|
||||
/></p>
|
||||
<p>{ t("home.footer.license") } <Link className="color-orchid"
|
||||
|
@ -5,6 +5,7 @@ import { ContentLoader } from "../../components/mini/loaders/ContentLoader.tsx";
|
||||
import { WarningAlert } from "../../components/mini/alerts/Warning.tsx";
|
||||
import { ProfileCard } from "../../components/pages/profile/Profile.tsx";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { PageTitle } from "../../components/mini/util/PageTitle.tsx";
|
||||
|
||||
export const Profile = () =>
|
||||
{
|
||||
@ -29,7 +30,6 @@ export const Profile = () =>
|
||||
case 200:
|
||||
setError(1);
|
||||
setData(data.data);
|
||||
console.log(data.data.steam);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@ -42,12 +42,15 @@ export const Profile = () =>
|
||||
{/* LOADING */ }
|
||||
{ error === 0 && <ContentLoader/> }
|
||||
{/* NOT FOUND */ }
|
||||
{ error === 2 && <PageTitle title={ `simrail.alekswilc.dev | Profile not found` }/> }
|
||||
{ error === 2 && <WarningAlert title={ t("profile.errors.notfound.title") }
|
||||
description={ t("profile.errors.notfound.description") }/> }
|
||||
{/* BLACKLISTED PROFILE */ }
|
||||
{ error === 3 && <PageTitle title={ `simrail.alekswilc.dev | Blacklisted profile` }/> }
|
||||
{ error === 3 && <WarningAlert title={ t("profile.errors.blacklist.title") }
|
||||
description={ t("profile.errors.blacklist.description") }/> }
|
||||
{/* SUCCESS */ }
|
||||
{ error === 1 && <PageTitle title={ `simrail.alekswilc.dev | ${ data.steam.personname }'s profile` }/> }
|
||||
{ error === 1 && <ProfileCard data={ data }/> }
|
||||
</>
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user