w2l template page styling + animation

This commit is contained in:
BFlat committed 2022-07-23 14:17:15 +01:00
1 parent 788fea1036
commit 549e440265
4 files changed
+429 -341

No files matched your search

@@ -10,6 +10,8 @@ import {
} from "../../../api/w2l/GetW2lTemplate";
import { GetW2lTemplateUseCount } from "../../../api/w2l/GetW2lTemplateUseCount";
import { BackLink } from "../../_common/BackLink";
import { distance, delay, delay2, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
const DEFAULT_APPROVED_STATE = true;
@@ -117,76 +119,86 @@ function W2lTemplateApproveFc(props: Props) {
return (
<div>
<div className="container py-5">
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold">{h1Title}</h1>
<Fade bottom cascade duration={duration} distance={distance}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold">{h1Title}</h1>
</div>
<div className="pt-3">
<BackLink link={templateLink} text="Back to template" />
</div>
</div>
<div className="pt-3">
<BackLink link={templateLink} text="Back to template" />
</div>
</div>
</Fade>
<div className="container-panel pt-2 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<table className="table">
<thead>
<tr>
<th>
<abbr title="Detail">Detail</abbr>
</th>
<th>
<abbr title="Value">Value</abbr>
</th>
</tr>
</thead>
<tbody>
<tr>
<th>Creator</th>
<td>{creatorLink}</td>
</tr>
<tr>
<th>Use Count</th>
<td>{humanUseCount}</td>
</tr>
<tr>
<th>Title</th>
<td>{w2lTemplate?.title}</td>
</tr>
<tr>
<th>Upload Date (UTC)</th>
<td>{w2lTemplate?.created_at}</td>
</tr>
</tbody>
</table>
</div>
</div>
<form onSubmit={handleApproveFormSubmit}>
<div className="container-panel pt-1 pb-5">
<Fade
bottom
cascade
duration={duration}
delay={delay}
distance={distance}
>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<label className="sub-title">
Mod Approval (sets public list visibility)
</label>
<table className="table">
<thead>
<tr>
<th>
<abbr title="Detail">Detail</abbr>
</th>
<th>
<abbr title="Value">Value</abbr>
</th>
</tr>
</thead>
<tbody>
<tr>
<th>Creator</th>
<td>{creatorLink}</td>
</tr>
<tr>
<th>Use Count</th>
<td>{humanUseCount}</td>
</tr>
<tr>
<th>Title</th>
<td>{w2lTemplate?.title}</td>
</tr>
<tr>
<th>Upload Date (UTC)</th>
<td>{w2lTemplate?.created_at}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div>
<div className="form-group">
<select
name="approve"
value={approvedFormDefaultState}
onChange={handleModApprovalChange}
className="form-select"
>
<option value="true">Approve</option>
<option value="false">Disapprove</option>
</select>
<form onSubmit={handleApproveFormSubmit}>
<div className="container-panel pt-1 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<label className="sub-title">
Mod Approval (sets public list visibility)
</label>
<div>
<div className="form-group">
<select
name="approve"
value={approvedFormDefaultState}
onChange={handleModApprovalChange}
className="form-select"
>
<option value="true">Approve</option>
<option value="false">Disapprove</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div className="container pb-5">
<button className="btn btn-primary w-100">Moderate</button>
</div>
</form>
<div className="container pb-5">
<button className="btn btn-primary w-100">Moderate</button>
</div>
</form>
</Fade>
</div>
);
}
@@ -1,35 +1,45 @@
import React, { useState, useEffect, useCallback } from 'react';
import { ApiConfig } from '@storyteller/components';
import { FrontendUrlConfig } from '../../../../common/FrontendUrlConfig';
import { SessionWrapper } from '@storyteller/components/src/session/SessionWrapper';
import { useParams, Link, useHistory } from 'react-router-dom';
import { GetW2lTemplate, GetW2lTemplateIsOk, W2lTemplate } from '../../../api/w2l/GetW2lTemplate';
import { GetW2lTemplateUseCount } from '../../../api/w2l/GetW2lTemplateUseCount';
import { BackLink } from '../../_common/BackLink';
import React, { useState, useEffect, useCallback } from "react";
import { ApiConfig } from "@storyteller/components";
import { FrontendUrlConfig } from "../../../../common/FrontendUrlConfig";
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
import { useParams, Link, useHistory } from "react-router-dom";
import {
GetW2lTemplate,
GetW2lTemplateIsOk,
W2lTemplate,
} from "../../../api/w2l/GetW2lTemplate";
import { GetW2lTemplateUseCount } from "../../../api/w2l/GetW2lTemplateUseCount";
import { BackLink } from "../../_common/BackLink";
import { distance, delay, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
interface Props {
sessionWrapper: SessionWrapper,
sessionWrapper: SessionWrapper;
}
function W2lTemplateDeleteFc(props: Props) {
const history = useHistory();
let { templateToken } : { templateToken : string } = useParams();
let { templateToken }: { templateToken: string } = useParams();
const [w2lTemplate, setW2lTemplate] = useState<W2lTemplate|undefined>(undefined);
const [w2lTemplateUseCount, setW2lTemplateUseCount] = useState<number|undefined>(undefined);
const [w2lTemplate, setW2lTemplate] = useState<W2lTemplate | undefined>(
undefined
);
const [w2lTemplateUseCount, setW2lTemplateUseCount] = useState<
number | undefined
>(undefined);
const getTemplate = useCallback(async (templateToken) => {
const template = await GetW2lTemplate(templateToken);
if (GetW2lTemplateIsOk(template)) {
setW2lTemplate(template)
setW2lTemplate(template);
}
}, []);
const getTemplateUseCount = useCallback(async (templateToken) => {
const count = await GetW2lTemplateUseCount(templateToken);
setW2lTemplateUseCount(count || 0)
setW2lTemplateUseCount(count || 0);
}, []);
const templateLink = FrontendUrlConfig.w2lTemplatePage(templateToken);
@@ -39,7 +49,9 @@ function W2lTemplateDeleteFc(props: Props) {
getTemplateUseCount(templateToken);
}, [templateToken, getTemplate, getTemplateUseCount]);
const handleDeleteFormSubmit = (ev: React.FormEvent<HTMLFormElement>) : boolean => {
const handleDeleteFormSubmit = (
ev: React.FormEvent<HTMLFormElement>
): boolean => {
ev.preventDefault();
const api = new ApiConfig();
@@ -47,58 +59,62 @@ function W2lTemplateDeleteFc(props: Props) {
const request = {
set_delete: !currentlyDeleted,
as_mod: props.sessionWrapper.deleteTtsResultAsMod(w2lTemplate?.creator_user_token)
}
as_mod: props.sessionWrapper.deleteTtsResultAsMod(
w2lTemplate?.creator_user_token
),
};
fetch(endpointUrl, {
method: 'POST',
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
Accept: "application/json",
"Content-Type": "application/json",
},
credentials: 'include',
credentials: "include",
body: JSON.stringify(request),
})
.then(res => res.json())
.then(res => {
if (res.success) {
if (props.sessionWrapper.canDeleteOtherUsersTtsResults()) {
history.push(templateLink); // Mods can perform further actions
} else {
history.push('/');
.then((res) => res.json())
.then((res) => {
if (res.success) {
if (props.sessionWrapper.canDeleteOtherUsersTtsResults()) {
history.push(templateLink); // Mods can perform further actions
} else {
history.push("/");
}
}
}
})
.catch(e => {
});
})
.catch((e) => {});
return false;
}
};
let creatorLink = <span />;
if (!!w2lTemplate?.creator_display_name) {
const creatorUrl = FrontendUrlConfig.userProfilePage(w2lTemplate?.creator_display_name);
const creatorUrl = FrontendUrlConfig.userProfilePage(
w2lTemplate?.creator_display_name
);
creatorLink = (
<Link to={creatorUrl}>{w2lTemplate?.creator_display_name}</Link>
);
}
let currentlyDeleted = !!w2lTemplate?.maybe_moderator_fields?.mod_deleted_at ||
!!w2lTemplate?.maybe_moderator_fields?.user_deleted_at;
let currentlyDeleted =
!!w2lTemplate?.maybe_moderator_fields?.mod_deleted_at ||
!!w2lTemplate?.maybe_moderator_fields?.user_deleted_at;
const h1Title = currentlyDeleted ? "Undelete Template?" : "Delete Template?";
const buttonTitle = currentlyDeleted ? "Confirm Undelete" : "Confirm Delete";
const buttonCss = currentlyDeleted ?
"button is-warning is-large is-fullwidth" :
"button is-danger is-large is-fullwidth";
const buttonCss = currentlyDeleted
? "btn btn-primary w-100"
: "btn btn-primary w-100";
const formLabel = currentlyDeleted ?
"Recover the W2L Template (makes it visible again)" :
"Delete W2L Template (hides from everyone but mods)";
const formLabel = currentlyDeleted
? "Recover the W2L Template (makes it visible again)"
: "Delete W2L Template (hides from everyone but mods)";
let humanUseCount : string | number = 'Fetching...';
let humanUseCount: string | number = "Fetching...";
if (w2lTemplateUseCount !== undefined && w2lTemplateUseCount !== null) {
humanUseCount = w2lTemplateUseCount;
@@ -106,90 +122,120 @@ function W2lTemplateDeleteFc(props: Props) {
let moderatorRows = null;
if (props.sessionWrapper.canDeleteOtherUsersTtsResults() || props.sessionWrapper.canDeleteOtherUsersW2lTemplates()) {
if (
props.sessionWrapper.canDeleteOtherUsersTtsResults() ||
props.sessionWrapper.canDeleteOtherUsersW2lTemplates()
) {
moderatorRows = (
<>
<tr>
<th>Creator is banned</th>
<td>{w2lTemplate?.maybe_moderator_fields?.creator_is_banned ? "banned" : "good standing" }</td>
<td>
{w2lTemplate?.maybe_moderator_fields?.creator_is_banned
? "banned"
: "good standing"}
</td>
</tr>
<tr>
<th>Creator IP Address (Creation)</th>
<td>{w2lTemplate?.maybe_moderator_fields?.creator_ip_address_creation || "server error"}</td>
<td>
{w2lTemplate?.maybe_moderator_fields?.creator_ip_address_creation ||
"server error"}
</td>
</tr>
<tr>
<th>Creator IP Address (Update)</th>
<td>{w2lTemplate?.maybe_moderator_fields?.creator_ip_address_last_update || "server error"}</td>
<td>
{w2lTemplate?.maybe_moderator_fields
?.creator_ip_address_last_update || "server error"}
</td>
</tr>
<tr>
<th>Mod Deleted At (UTC)</th>
<td>{w2lTemplate?.maybe_moderator_fields?.mod_deleted_at || "not deleted"}</td>
<td>
{w2lTemplate?.maybe_moderator_fields?.mod_deleted_at ||
"not deleted"}
</td>
</tr>
<tr>
<th>User Deleted At (UTC)</th>
<td>{w2lTemplate?.maybe_moderator_fields?.user_deleted_at || "not deleted"}</td>
<td>
{w2lTemplate?.maybe_moderator_fields?.user_deleted_at ||
"not deleted"}
</td>
</tr>
</>
);
}
return (
<div className="content">
<h1 className="title is-1"> {h1Title} </h1>
<p>
<BackLink link={templateLink} text="Back to template" />
</p>
<table className="table">
<thead>
<tr>
<th><abbr title="Detail">Detail</abbr></th>
<th><abbr title="Value">Value</abbr></th>
</tr>
</thead>
<tbody>
<tr>
<th>Creator</th>
<td>
{creatorLink}
</td>
</tr>
<tr>
<th>Use Count</th>
<td>{humanUseCount}</td>
</tr>
<tr>
<th>Title</th>
<td>{w2lTemplate?.title}</td>
</tr>
<tr>
<th>Upload Date (UTC)</th>
<td>{w2lTemplate?.created_at}</td>
</tr>
<div>
<Fade bottom cascade duration={duration} distance={distance}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold">{h1Title}</h1>
</div>
<div className="pt-3">
<BackLink link={templateLink} text="Back to template" />
</div>
</div>
</Fade>
{moderatorRows}
<Fade
bottom
cascade
duration={duration}
delay={delay}
distance={distance}
>
<div className="container pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<table className="table">
<thead>
<tr>
<th>
<abbr title="Detail">Detail</abbr>
</th>
<th>
<abbr title="Value">Value</abbr>
</th>
</tr>
</thead>
<tbody>
<tr>
<th>Creator</th>
<td>{creatorLink}</td>
</tr>
<tr>
<th>Use Count</th>
<td>{humanUseCount}</td>
</tr>
<tr>
<th>Title</th>
<td>{w2lTemplate?.title}</td>
</tr>
<tr>
<th>Upload Date (UTC)</th>
<td>{w2lTemplate?.created_at}</td>
</tr>
</tbody>
</table>
{moderatorRows}
</tbody>
</table>
</div>
</div>
<br />
<form onSubmit={handleDeleteFormSubmit}>
<label className="label">{formLabel}</label>
<p className="control">
<button className={buttonCss}>
{buttonTitle}
</button>
</p>
</form>
<br />
<br />
<BackLink link={templateLink} text="Back to template" />
<form onSubmit={handleDeleteFormSubmit}>
<div className="container">
<button className={buttonCss}>{buttonTitle}</button>
</div>
<div className="container pb-5">
<p className="pt-4">{formLabel}</p>
</div>
</form>
</Fade>
</div>
)
);
}
export { W2lTemplateDeleteFc };
@@ -11,6 +11,8 @@ import {
W2lTemplate,
} from "../../../api/w2l/GetW2lTemplate";
import { BackLink } from "../../_common/BackLink";
import { distance, delay, delay2, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
const DEFAULT_VISIBILITY = "public";
@@ -117,76 +119,88 @@ function W2lTemplateEditFc(props: Props) {
return (
<div>
<div className="container py-5">
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold">Edit Template</h1>
<Fade bottom cascade duration={duration} distance={distance}>
<div className="container pt-5 pb-4 px-lg-5 px-xl-3">
<div className="d-flex flex-column">
<h1 className="display-5 fw-bold">Edit Template</h1>
</div>
<div className="mt-3">
<BackLink link={templateLink} text="Back to template" />
</div>
</div>
<div className="mt-3">
<BackLink link={templateLink} text="Back to template" />
</div>
</div>
</Fade>
<form onSubmit={handleFormSubmit}>
<fieldset disabled={isDisabled}>
<div className="container-panel pt-2 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">Template title</label>
<div className="form-group">
<input
onChange={handleTitleChange}
className="form-control"
type="text"
placeholder="Template title"
value={title}
/>
<Fade
bottom
cascade
duration={duration}
delay={delay}
distance={distance}
>
<form onSubmit={handleFormSubmit}>
<fieldset disabled={isDisabled}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 py-4 p-lg-4">
<div className="d-flex flex-column gap-4">
<div>
<label className="sub-title">Template title</label>
<div className="form-group">
<input
onChange={handleTitleChange}
className="form-control"
type="text"
placeholder="Template title"
value={title}
/>
</div>
{/*<p className="help">{invalidReason}</p>*/}
</div>
{/*<p className="help">{invalidReason}</p>*/}
</div>
<div>
<label className="sub-title">
Description (supports Markdown)
</label>
<div className="form-group">
<textarea
onChange={handleDescriptionMarkdownChange}
className="form-control"
placeholder="Model description (ie. source of data, training duration, etc)"
value={descriptionMarkdown}
rows={5}
/>
<div>
<label className="sub-title">
Description (supports Markdown)
</label>
<div className="form-group">
<textarea
onChange={handleDescriptionMarkdownChange}
className="form-control"
placeholder="Model description (ie. source of data, training duration, etc)"
value={descriptionMarkdown}
rows={5}
/>
</div>
</div>
</div>
<div>
<label className="sub-title">
Template Visibility&nbsp;{visibilityIcon}
</label>
<div className="form-group">
<select
name="creator_set_visibility"
onChange={handleVisibilityChange}
value={visibility}
className="form-control"
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">Unlisted (shareable URLs)</option>
</select>
<div>
<label className="sub-title">
Template Visibility&nbsp;{visibilityIcon}
</label>
<div className="form-group">
<select
name="creator_set_visibility"
onChange={handleVisibilityChange}
value={visibility}
className="form-control"
>
<option value="public">
Public (visible from your profile)
</option>
<option value="hidden">
Unlisted (shareable URLs)
</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
<div className="container pb-5">
<button className="btn btn-primary w-100">Update Template</button>
</div>
</fieldset>
</form>
<div className="container pb-5">
<button className="btn btn-primary w-100">Update Template</button>
</div>
</fieldset>
</form>
</Fade>
</div>
);
}
@@ -21,6 +21,8 @@ import {
} from "../../../api/w2l/GetW2lTemplate";
import { GetW2lTemplateUseCount } from "../../../api/w2l/GetW2lTemplateUseCount";
import { BackLink } from "../../_common/BackLink";
import { distance, delay, delay2, duration } from "../../../../data/animation";
const Fade = require("react-reveal/Fade");
interface EnqueueJobResponsePayload {
success: boolean;
@@ -376,147 +378,161 @@ function W2lTemplateViewFc(props: Props) {
return (
<div>
<div className="container py-5 px-md-4 px-lg-5 px-xl-3">
<div className="d-flex flex-column">
<Fade bottom cascade duration={duration} distance={distance}>
<div className="container py-5 px-md-4 px-lg-5 px-xl-3">
<h1 className="display-5 fw-bold">Video Lip Sync Template</h1>
<h4>Template: {w2lTemplate?.title}</h4>
<div className="pt-3">
<BackLink
link={FrontendUrlConfig.w2lListPage()}
text="Back to all templates"
/>
</div>
</div>
<div className="mt-3">
<BackLink
link={FrontendUrlConfig.w2lListPage()}
text="Back to all templates"
/>
</div>
</div>
</Fade>
<form onSubmit={handleInferenceFormSubmit}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Upload Audio</h2>
<div className="py-6">
<div className="d-flex flex-column flex-lg-row gap-5">
<div className="d-flex flex-column gap-4 w-100 w-lg-50">
<p>
Upload audio from FakeYou or any other source (eg. music),
then submit. You'll get a beautifully lipsynced video.
</p>
<div>
<label className="sub-title">Select an audio file</label>
<input
id="formFileLg"
type="file"
name="audio"
className="form-control form-control-lg"
onChange={(e) => handleAudioFileChange(e.target.files)}
/>
<Fade
bottom
cascade
duration={duration}
distance={distance}
delay={delay}
>
<form onSubmit={handleInferenceFormSubmit}>
<div className="container-panel pt-4 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Upload Audio</h2>
<div className="py-6">
<div className="d-flex flex-column flex-lg-row gap-5">
<div className="d-flex flex-column gap-4 w-100 w-lg-50">
<p>
Upload audio from FakeYou or any other source (eg. music),
then submit. You'll get a beautifully lipsynced video.
</p>
<div>
<label className="sub-title">Select an audio file</label>
<input
id="formFileLg"
type="file"
name="audio"
className="form-control form-control-lg"
onChange={(e) => handleAudioFileChange(e.target.files)}
/>
</div>
<button className="btn btn-primary w-100 mt-3">
Submit
</button>
</div>
<button className="btn btn-primary w-100 mt-3">Submit</button>
</div>
<div className="d-flex w-100 w-lg-50 justify-content-center">
<div className="template-preview ">
<img
src={url}
alt="template preview"
className="img-fluid rounded"
/>
<div className="d-flex w-100 w-lg-50 justify-content-center">
<div className="template-preview ">
<img
src={url}
alt="template preview"
className="img-fluid rounded"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
<div>
<div>{templateDescription}</div>
</div>
</form>
{templateDescription}
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Template Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Title</th>
<td>{w2lTemplate?.title}</td>
</tr>
<tr>
<th>Creator</th>
<td>{creatorLink}</td>
</tr>
<tr>
<th>Use count</th>
<td>{humanUseCount}</td>
</tr>
<tr>
<th>Visibility</th>
<td>{resultVisibility}</td>
</tr>
<tr>
<th>Is public listing approved?</th>
<td>{modApprovalStatus}</td>
</tr>
</tbody>
</table>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Template Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Title</th>
<td>{w2lTemplate?.title}</td>
</tr>
<tr>
<th>Creator</th>
<td>{creatorLink}</td>
</tr>
<tr>
<th>Use count</th>
<td>{humanUseCount}</td>
</tr>
<tr>
<th>Visibility</th>
<td>{resultVisibility}</td>
</tr>
<tr>
<th>Is public listing approved?</th>
<td>{modApprovalStatus}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Media Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Media type</th>
<td>{w2lTemplate?.template_type}</td>
</tr>
<tr>
<th>Dimensions</th>
<td>
{w2lTemplate?.frame_width} x {w2lTemplate?.frame_height}
</td>
</tr>
<tr>
<th>Duration (milliseconds)</th>
<td>{w2lTemplate?.duration_millis}</td>
</tr>
<tr>
<th>Created at (UTC)</th>
<td>{w2lTemplate?.created_at}</td>
</tr>
<tr>
<th>Updated at (UTC)</th>
<td>{w2lTemplate?.updated_at}</td>
</tr>
</tbody>
</table>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Media Details</h2>
<div className="py-6">
<table className="table">
<tbody>
<tr>
<th>Media type</th>
<td>{w2lTemplate?.template_type}</td>
</tr>
<tr>
<th>Dimensions</th>
<td>
{w2lTemplate?.frame_width} x {w2lTemplate?.frame_height}
</td>
</tr>
<tr>
<th>Duration (milliseconds)</th>
<td>{w2lTemplate?.duration_millis}</td>
</tr>
<tr>
<th>Created at (UTC)</th>
<td>{w2lTemplate?.created_at}</td>
</tr>
<tr>
<th>Updated at (UTC)</th>
<td>{w2lTemplate?.updated_at}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Moderator Details</h2>
<div className="py-6">
<table className="table">
<tbody>{moderatorRows}</tbody>
</table>
<div className="container-panel pt-3 pb-5">
<div className="panel p-3 p-lg-4">
<h2 className="panel-title fw-bold">Moderator Details</h2>
<div className="py-6">
<table className="table">
<tbody>{moderatorRows}</tbody>
</table>
</div>
</div>
</div>
</div>
<div className="container">
<div className="d-flex flex-column flex-lg-row gap-3">
{editButton}
{approveButton}
{deleteButton}
<div className="container">
<div className="d-flex flex-column flex-lg-row gap-3">
{editButton}
{approveButton}
{deleteButton}
</div>
</div>
</div>
<div className="container pt-4 pb-5">
<ReportDiscordLinkFc />
</div>
<div>
<div className="container pt-4 pb-5">
<ReportDiscordLinkFc />
</div>
</div>
</Fade>
<SessionW2lInferenceResultListFc
w2lInferenceJobs={props.w2lInferenceJobs}