v3 release #75
@ -68,14 +68,14 @@ export class LeaderboardRoute {
|
||||
const records = await MProfile.aggregate(filter)
|
||||
.sort({ dispatcherTime: -1 })
|
||||
.limit(10)
|
||||
res.render('leaderboard/index.ejs', {
|
||||
records,
|
||||
dayjs,
|
||||
msToTime,
|
||||
type: 'station',
|
||||
q: req.query.q,
|
||||
...GitUtil.getData(),
|
||||
});
|
||||
|
||||
|
||||
res.json(
|
||||
new SuccessResponseBuilder<{ records: Omit<IProfile, '_id' | '__v'>[] }>()
|
||||
.setCode(200)
|
||||
.setData({ records: records.map(x => removeProperties<Omit<IProfile, '_id' | '__v'>>(x, ['_id', '__v'])) })
|
||||
.toJSON()
|
||||
);
|
||||
})
|
||||
|
||||
return app;
|
||||
|
@ -10,6 +10,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"apexcharts": "^3.41.0",
|
||||
"dayjs": "^1.11.13",
|
||||
"flatpickr": "^4.6.13",
|
||||
"headlessui": "^0.0.0",
|
||||
"i18next": "^23.15.1",
|
||||
|
@ -12,7 +12,8 @@ import Alerts from './pages/UiElements/Alerts';
|
||||
import Buttons from './pages/UiElements/Buttons';
|
||||
import DefaultLayout from './layout/DefaultLayout';
|
||||
import "./i18n";
|
||||
import { TrainLogs } from './pages/Logs.tsx';
|
||||
import { TrainLeaderboard } from './pages/leaderboard/TrainLeaderboard.tsx';
|
||||
import { StationLeaderboard } from './pages/leaderboard/StationsLeaderboard.tsx';
|
||||
|
||||
|
||||
function App() {
|
||||
@ -42,11 +43,20 @@ function App() {
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/logs/trains"
|
||||
path="/leaderboard/trains"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Train Logs" />
|
||||
<TrainLogs />
|
||||
<PageTitle title="simrail.alekswilc.dev | Train Leaderboard" />
|
||||
<TrainLeaderboard />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/leaderboard/stations"
|
||||
element={
|
||||
<>
|
||||
<PageTitle title="simrail.alekswilc.dev | Stations Leaderboard" />
|
||||
<StationLeaderboard />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
@ -1,127 +0,0 @@
|
||||
import { BRAND } from '../../types/brand';
|
||||
import BrandOne from '../../images/brand/brand-01.svg';
|
||||
import BrandTwo from '../../images/brand/brand-02.svg';
|
||||
import BrandThree from '../../images/brand/brand-03.svg';
|
||||
import BrandFour from '../../images/brand/brand-04.svg';
|
||||
import BrandFive from '../../images/brand/brand-05.svg';
|
||||
|
||||
const brandData: BRAND[] = [
|
||||
{
|
||||
logo: BrandOne,
|
||||
name: 'Google',
|
||||
visitors: 3.5,
|
||||
revenues: '5,768',
|
||||
sales: 590,
|
||||
conversion: 4.8,
|
||||
},
|
||||
{
|
||||
logo: BrandTwo,
|
||||
name: 'Twitter',
|
||||
visitors: 2.2,
|
||||
revenues: '4,635',
|
||||
sales: 467,
|
||||
conversion: 4.3,
|
||||
},
|
||||
{
|
||||
logo: BrandThree,
|
||||
name: 'Github',
|
||||
visitors: 2.1,
|
||||
revenues: '4,290',
|
||||
sales: 420,
|
||||
conversion: 3.7,
|
||||
},
|
||||
{
|
||||
logo: BrandFour,
|
||||
name: 'Vimeo',
|
||||
visitors: 1.5,
|
||||
revenues: '3,580',
|
||||
sales: 389,
|
||||
conversion: 2.5,
|
||||
},
|
||||
{
|
||||
logo: BrandFive,
|
||||
name: 'Facebook',
|
||||
visitors: 3.5,
|
||||
revenues: '6,768',
|
||||
sales: 390,
|
||||
conversion: 4.2,
|
||||
},
|
||||
];
|
||||
|
||||
const TableOne = () => {
|
||||
return (
|
||||
<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">
|
||||
<h4 className="mb-6 text-xl font-semibold text-black dark:text-white">
|
||||
Top Channels
|
||||
</h4>
|
||||
|
||||
<div className="flex flex-col">
|
||||
<div className="grid grid-cols-3 rounded-sm bg-gray-2 dark:bg-meta-4 sm:grid-cols-5">
|
||||
<div className="p-2.5 xl:p-5">
|
||||
<h5 className="text-sm font-medium uppercase xsm:text-base">
|
||||
Source
|
||||
</h5>
|
||||
</div>
|
||||
<div className="p-2.5 text-center xl:p-5">
|
||||
<h5 className="text-sm font-medium uppercase xsm:text-base">
|
||||
Visitors
|
||||
</h5>
|
||||
</div>
|
||||
<div className="p-2.5 text-center xl:p-5">
|
||||
<h5 className="text-sm font-medium uppercase xsm:text-base">
|
||||
Revenues
|
||||
</h5>
|
||||
</div>
|
||||
<div className="hidden p-2.5 text-center sm:block xl:p-5">
|
||||
<h5 className="text-sm font-medium uppercase xsm:text-base">
|
||||
Sales
|
||||
</h5>
|
||||
</div>
|
||||
<div className="hidden p-2.5 text-center sm:block xl:p-5">
|
||||
<h5 className="text-sm font-medium uppercase xsm:text-base">
|
||||
Conversion
|
||||
</h5>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{brandData.map((brand, key) => (
|
||||
<div
|
||||
className={`grid grid-cols-3 sm:grid-cols-5 ${
|
||||
key === brandData.length - 1
|
||||
? ''
|
||||
: 'border-b border-stroke dark:border-strokedark'
|
||||
}`}
|
||||
key={key}
|
||||
>
|
||||
<div className="flex items-center gap-3 p-2.5 xl:p-5">
|
||||
<div className="flex-shrink-0">
|
||||
<img src={brand.logo} alt="Brand" />
|
||||
</div>
|
||||
<p className="hidden text-black dark:text-white sm:block">
|
||||
{brand.name}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-center p-2.5 xl:p-5">
|
||||
<p className="text-black dark:text-white">{brand.visitors}K</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-center p-2.5 xl:p-5">
|
||||
<p className="text-meta-3">${brand.revenues}</p>
|
||||
</div>
|
||||
|
||||
<div className="hidden items-center justify-center p-2.5 sm:flex xl:p-5">
|
||||
<p className="text-black dark:text-white">{brand.sales}</p>
|
||||
</div>
|
||||
|
||||
<div className="hidden items-center justify-center p-2.5 sm:flex xl:p-5">
|
||||
<p className="text-meta-5">{brand.conversion}%</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TableOne;
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,14 +1,14 @@
|
||||
import toast from 'react-hot-toast';
|
||||
import dataJSON from '../../public/data.json';
|
||||
|
||||
|
||||
const createToast=(title: string, msg: string, type: number)=>{toast.custom((t) => (
|
||||
//TODO: rewrite
|
||||
const createToast = (title: string, msg: string, type: number) => {
|
||||
toast.custom((t) => (
|
||||
|
||||
<div
|
||||
className={`${
|
||||
t.visible ? 'animate-enter' : 'animate-leave'
|
||||
className={`${t.visible ? 'animate-enter' : 'animate-leave'
|
||||
}
|
||||
max-w-md w-full ${type=='0'?"bg-[#04b20c]":type=='1'?"bg-[#eab90f]":"bg-[#e13f32]"} shadow-lg rounded-lg pointer-events-auto flex ring-1 ring-black ring-opacity-5`}
|
||||
max-w-md w-full ${type === 0 ? "bg-[#04b20c]" : type === 1 ? "bg-[#eab90f]" : "bg-[#e13f32]"} shadow-lg rounded-lg pointer-events-auto flex ring-1 ring-black ring-opacity-5`}
|
||||
>
|
||||
<div className="flex-1 w-0 p-4 ">
|
||||
<div className="flex items-start">
|
||||
@ -50,7 +50,8 @@ const createToast=(title: string, msg: string, type: number)=>{toast.custom((t)
|
||||
|
||||
</div>
|
||||
</div>
|
||||
))};
|
||||
))
|
||||
};
|
||||
// let dataJSON: any;
|
||||
// let headers = new Headers();
|
||||
// headers.append('Access-Control-Allow-Origin', 'http://127.0.0.1:8000');
|
||||
@ -73,8 +74,7 @@ if (alertSettings){
|
||||
const value = isNaN(parseFloat(alertSetting.value)) ? alertSetting.value : parseFloat(alertSetting.value);
|
||||
const para = alertSetting.criterion < 2 ? "delta_" + alertSetting.para : alertSetting.para;
|
||||
if (alertSetting.id == "ALL") {
|
||||
Object.keys(dataJSON).map((id:string)=>
|
||||
{
|
||||
Object.keys(dataJSON).map((id: string) => {
|
||||
const condition = alertSetting.criterion == '0' ? value <= -1 * dataJSON[id][para] :
|
||||
alertSetting.criterion == '1' || alertSetting.criterion == '3' ? value >= dataJSON[id][para] :
|
||||
alertSetting.criterion == '2' ? value <= dataJSON[id][para] :
|
||||
@ -109,4 +109,3 @@ if (alertSettings){
|
||||
}
|
||||
|
||||
export default fireToast;
|
||||
|
@ -27,4 +27,7 @@ i18n
|
||||
defaultNS: "translation",
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
export { i18n };
|
@ -29,5 +29,13 @@
|
||||
"stations": "Stacje",
|
||||
"trains": "Pociągi",
|
||||
"leaderboard": "Tablica wyników"
|
||||
},
|
||||
"leaderboard": {
|
||||
"user": "Użytkownik",
|
||||
"time": "Czas",
|
||||
"distance": "Dystans",
|
||||
"points": "Punkty",
|
||||
"profile": "Otwórz profil",
|
||||
"actions": "Akcje"
|
||||
}
|
||||
}
|
@ -6,6 +6,15 @@ import './css/style.css';
|
||||
import './css/satoshi.css';
|
||||
import 'flatpickr/dist/flatpickr.min.css';
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime.js';
|
||||
import duration from 'dayjs/plugin/duration.js';
|
||||
|
||||
|
||||
dayjs.extend(duration)
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
||||
<React.StrictMode>
|
||||
<Router>
|
||||
|
@ -1,21 +0,0 @@
|
||||
|
||||
import TableOne from '../components/Tables/TableOne';
|
||||
import TableThree from '../components/Tables/TableThree';
|
||||
import TableTwo from '../components/Tables/TableTwo';
|
||||
import { TTrainRecord } from '../types/train.ts';
|
||||
|
||||
|
||||
const trains: TTrainRecord[] = {"success":true,"data":{"records":[{"id":"16b54f4a-0826-4005-b67d-2ab57d74ffeb","steam":"76561199101984415","steamName":"tomsobczak35","trainTime":4841000336,"trainPoints":572048,"trainDistance":8066546,"dispatcherTime":0,"trainStats":{"Pendolino (ED250)":{"distance":8066546,"score":572048,"time":4841000336}}},{"id":"a9050fd0-f3cd-45c9-8087-44948da79b00","steam":"76561198258359953","steamName":"Kashameister.","trainTime":4838762785,"trainPoints":353232,"trainDistance":10274248,"dispatcherTime":0,"trainStats":{"EU07":{"distance":10274248,"score":353232,"time":4838762785}}},{"id":"2a08cadb-bacb-494a-8d09-0ef1870f1057","steam":"76561198200906855","steamName":"Nesto Ash Leo","trainTime":4411743671,"trainPoints":110438,"trainDistance":4412798,"dispatcherTime":0,"trainStats":{"EP08":{"distance":4412798,"score":110438,"time":4411743671}}},{"id":"23de2c57-84da-4845-b901-a40b6b5e1261","steam":"76561199065951587","steamName":"Pablo","trainTime":3021172809,"trainPoints":55277,"trainDistance":429106,"dispatcherTime":250586,"trainStats":{"EN96":{"distance":429106,"score":55277,"time":3021172809}},"dispatcherStats":{"Korytów":{"time":22064},"Olszamowice":{"time":221137},"Dąbrowa Górnicza":{"time":7385}}},{"id":"b44b2b4b-476a-4e52-b612-573d5c5eea78","steam":"76561198356160006","steamName":"Marcion","trainTime":9571588,"dispatcherTime":0,"trainStats":{"Pendolino (ED250)":{"distance":303450,"score":9856,"time":9571588}},"trainDistance":303450,"trainPoints":9856},{"id":"3ee1f655-8329-4c83-96ae-bcf162d31f78","steam":"76561199465955782","steamName":"Bolek","trainTime":14441779,"dispatcherTime":0,"trainStats":{"Pendolino (ED250)":{"distance":402970,"score":9740,"time":14441779}},"trainDistance":402970,"trainPoints":9740},{"id":"c3731119-72b0-47c4-a047-70315e595d01","steam":"76561198048854814","steamName":"Night King_UA","trainTime":9537157,"dispatcherTime":0,"trainStats":{"Pendolino (ED250)":{"distance":302954,"score":9686,"time":9537157}},"trainDistance":302954,"trainPoints":9686},{"id":"a88f7594-844b-47e1-b657-d6c0be2d021a","steam":"76561198886710784","steamName":"LIPTON2315","trainTime":10820008,"dispatcherTime":0,"trainStats":{"EP08":{"distance":240000,"score":0,"time":9860788},"Pendolino (ED250)":{"distance":22693,"score":9320,"time":959220}},"trainDistance":262693,"trainPoints":9320},{"id":"42b5c7f0-3af4-4305-aca7-6462e5bf134b","steam":"76561198067997310","steamName":"Gladicek","trainTime":8042564,"dispatcherTime":0,"trainStats":{"EU07":{"distance":97165,"score":0,"time":4419762},"Traxx (E186)":{"distance":5704,"score":4483,"time":873122},"EN57":{"distance":27186,"score":4696,"time":2262371},"EN96":{"distance":3506,"score":0,"time":487309}},"trainDistance":133561,"trainPoints":9179},{"id":"31a65828-3e87-4123-b8c7-c2604375e5a4","steam":"76561198859961880","steamName":"mpapa","trainTime":15313091,"dispatcherTime":0,"trainStats":{"EP08":{"distance":110491,"score":4463,"time":13036616},"Dragon2 (E6ACTa, E6ACTadb)":{"distance":924,"score":0,"time":321162},"Pendolino (ED250)":{"distance":59999,"score":2750,"time":1955313}},"trainDistance":171414,"trainPoints":7213}]},"code":200}.data.records;
|
||||
|
||||
|
||||
export const TrainLogs = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col gap-10">
|
||||
<TableOne />
|
||||
<TableTwo />
|
||||
<TableThree />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
@ -1,15 +1,15 @@
|
||||
|
||||
import TableOne from '../components/Tables/TableOne';
|
||||
import TableThree from '../components/Tables/TableThree';
|
||||
import TableTwo from '../components/Tables/TableTwo';
|
||||
// import TableOne from '../components/Tables/TableOne';
|
||||
// import TableThree from '../components/Tables/TableThree';
|
||||
// import TableTwo from '../components/Tables/TableTwo';
|
||||
|
||||
const Tables = () => {
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col gap-10">
|
||||
<TableOne />
|
||||
{/* <TableOne />
|
||||
<TableTwo />
|
||||
<TableThree />
|
||||
<TableThree /> */}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
@ -1,31 +0,0 @@
|
||||
export interface TTrainResponse {
|
||||
success: boolean;
|
||||
data: TTrainData;
|
||||
code: number;
|
||||
}
|
||||
|
||||
export interface TTrainData {
|
||||
records: TTrainRecord[];
|
||||
}
|
||||
|
||||
export interface TTrainRecord {
|
||||
id: string;
|
||||
steam: string;
|
||||
steamName: string;
|
||||
trainTime: number;
|
||||
trainPoints: number;
|
||||
trainDistance: number;
|
||||
dispatcherTime: number;
|
||||
trainStats: { [key: string]: TTrainStat };
|
||||
dispatcherStats?: { [key: string]: TDispatcherStat };
|
||||
}
|
||||
|
||||
export interface TDispatcherStat {
|
||||
time: number;
|
||||
}
|
||||
|
||||
export interface TTrainStat {
|
||||
distance: number;
|
||||
score: number;
|
||||
time: number;
|
||||
}
|
@ -1150,7 +1150,7 @@ csstype@^3.0.2:
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
|
||||
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
|
||||
|
||||
dayjs@^1.11.12:
|
||||
dayjs@^1.11.12, dayjs@^1.11.13:
|
||||
version "1.11.13"
|
||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c"
|
||||
integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==
|
||||
|
Loading…
x
Reference in New Issue
Block a user