├── .github └── FUNDING.yml ├── README.md ├── next-env.d.ts ├── public ├── favicon.ico ├── logo.svg ├── logo_white.svg └── logo-gr.svg ├── src ├── components │ ├── Head.tsx │ ├── CategoryFlagsTable.tsx │ ├── Footer.tsx │ ├── CommandsTable.tsx │ ├── ServersList.tsx │ ├── Pagination.tsx │ ├── AppNavbar.tsx │ └── ClusterModal.tsx ├── hooks │ └── use-websocket.ts ├── pages │ ├── about.tsx │ ├── _document.tsx │ ├── _app.tsx │ ├── index.tsx │ ├── commands.tsx │ ├── discover.tsx │ └── stats.tsx ├── types.ts └── style.css ├── lib ├── ws │ ├── message.ts │ ├── message-util.ts │ ├── event-emitter.ts │ └── event-handler.ts └── interfaces │ └── aether.ts ├── .gitignore ├── tsconfig.json ├── package.json ├── LICENSE └── yarn.lock /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: GamingGeek 2 | patreon: FireBot 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fire-Website 2 | Source Code of [Fire Website](https://fire.gaminggeek.dev) 3 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FireDiscordBot/old-website/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/components/Head.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import NextHead from "next/head"; 3 | 4 | interface Props { 5 | title: string; 6 | } 7 | 8 | const Head = ({ title }: Props) => ( 9 | 10 | {title} 11 | 12 | ); 13 | 14 | export default Head; 15 | -------------------------------------------------------------------------------- /lib/ws/message.ts: -------------------------------------------------------------------------------- 1 | import { WebsiteEvents } from "../interfaces/aether" 2 | 3 | export class Message { 4 | type: WebsiteEvents 5 | data: unknown 6 | 7 | constructor(type: WebsiteEvents, data: unknown) { 8 | this.type = type 9 | this.data = data 10 | } 11 | 12 | toJSON() { 13 | return { 14 | op: this.type, 15 | d: this.data, 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | .env* 21 | /.idea 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | package-lock.json 27 | 28 | .vscode 29 | .vercel/README.txt 30 | .vercel/project.json 31 | -------------------------------------------------------------------------------- /lib/ws/message-util.ts: -------------------------------------------------------------------------------- 1 | import { deflateSync, inflateSync } from "zlib" 2 | import { Payload } from "../interfaces/aether" 3 | import { Message } from "./message" 4 | 5 | export class MessageUtil { 6 | static encode(message: Message) { 7 | const deflated = deflateSync(JSON.stringify(message), { level: 5 }) 8 | return deflated.toString("base64") 9 | } 10 | 11 | static decode(message: string) { 12 | const inflated = inflateSync(Buffer.from(message, "base64"), { 13 | level: 5, 14 | })?.toString() 15 | if (!inflated) return null 16 | else return JSON.parse(inflated) as Payload 17 | } 18 | } -------------------------------------------------------------------------------- /lib/ws/event-emitter.ts: -------------------------------------------------------------------------------- 1 | import { FireStats } from "../interfaces/aether"; 2 | import { EventEmitter } from "events"; 3 | 4 | interface EmitterEvents { 5 | REALTIME_STATS: (stats: FireStats) => void; 6 | SUBSCRIBE: (route: string, extra?: unknown) => void; 7 | HELLO: (hello: { interval: number }) => void; 8 | } 9 | 10 | export declare interface Emitter { 11 | on(event: T, listener: EmitterEvents[T]): this; 12 | emit( 13 | event: T, 14 | ...args: Parameters 15 | ): boolean; 16 | } 17 | 18 | export class Emitter extends EventEmitter {} 19 | -------------------------------------------------------------------------------- /src/hooks/use-websocket.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from "events"; 2 | 3 | import * as React from "react"; 4 | 5 | import { EventHandler } from "../../lib/ws/event-handler"; 6 | 7 | const useWebsocket = (url: string, emitter: EventEmitter) => { 8 | const [handler, setHandler] = React.useState(null); 9 | React.useEffect(() => { 10 | const ws = new WebSocket(url); 11 | const handler = new EventHandler(emitter).setWebsocket(ws); 12 | setHandler(handler); 13 | 14 | return () => ws.close(); 15 | }, [emitter, url]); 16 | 17 | return [handler]; 18 | }; 19 | 20 | export default useWebsocket; 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "strict": false, 12 | "forceConsistentCasingInFileNames": true, 13 | "noEmit": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "jsx": "preserve" 20 | }, 21 | "include": [ 22 | "next-env.d.ts", 23 | "**/*.ts", 24 | "**/*.tsx" 25 | ], 26 | "exclude": [ 27 | "node_modules" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /src/components/CategoryFlagsTable.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Table from "react-bootstrap/Table"; 3 | 4 | import type { CategoryFlag } from "../types"; 5 | 6 | interface FlagsTableProps { 7 | prefix: string; 8 | flags: CategoryFlag[]; 9 | } 10 | 11 | const CategoryFlagsTable = ({ prefix, flags }: FlagsTableProps) => ( 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | {flags.map((flag) => ( 20 | 21 | 22 | 23 | 24 | 25 | ))} 26 | 27 |
NameDescriptionUsage
{flag.name}{flag.description}{flag.usage.replace("{prefix}", prefix)}
28 | ); 29 | 30 | export default CategoryFlagsTable; 31 | -------------------------------------------------------------------------------- /src/components/Footer.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Footer = () => ( 4 | 29 | ); 30 | 31 | export default Footer; 32 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fire", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev -p 3002", 7 | "build": "next build", 8 | "start": "next start -p 3001", 9 | "export": "next export" 10 | }, 11 | "dependencies": { 12 | "@appbaseio/reactivesearch": "^3.12.7", 13 | "bootstrap": "^4.5.3", 14 | "cookie-parser": "^1.4.5", 15 | "cross-env": "^7.0.2", 16 | "express": "^4.17.1", 17 | "next": "^11.1.1", 18 | "next-cookies": "^2.0.3", 19 | "react": "17.0.1", 20 | "react-bootstrap": "^1.4.0", 21 | "react-dom": "17.0.1" 22 | }, 23 | "devDependencies": { 24 | "@types/node": "^14.14.5", 25 | "@types/react": "^16.9.53", 26 | "prop-types": "^15.7.2", 27 | "typescript": "^4.0.5" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/components/CommandsTable.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Table from "react-bootstrap/Table"; 3 | 4 | import type { Command } from "../types"; 5 | 6 | interface CommandsTableProps { 7 | prefix: string; 8 | commands: Command[]; 9 | } 10 | 11 | const CommandsTable = ({ prefix, commands }: CommandsTableProps) => ( 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | {commands.map((command) => ( 21 | 22 | 23 | 24 | 25 | 26 | 27 | ))} 28 | 29 |
NameDescriptionUsageAliases
{command.name}{command.description}{command.usage.replace("{prefix}", prefix)}{command.aliases}
30 | ); 31 | 32 | export default CommandsTable; 33 | -------------------------------------------------------------------------------- /src/pages/about.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import Head from "../components/Head"; 4 | import Container from "react-bootstrap/Container"; 5 | import Row from "react-bootstrap/Row"; 6 | import Col from "react-bootstrap/Col"; 7 | 8 | const About = () => ( 9 | <> 10 | 11 |
12 | 13 | 14 | 15 |
16 | Fire is made by Geek#8405. 17 |
18 | Website is made by Nystrex#6606{" "} 19 | and bruno#1111 20 |
21 | © 2021 22 |
23 | 24 |
25 |
26 |
27 | 28 | ); 29 | 30 | export default About; 31 | -------------------------------------------------------------------------------- /src/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import Document, { Html, Head, Main, NextScript } from "next/document"; 2 | import React from "react"; 3 | 4 | class MyDocument extends Document { 5 | render() { 6 | return ( 7 | 8 | 9 | 10 | 14 | 15 | 16 |
17 | 18 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | ); 31 | } 32 | } 33 | 34 | export default MyDocument; 35 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | export interface Server { 2 | name: string; 3 | id: string; 4 | icon: string; 5 | splash: string; 6 | vanity: string; 7 | members: number; 8 | key?: number; 9 | } 10 | 11 | export interface Command { 12 | name: string; 13 | description: string; 14 | usage: string; 15 | aliases: string; 16 | category?: string; 17 | } 18 | 19 | export interface CategoryFlag { 20 | name: string; 21 | description: string; 22 | usage: string; 23 | } 24 | 25 | export interface Category { 26 | id: number; 27 | name: string; 28 | commands: Command[]; 29 | flags?: CategoryFlag[]; 30 | Note?: string; 31 | } 32 | 33 | export interface Cluster { 34 | id: number; 35 | name: string; 36 | env: string; 37 | uptime: string; 38 | cpu: number; 39 | ram: string; 40 | version: string; 41 | guilds: number; 42 | unavailableGuilds: number; 43 | users: number; 44 | commands: number; 45 | events: number; 46 | shards: Shard[]; 47 | error?: string; 48 | reason?: string; 49 | code?: string; 50 | } 51 | 52 | export interface Shard { 53 | id: number; 54 | wsPing: number; 55 | guilds: number; 56 | unavailableGuilds: number; 57 | users: number; 58 | status: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8; 59 | } 60 | 61 | export interface Stats { 62 | cpu: number; 63 | ram: string; 64 | totalRam: string; 65 | clusterCount: number; 66 | shardCount: number; 67 | guilds: number; 68 | users: number; 69 | clusters: Cluster[]; 70 | } 71 | -------------------------------------------------------------------------------- /src/components/ServersList.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Col from "react-bootstrap/Col"; 3 | import Card from "react-bootstrap/Card"; 4 | import Media from "react-bootstrap/Media"; 5 | import type { Server } from "../types"; 6 | 7 | interface ServerDisplayProps { 8 | server: Server; 9 | } 10 | 11 | const ServerDisplay = ({ server }: ServerDisplayProps) => ( 12 | 13 | 14 | 15 | 16 | 17 | 18 | {server.name} 19 |
20 |
21 | {server.members.toLocaleString()} Members 22 |
23 |
24 |
25 |
26 | 27 |
28 |
29 | ); 30 | 31 | interface ServersListProps { 32 | servers: Server[]; 33 | } 34 | 35 | const ServersList = ({ servers }: ServersListProps) => { 36 | return ( 37 | <> 38 | {servers.map((server) => ( 39 | 40 | 41 | 42 | ))} 43 | 44 | ); 45 | }; 46 | 47 | export default ServersList; 48 | -------------------------------------------------------------------------------- /src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import type { AppProps } from "next/app"; 3 | 4 | import Footer from "../components/Footer"; 5 | import AppNavbar from "../components/AppNavbar"; 6 | 7 | import "bootstrap/dist/css/bootstrap.css"; 8 | import "../style.css"; 9 | 10 | import { EventHandler } from "../../lib/ws/event-handler"; 11 | import { Emitter } from "../../lib/ws/event-emitter"; 12 | import useWebsocket from "../hooks/use-websocket"; 13 | 14 | // export const emitter = new Emitter(); 15 | 16 | const MyApp = ({ Component, pageProps }: AppProps) => { 17 | // const [handler] = useWebsocket( 18 | // "wss://aether-ws.gaminggeek.dev/website?encoding=zlib", 19 | // emitter 20 | // ); 21 | // if (handler) { 22 | // initHandler(handler); 23 | // } 24 | 25 | return ( 26 | <> 27 | 28 | 29 |