Improve publish page.

This commit is contained in:
2025-05-15 19:53:30 +08:00
parent 75389bc3c0
commit f8271161cb
3 changed files with 57 additions and 41 deletions

View File

@@ -19,7 +19,7 @@ export const i18nData = {
"Don't have an account? Register": "Don't have an account? Register", "Don't have an account? Register": "Don't have an account? Register",
"Already have an account? Login": "Already have an account? Login", "Already have an account? Login": "Already have an account? Login",
"Publish Resource": "Publish Resource", "Publish Resource": "Publish Resource",
"All information, images, and files can be modified after publishing": "All information, images, and files can be modified after publishing", "All information can be modified after publishing": "All information can be modified after publishing",
"Title": "Title", "Title": "Title",
"Alternative Titles": "Alternative Titles", "Alternative Titles": "Alternative Titles",
"Add Alternative Title": "Add Alternative Title", "Add Alternative Title": "Add Alternative Title",
@@ -142,6 +142,11 @@ export const i18nData = {
"Cloudflare Turnstile Site Key": "Cloudflare Turnstile Site Key", "Cloudflare Turnstile Site Key": "Cloudflare Turnstile Site Key",
"Cloudflare Turnstile Secret Key": "Cloudflare Turnstile Secret Key", "Cloudflare Turnstile Secret Key": "Cloudflare Turnstile Secret Key",
"If the cloudflare turnstile keys are not empty, the turnstile will be used for register and download.": "If the cloudflare turnstile keys are not empty, the turnstile will be used for register and download.", "If the cloudflare turnstile keys are not empty, the turnstile will be used for register and download.": "If the cloudflare turnstile keys are not empty, the turnstile will be used for register and download.",
"The first image will be used as the cover image": "The first image will be used as the cover image",
"Please enter a search keyword": "Please enter a search keyword",
"Searching...": "Searching...",
"Create Tag": "Create Tag",
"Search Tags": "Search Tags",
} }
}, },
"zh-CN": { "zh-CN": {
@@ -164,7 +169,7 @@ export const i18nData = {
"Don't have an account? Register": "没有账号?注册", "Don't have an account? Register": "没有账号?注册",
"Already have an account? Login": "已有账号?登录", "Already have an account? Login": "已有账号?登录",
"Publish Resource": "发布资源", "Publish Resource": "发布资源",
"All information, images, and files can be modified after publishing": "所有的信息, 图片, 文件均可在发布后修改", "All information can be modified after publishing": "所有的信息均可在发布后修改",
"Title": "标题", "Title": "标题",
"Alternative Titles": "其他标题", "Alternative Titles": "其他标题",
"Add Alternative Title": "新增标题", "Add Alternative Title": "新增标题",
@@ -287,6 +292,11 @@ export const i18nData = {
"Cloudflare Turnstile Site Key": "Cloudflare Turnstile 站点密钥", "Cloudflare Turnstile Site Key": "Cloudflare Turnstile 站点密钥",
"Cloudflare Turnstile Secret Key": "Cloudflare Turnstile 密钥", "Cloudflare Turnstile Secret Key": "Cloudflare Turnstile 密钥",
"If the cloudflare turnstile keys are not empty, the turnstile will be used for register and download.": "如果设置了 Cloudflare Turnstile 密钥,将在注册和下载时启用验证", "If the cloudflare turnstile keys are not empty, the turnstile will be used for register and download.": "如果设置了 Cloudflare Turnstile 密钥,将在注册和下载时启用验证",
"The first image will be used as the cover image": "第一张图片将用作封面图片",
"Please enter a search keyword": "请输入搜索关键词",
"Searching...": "搜索中...",
"Create Tag": "创建标签",
"Search Tags": "搜索标签",
} }
}, },
"zh-TW": { "zh-TW": {
@@ -309,7 +319,7 @@ export const i18nData = {
"Don't have an account? Register": "沒有賬號?註冊", "Don't have an account? Register": "沒有賬號?註冊",
"Already have an account? Login": "已有賬號?登入", "Already have an account? Login": "已有賬號?登入",
"Publish Resource": "發布資源", "Publish Resource": "發布資源",
"All information, images, and files can be modified after publishing": "所有資訊、圖片、檔案均可於發布後修改", "All information can be modified after publishing": "所有資訊均可於發布後修改",
"Title": "標題", "Title": "標題",
"Alternative Titles": "其他標題", "Alternative Titles": "其他標題",
"Add Alternative Title": "新增標題", "Add Alternative Title": "新增標題",
@@ -432,6 +442,11 @@ export const i18nData = {
"Cloudflare Turnstile Site Key": "Cloudflare Turnstile 網站密鑰", "Cloudflare Turnstile Site Key": "Cloudflare Turnstile 網站密鑰",
"Cloudflare Turnstile Secret Key": "Cloudflare Turnstile 密鑰", "Cloudflare Turnstile Secret Key": "Cloudflare Turnstile 密鑰",
"If the cloudflare turnstile keys are not empty, the turnstile will be used for register and download.": "如果設置了 Cloudflare Turnstile 密鑰,將在註冊和下載時啟用驗證", "If the cloudflare turnstile keys are not empty, the turnstile will be used for register and download.": "如果設置了 Cloudflare Turnstile 密鑰,將在註冊和下載時啟用驗證",
"The first image will be used as the cover image": "第一張圖片將用作封面圖片",
"Please enter a search keyword": "請輸入搜尋關鍵字",
"Searching...": "搜尋中...",
"Create Tag": "創建標籤",
"Search Tags": "搜尋標籤",
} }
} }
} }

View File

@@ -7,18 +7,18 @@
prefersdark: false; prefersdark: false;
color-scheme: "light"; color-scheme: "light";
--color-base-100: oklch(99% 0.014 343.198); --color-base-100: oklch(99% 0.014 343.198);
--color-base-200: oklch(96% 0.028 342.258); --color-base-200: oklch(97% 0.028 342.258);
--color-base-300: oklch(84% 0.061 343.231); --color-base-300: oklch(84% 0.061 343.231);
--color-base-content: oklch(0% 0 0); --color-base-content: oklch(0% 0 0);
--color-primary: oklch(65% 0.241 354.308); --color-primary: oklch(65% 0.241 354.308);
--color-primary-content: oklch(100% 0 0); --color-primary-content: oklch(100% 0 0);
--color-secondary: oklch(62% 0.265 303.9); --color-secondary: oklch(62% 0.265 303.9);
--color-secondary-content: oklch(97% 0.014 308.299); --color-secondary-content: oklch(97% 0.014 308.299);
--color-accent: oklch(78% 0.115 274.713); --color-accent: oklch(0.759 0.124 274.458);
--color-accent-content: oklch(39% 0.09 240.876); --color-accent-content: oklch(20% 0.09 240.876);
--color-neutral: oklch(40% 0.153 2.432); --color-neutral: oklch(40% 0.153 2.432);
--color-neutral-content: oklch(89% 0.061 343.231); --color-neutral-content: oklch(89% 0.061 343.231);
--color-info: oklch(80% 0.105 251.813); --color-info: oklch(75% 0.105 251.813);
--color-info-content: oklch(44% 0.11 240.79); --color-info-content: oklch(44% 0.11 240.79);
--color-success: oklch(70% 0.14 182.503); --color-success: oklch(70% 0.14 182.503);
--color-success-content: oklch(43% 0.095 166.913); --color-success-content: oklch(43% 0.095 166.913);
@@ -27,7 +27,7 @@
--color-error: oklch(63% 0.237 25.331); --color-error: oklch(63% 0.237 25.331);
--color-error-content: oklch(97% 0.013 17.38); --color-error-content: oklch(97% 0.013 17.38);
--radius-selector: 1rem; --radius-selector: 1rem;
--radius-field: 1rem; --radius-field: 1.5rem;
--radius-box: 1rem; --radius-box: 1rem;
--size-selector: 0.25rem; --size-selector: 0.25rem;
--size-field: 0.25rem; --size-field: 0.25rem;
@@ -62,7 +62,7 @@
--color-error: oklch(68.22% 0.206 24.43); --color-error: oklch(68.22% 0.206 24.43);
--color-error-content: oklch(13.644% 0.041 24.43); --color-error-content: oklch(13.644% 0.041 24.43);
--radius-selector: 1rem; --radius-selector: 1rem;
--radius-field: 1rem; --radius-field: 1.5rem;
--radius-box: 1rem; --radius-box: 1rem;
--size-selector: 0.25rem; --size-selector: 0.25rem;
--size-field: 0.25rem; --size-field: 0.25rem;

View File

@@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { MdAdd, MdDelete, MdOutlineInfo } from "react-icons/md"; import {MdAdd, MdClose, MdDelete, MdOutlineInfo, MdSearch} from "react-icons/md";
import { Tag } from "../network/models.ts"; import { Tag } from "../network/models.ts";
import { network } from "../network/network.ts"; import { network } from "../network/network.ts";
import { LuInfo } from "react-icons/lu"; import { LuInfo } from "react-icons/lu";
@@ -24,7 +24,7 @@ export default function PublishPage() {
useEffect(() => { useEffect(() => {
document.title = t("Publish Resource"); document.title = t("Publish Resource");
}, []) }, [t])
const handleSubmit = async () => { const handleSubmit = async () => {
if (isSubmitting) { if (isSubmitting) {
@@ -102,7 +102,7 @@ export default function PublishPage() {
<h1 className={"text-2xl font-bold my-4"}>{t("Publish Resource")}</h1> <h1 className={"text-2xl font-bold my-4"}>{t("Publish Resource")}</h1>
<div role="alert" className="alert alert-info mb-2 alert-dash"> <div role="alert" className="alert alert-info mb-2 alert-dash">
<MdOutlineInfo size={24} /> <MdOutlineInfo size={24} />
<span>{t("All information, images, and files can be modified after publishing")}</span> <span>{t("All information can be modified after publishing")}</span>
</div> </div>
<p className={"my-1"}>{t("Title")}</p> <p className={"my-1"}>{t("Title")}</p>
<input type="text" className="input w-full" value={title} onChange={(e) => setTitle(e.target.value)} /> <input type="text" className="input w-full" value={title} onChange={(e) => setTitle(e.target.value)} />
@@ -137,7 +137,16 @@ export default function PublishPage() {
<p className={"my-1 pb-1"}> <p className={"my-1 pb-1"}>
{ {
tags.map((tag, index) => { tags.map((tag, index) => {
return <span key={index} className={"badge badge-primary mr-2"}>{tag.name}</span> return <span key={index} className={"badge badge-primary mr-2 text-sm"}>
{tag.name}
<span onClick={() => {
const newTags = [...tags]
newTags.splice(index, 1)
setTags(newTags)
}}>
<MdClose size={18}/>
</span>
</span>
}) })
} }
</p> </p>
@@ -155,7 +164,10 @@ export default function PublishPage() {
<p className={"my-1"}>{t("Images")}</p> <p className={"my-1"}>{t("Images")}</p>
<div role="alert" className="alert alert-info alert-soft my-2"> <div role="alert" className="alert alert-info alert-soft my-2">
<MdOutlineInfo size={24} /> <MdOutlineInfo size={24} />
<span>{t("Images will not be displayed automatically, you need to reference them in the description")}</span> <div>
<p>{t("Images will not be displayed automatically, you need to reference them in the description")}</p>
<p>{t("The first image will be used as the cover image")}</p>
</div>
</div> </div>
<div className={`rounded-box border border-base-content/5 bg-base-100 ${images.length === 0 ? "hidden" : ""}`}> <div className={`rounded-box border border-base-content/5 bg-base-100 ${images.length === 0 ? "hidden" : ""}`}>
<table className={"table"}> <table className={"table"}>
@@ -273,7 +285,7 @@ function TagInput({ onAdd }: { onAdd: (tag: Tag) => void }) {
input.blur() input.blur()
} }
let dropdownContent = <></> let dropdownContent
if (error) { if (error) {
dropdownContent = <div className="alert alert-error my-2"> dropdownContent = <div className="alert alert-error my-2">
<svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 shrink-0 stroke-current" fill="none" <svg xmlns="http://www.w3.org/2000/svg" className="h-6 w-6 shrink-0 stroke-current" fill="none"
@@ -319,18 +331,7 @@ function TagInput({ onAdd }: { onAdd: (tag: Tag) => void }) {
return <div className={"dropdown dropdown-end"}> return <div className={"dropdown dropdown-end"}>
<label className="input"> <label className="input">
<svg className="h-[1em] opacity-50" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <MdSearch size={18}/>
<g
stroke-linejoin="round"
stroke-linecap="round"
stroke-width="2.5"
fill="none"
stroke="currentColor"
>
<circle cx="11" cy="11" r="8"></circle>
<path d="m21 21-4.3-4.3"></path>
</g>
</svg>
<input autoComplete={"off"} id={"search_tags_input"} tabIndex={0} type="text" className="grow" placeholder={t("Search Tags")} value={keyword} onChange={(e) => handleChange(e.target.value)} /> <input autoComplete={"off"} id={"search_tags_input"} tabIndex={0} type="text" className="grow" placeholder={t("Search Tags")} value={keyword} onChange={(e) => handleChange(e.target.value)} />
</label> </label>
<ul tabIndex={0} className="dropdown-content menu bg-base-100 rounded-box z-1 w-52 p-2 shadow mt-2 border border-base-300"> <ul tabIndex={0} className="dropdown-content menu bg-base-100 rounded-box z-1 w-52 p-2 shadow mt-2 border border-base-300">