This commit is contained in:
BFlat committed 2023-10-13 00:40:22 +07:00
1 parent cf3f79dc5f
commit a65267ec7f
11 files changed
+141 -38

No files matched your search

@@ -4,7 +4,7 @@
font-weight: 500;
border-radius: 0.5rem;
font-size: 13px;
padding: 9px 12px;
padding: 6px 12px;
background-color: $secondary;
color: $white;
cursor: pointer;
@@ -3,13 +3,17 @@ import "./CheckableTag.scss";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faXmark } from "@fortawesome/pro-solid-svg-icons";
interface Props {
interface CheckableTagProps {
tag: string;
isSelected: boolean;
onToggle: (tag: string) => void;
}
export default function CheckableTag({ tag, isSelected, onToggle }: Props) {
export default function CheckableTag({
tag,
isSelected,
onToggle,
}: CheckableTagProps) {
return (
<div
className={`d-flex align-items-center checkable-tag ${
@@ -2,12 +2,12 @@ import React from "react";
import Input from "../Input";
import { faSearch } from "@fortawesome/pro-solid-svg-icons";
interface Props {
interface ModelSearchProps {
value: string;
onChange: (value: string) => void;
}
export default function ModelSearch({ value, onChange }: Props) {
export default function ModelSearch({ value, onChange }: ModelSearchProps) {
return (
<Input
icon={faSearch}
@@ -1,4 +0,0 @@
export const dummyData = [
{ id: 1, name: "Item 1", tags: ["tag1", "tag2"] },
{ id: 2, name: "Item 2", tags: ["tag2", "tag3"] },
];
@@ -5,14 +5,20 @@
border-radius: 0.5rem;
border: 1px solid lighten($panel, 12%);
.creator-name {
font-weight: 400;
font-size: 14px;
color: $white;
margin-bottom: 0.5rem;
}
.type-tag {
font-weight: 600;
border-radius: 0.4rem;
border-radius: 0.35rem;
font-size: 13px;
padding: 4px 8px;
background-color: $secondary;
color: $white;
cursor: pointer;
transition: 0.2s;
-moz-user-select: none;
-khtml-user-select: none;
@@ -26,4 +32,8 @@
background-color: #c6c7e1;
}
}
.model-details {
font-size: 14px;
}
}
@@ -1,28 +1,71 @@
import React from "react";
import "./ModelSearchResults.scss";
import { Link } from "react-router-dom";
import Button from "../Button";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faChartSimple,
faComment,
faHeart,
} from "@fortawesome/pro-solid-svg-icons";
interface Props {
interface ModelSearchResultsProps {
data: any[];
}
export default function ModelSearchResults({ data }: Props) {
function shortenNumber(num: number): string {
if (Math.abs(num) < 1e3) return num.toString();
if (Math.abs(num) < 1e6) return (num / 1e3).toFixed(1) + "k";
if (Math.abs(num) < 1e9) return (num / 1e6).toFixed(1) + "M";
return num.toString();
}
export default function ModelSearchResults({ data }: ModelSearchResultsProps) {
return (
<div className="row g-3">
{data.map((item) => (
<div className="col-12 col-lg-6">
<div className="model-search-results p-3" key={item.id}>
<h5 className="fw-semibold mb-0">{item.name}</h5>
<p className="">by {item.creator}</p>
<span
className={`type-tag ${
item.type === "Tacotron2" ? "tt2" : "tt2"
}`}
>
{item.type}
</span>
{data.map((item) => {
return (
<div className="col-12 col-lg-6" key={item.id}>
<div className="model-search-results p-3">
<h5 className="fw-semibold mb-0">{item.name}</h5>
<p className="creator-name">
by{" "}
<Link className="fw-medium" to={`/profile/${item.creator}`}>
{item.creator}
</Link>
</p>
<div className="d-flex align-items-end">
<div className="flex-grow-1">
<span
className={`type-tag ${
item.type === "Tacotron2" ? "tt2" : "tt2"
}`}
>
{item.type}
</span>
<div className="d-flex gap-3 model-details fw-medium mt-3">
<div>
<FontAwesomeIcon icon={faHeart} className="me-2" />
{item.likes && shortenNumber(item.likes)}
</div>
<div>
<FontAwesomeIcon icon={faChartSimple} className="me-2" />
{item.uses && shortenNumber(item.uses)}
</div>
<div>
<FontAwesomeIcon icon={faComment} className="me-2" />
{item.comments && shortenNumber(item.comments)}
</div>
</div>
</div>
<div>
<Button label="Use Voice" small={true} to="/" />
</div>
</div>
</div>
</div>
</div>
))}
);
})}
</div>
);
}
@@ -1,13 +1,17 @@
import React from "react";
import CheckableTag from "../CheckableTag";
interface Props {
interface ModelTagsProps {
tags: string[];
selectedTags: string[];
onSelectTag: (tag: string) => void;
}
export default function ModelTags({ tags, selectedTags, onSelectTag }: Props) {
export default function ModelTags({
tags,
selectedTags,
onSelectTag,
}: ModelTagsProps) {
return (
<div className="d-flex gap-2 flex-wrap">
{tags.map((tag) => (
@@ -41,13 +41,15 @@ export default function PageHeader({
{icon}
{title}
</h2>
{showButton && (
<Button
variant={buttonVariant}
label={buttonLabel}
to={buttonTo}
/>
)}
<div className="d-none d-md-block">
{showButton && (
<Button
variant={buttonVariant}
label={buttonLabel}
to={buttonTo}
/>
)}
</div>
</div>
<p>{subText}</p>
</div>
@@ -0,0 +1 @@
export { default } from "./useShortenNumber";
@@ -0,0 +1,6 @@
export default function useShortenNumber(num: number): string {
if (Math.abs(num) < 1e3) return num.toString();
if (Math.abs(num) < 1e6) return (num / 1e3).toFixed(1) + "k";
if (Math.abs(num) < 1e9) return (num / 1e6).toFixed(1) + "M";
return num.toString();
}
@@ -2,12 +2,13 @@ import React from "react";
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
import Container from "components/common/Container";
import PageHeader from "components/layout/PageHeader";
import { faMessageDots } from "@fortawesome/pro-solid-svg-icons";
import { faClock, faMessageDots } from "@fortawesome/pro-solid-svg-icons";
import ModelSearch from "components/common/ModelSearch";
import Panel from "components/common/Panel";
import useSearch from "hooks/useSearch/useSearch";
import ModelSearchResults from "components/common/ModelSearchResults";
import ModelTags from "components/common/ModelTags";
import Select from "components/common/Select";
interface TtsModelSearchPageProps {
sessionWrapper: SessionWrapper;
@@ -19,18 +20,33 @@ const dummyData = [
name: "Spongebob",
tags: ["English", "High-pitched", "Character"],
type: "Tacotron2",
creator: "echelon",
likes: 14000,
uses: 1000000,
comments: 250,
time: new Date("2023-09-20T12:00:00Z").toISOString(),
},
{
id: 2,
name: "Mariano Closs",
tags: ["Spanish", "Low-pitched"],
type: "Tacotron2",
creator: "echelon",
likes: 308290,
uses: 30000000,
comments: 1200,
time: new Date("2023-10-12T12:00:00Z").toISOString(),
},
{
id: 3,
name: "Cristiano Ronaldo",
tags: ["Portuguese", "Low-pitched"],
type: "Tacotron2",
creator: "echelon",
likes: 17500,
uses: 40000000,
comments: 250,
time: new Date("2023-09-20T12:00:00Z").toISOString(),
},
];
@@ -72,12 +88,24 @@ export default function TtsModelSearchPage(props: TtsModelSearchPageProps) {
</div>
);
const sortOptions = [
{ value: "most liked", label: "Most Liked" },
{ value: "most used", label: "Most Used" },
{ value: "moset recent", label: "Most Recent" },
];
const sortTimeOptions = [
{ value: "all time", label: "All Time" },
{ value: "today", label: "Today" },
{ value: "this week", label: "This Week" },
{ value: "this month", label: "This Month" },
];
return (
<Container type="panel">
<PageHeader
title="Text to Speech"
titleIcon={faMessageDots}
subText="Turn text into your favorite character's speaking voice."
subText="Turn text into your favorite character's voice."
showButton={true}
buttonLabel="Create a voice"
buttonVariant="secondary"
@@ -85,6 +113,15 @@ export default function TtsModelSearchPage(props: TtsModelSearchPageProps) {
extension={searchTts}
/>
<Panel padding={true}>
<div className="d-flex gap-2 mb-3">
<Select options={sortOptions} defaultValue={sortOptions[0]} />
<Select
icon={faClock}
options={sortTimeOptions}
defaultValue={sortTimeOptions[0]}
/>
</div>
<ModelSearchResults data={filteredData} />
</Panel>
</Container>