Skip to content

Commit

Permalink
stickybans in detail
Browse files Browse the repository at this point in the history
  • Loading branch information
harryob committed Apr 25, 2024
1 parent be5be2c commit 13f6cfc
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 128 deletions.
4 changes: 2 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { GlobalContext } from "./types/global";
import { CidLookup } from "./components/cidLookup";
import { RoundData } from "./components/roundData";
import { Dialog } from "./components/dialog";
import { StickybansModal } from "./components/stickybans";
import { Stickybans } from "./components/stickybans";

export default function App(): React.ReactElement {
const [toastMessage, showToastMessage] = useState<string | null>(null);
Expand Down Expand Up @@ -45,7 +45,7 @@ export default function App(): React.ReactElement {
toggle={() => setStickyMenu(false)}
className="w-11/12"
>
<StickybansModal />
<Stickybans />
</Dialog>
)}

Expand Down
10 changes: 7 additions & 3 deletions src/components/cidLookup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import React, {
import { GlobalContext } from "../types/global";
import { ConnectionHistory } from "../types/loginTriplet";
import { TripletList } from "./tripletsList";
import { StickybanMatch } from "./stickybanMatch";

interface CidLookupProps extends PropsWithChildren {
initialCid?: string;
Expand All @@ -17,20 +18,22 @@ export const CidLookup: React.FC<CidLookupProps> = (props: CidLookupProps) => {
const { initialCid } = props;

const [cid, setCid] = useState<string>("");
const [ipData, setCidData] = useState<ConnectionHistory | null>(null);
const [cidData, setCidData] = useState<ConnectionHistory | null>(null);
const [confirmedCid, setConfirmedCid] = useState("");

const [loading, setLoading] = useState(false);

const global = useContext(GlobalContext);

useEffect(() => {
if (initialCid && !ipData) {
if (initialCid && !cidData) {
updateCid(initialCid);
}
});

const updateCid = (override?: string) => {
setLoading(true);
setConfirmedCid(override || cid);
if (override) {
setCid(override);
}
Expand Down Expand Up @@ -73,8 +76,9 @@ export const CidLookup: React.FC<CidLookupProps> = (props: CidLookupProps) => {
></input>
</form>

{cidData && <StickybanMatch cid={confirmedCid} />}
{loading && <div className="text-2xl text-center">Loading...</div>}
{ipData?.triplets && <TripletList triplets={ipData.triplets} />}
{cidData?.triplets && <TripletList triplets={cidData.triplets} />}
</>
);
};
5 changes: 5 additions & 0 deletions src/components/ipLookup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import React, {
import { GlobalContext } from "../types/global";
import { TripletList } from "./tripletsList";
import { ConnectionHistory } from "../types/loginTriplet";
import { StickybanMatch } from "./stickybanMatch";

interface IpLookupProps extends PropsWithChildren {
initialIp?: string;
Expand All @@ -17,6 +18,8 @@ export const IpLookup: React.FC<IpLookupProps> = (props: IpLookupProps) => {
const { initialIp } = props;

const [ip, setIp] = useState<string>("");
const [confirmedIp, setConfirmedIp] = useState("");

const [ipData, setIpData] = useState<ConnectionHistory | null>(null);

const [loading, setLoading] = useState(false);
Expand All @@ -31,6 +34,7 @@ export const IpLookup: React.FC<IpLookupProps> = (props: IpLookupProps) => {

const updateIp = (override?: string) => {
setLoading(true);
setConfirmedIp(override || ip);
if (override) {
setIp(override);
}
Expand Down Expand Up @@ -73,6 +77,7 @@ export const IpLookup: React.FC<IpLookupProps> = (props: IpLookupProps) => {
></input>
</form>

{ipData && <StickybanMatch ip={confirmedIp} />}
{loading && <div className="text-2xl text-center">Loading...</div>}
{ipData?.triplets && <TripletList triplets={ipData.triplets} />}
</>
Expand Down
59 changes: 59 additions & 0 deletions src/components/stickybanMatch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { useEffect, useState } from "react";
import { Stickyban } from "../types/stickyban";
import { Link } from "./link";
import { Dialog } from "./dialog";
import { StickybanModal } from "./stickybanModal";

export const StickybanMatch: React.FC<StickybanMatch> = (
props: StickybanMatch
) => {
const [stickyData, setStickyData] = useState<Stickyban[] | null>(null);
const [open, setOpen] = useState(false);

const { ip, ckey, cid } = props;

const getPath = () => {
if (ip) return `/Stickyban/Ip?ip=${ip}`;
if (ckey) return `/Stickyban/Ckey?ckey=${ckey}`;
if (cid) return `/Stickyban/Cid?cid=${cid}`;
};

const getText = () => {
if (ip) return "IP";
if (ckey) return "CKEY";
if (cid) return "CID";
};

useEffect(() => {
if (!stickyData) {
fetch(`${import.meta.env.VITE_API_PATH}${getPath()}`).then((value) =>
value.json().then((json) => setStickyData(json))
);
}
});

if (!stickyData?.length) return;

return (
<>
<div className="red-alert-bg p-3 mt-3">
<div className="foreground p-3">
<Link onClick={() => setOpen(true)}>
{getText()} has active stickybans.
</Link>
</div>
</div>
{open && (
<Dialog toggle={() => setOpen(false)} open={open}>
<StickybanModal stickybans={stickyData} />
</Dialog>
)}
</>
);
};

type StickybanMatch = {
ip?: string;
ckey?: string;
cid?: string;
};
109 changes: 109 additions & 0 deletions src/components/stickybanModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import React, { useState } from "react";
import {
Stickyban,
StickybansMatchedCid,
StickybansMatchedCkey,
StickybansMatchedIp,
} from "../types/stickyban";
import { Link } from "./link";
import { Dialog } from "./dialog";

type StickybanModalProps = {
stickybans: Stickyban[];
};

export const StickybanModal: React.FC<StickybanModalProps> = (
props: StickybanModalProps
) => {
const { stickybans } = props;

return (
<div className="pt-10">
<div className="overflow-scroll max-h-[800px]">
<table className="w-full">
<tbody>
<tr>
<th>Identifier</th>
<th>Message</th>
<th>Reason</th>
<th>Actions</th>
</tr>
{stickybans.map((stickyban) => (
<StickybanEntry stickyban={stickyban} key={stickyban.id} />
))}
</tbody>
</table>
</div>
</div>
);
};

const StickybanEntry = (props: { stickyban: Stickyban }) => {
const { stickyban } = props;

return (
<tr>
<td className="border p-2">{stickyban.identifier}</td>
<td className="border p-2">{stickyban.message}</td>
<td className="border p-2">{stickyban.reason.trim()}</td>
<td className="border p-2">
<ExpandDetails stickyban={stickyban} />
</td>
</tr>
);
};

const ExpandDetails = (props: { stickyban: Stickyban }) => {
const { stickyban } = props;

const [cids, setCids] = useState<StickybansMatchedCid[] | null>(null);
const [ckeys, setCkeys] = useState<StickybansMatchedCkey[] | null>(null);
const [ips, setIps] = useState<StickybansMatchedIp[] | null>(null);

const [open, setOpen] = useState(false);

const check = () => {
setOpen(true);

fetch(
`${import.meta.env.VITE_API_PATH}/Stickyban/Match/Cid?id=${stickyban.id}`
).then((value) =>
value.json().then((json) => {
setCids(json);
})
);

fetch(
`${import.meta.env.VITE_API_PATH}/Stickyban/Match/Ckey?id=${stickyban.id}`
).then((value) =>
value.json().then((json) => {
setCkeys(json);
})
);

fetch(
`${import.meta.env.VITE_API_PATH}/Stickyban/Match/Ip?id=${stickyban.id}`
).then((value) =>
value.json().then((json) => {
setIps(json);
})
);
};

return (
<>
<Link onClick={() => check()}>Details</Link>
{open && (
<Dialog open={!!cids} toggle={() => setOpen(false)}>
<div className="flex flex-col pt-10">
<div>CIDs: {cids && cids.map((cid) => cid.cid).join(", ")}</div>
<div>
CKEYs: {ckeys && ckeys.map((ckey) => ckey.ckey).join(", ")}
</div>
<div>IPs: {ips && ips.map((ip) => ip.ip).join(", ")}</div>
</div>
</Dialog>
)}
</>
);
};
Loading

0 comments on commit 13f6cfc

Please sign in to comment.