mirror of
https://github.com/wgh136/nysoure.git
synced 2025-09-27 12:17:24 +00:00
Add collelction permission.
This commit is contained in:
@@ -236,7 +236,8 @@ export const i18nData = {
|
||||
"Collection created successfully": "合集创建成功",
|
||||
"Collection deleted successfully": "合集删除成功",
|
||||
"Remove Resource": "移除资源",
|
||||
"Are you sure you want to remove this resource?": "您确定要移除此资源吗?",
|
||||
"Are you sure you want to remove this resource?":
|
||||
"您确定要移除此资源吗?",
|
||||
"Resource deleted successfully": "资源移除成功",
|
||||
"Edit Collection": "编辑合集",
|
||||
"Edit successful": "编辑成功",
|
||||
@@ -250,7 +251,9 @@ export const i18nData = {
|
||||
"Update File Info": "更新文件信息",
|
||||
"File info updated successfully": "文件信息更新成功",
|
||||
"File URL": "文件URL",
|
||||
"You do not have permission to upload files, please contact the administrator.": "您没有上传文件的权限,请联系管理员。",
|
||||
"You do not have permission to upload files, please contact the administrator.":
|
||||
"您没有上传文件的权限,请联系管理员。",
|
||||
"Private": "私有",
|
||||
},
|
||||
},
|
||||
"zh-TW": {
|
||||
@@ -490,7 +493,8 @@ export const i18nData = {
|
||||
"Collection created successfully": "合集創建成功",
|
||||
"Collection deleted successfully": "合集刪除成功",
|
||||
"Remove Resource": "移除資源",
|
||||
"Are you sure you want to remove this resource?": "您確定要移除此資源嗎?",
|
||||
"Are you sure you want to remove this resource?":
|
||||
"您確定要移除此資源嗎?",
|
||||
"Resource deleted successfully": "資源移除成功",
|
||||
"Edit Collection": "編輯合集",
|
||||
"Edit successful": "編輯成功",
|
||||
@@ -504,7 +508,9 @@ export const i18nData = {
|
||||
"Update File Info": "更新檔案信息",
|
||||
"File info updated successfully": "檔案信息更新成功",
|
||||
"File URL": "檔案URL",
|
||||
"You do not have permission to upload files, please contact the administrator.": "您沒有上傳檔案的權限,請聯繫管理員。",
|
||||
"You do not have permission to upload files, please contact the administrator.":
|
||||
"您沒有上傳檔案的權限,請聯繫管理員。",
|
||||
"Private": "私有",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@@ -199,4 +199,5 @@ export interface Collection {
|
||||
user: User;
|
||||
resources_count: number;
|
||||
images: Image[];
|
||||
isPublic: boolean;
|
||||
}
|
||||
|
@@ -693,11 +693,13 @@ class Network {
|
||||
async createCollection(
|
||||
title: string,
|
||||
article: string,
|
||||
isPublic: boolean,
|
||||
): Promise<Response<Collection>> {
|
||||
return this._callApi(() =>
|
||||
axios.postForm(`${this.apiBaseUrl}/collection/create`, {
|
||||
title,
|
||||
article,
|
||||
public: isPublic,
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -706,12 +708,14 @@ class Network {
|
||||
id: number,
|
||||
title: string,
|
||||
article: string,
|
||||
isPublic: boolean,
|
||||
): Promise<Response<any>> {
|
||||
return this._callApi(() =>
|
||||
axios.postForm(`${this.apiBaseUrl}/collection/update`, {
|
||||
id,
|
||||
title,
|
||||
article,
|
||||
public: isPublic,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@@ -6,10 +6,11 @@ import { Collection } from "../network/models";
|
||||
import Markdown from "react-markdown";
|
||||
import ResourcesView from "../components/resources_view";
|
||||
import Loading from "../components/loading";
|
||||
import { MdOutlineDelete, MdOutlineEdit } from "react-icons/md";
|
||||
import { MdOutlineAdd, MdOutlineDelete, MdOutlineEdit } from "react-icons/md";
|
||||
import { app } from "../app";
|
||||
import { useTranslation } from "../utils/i18n";
|
||||
import Button from "../components/button";
|
||||
import Badge from "../components/badge";
|
||||
|
||||
export default function CollectionPage() {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
@@ -54,7 +55,7 @@ export default function CollectionPage() {
|
||||
useEffect(() => {
|
||||
if (!collection) return;
|
||||
document.title = collection.title;
|
||||
}, [collection])
|
||||
}, [collection]);
|
||||
|
||||
const toBeDeletedRID = useRef<number | null>(null);
|
||||
|
||||
@@ -160,6 +161,12 @@ export default function CollectionPage() {
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
<span className="flex-1" />
|
||||
{!collection.isPublic && (
|
||||
<Badge className="badge-soft badge-error text-xs mr-2">
|
||||
<MdOutlineAdd size={16} className="inline-block" /> {t("Private")}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ResourcesView
|
||||
@@ -275,6 +282,7 @@ function EditCollectionDialog({
|
||||
}) {
|
||||
const [editTitle, setEditTitle] = useState(collection.title);
|
||||
const [editArticle, setEditArticle] = useState(collection.article);
|
||||
const [editIsPublic, setEditIsPublic] = useState(collection.isPublic);
|
||||
const [editLoading, setEditLoading] = useState(false);
|
||||
|
||||
const { t } = useTranslation();
|
||||
@@ -292,6 +300,7 @@ function EditCollectionDialog({
|
||||
collection.id,
|
||||
editTitle,
|
||||
editArticle,
|
||||
editIsPublic,
|
||||
);
|
||||
setEditLoading(false);
|
||||
if (res.success) {
|
||||
@@ -300,7 +309,12 @@ function EditCollectionDialog({
|
||||
if (getRes.success) {
|
||||
onSaved(getRes.data!);
|
||||
} else {
|
||||
onSaved({ ...collection, title: editTitle, article: editArticle });
|
||||
onSaved({
|
||||
...collection,
|
||||
title: editTitle,
|
||||
article: editArticle,
|
||||
isPublic: editIsPublic,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
showToast({
|
||||
@@ -325,11 +339,21 @@ function EditCollectionDialog({
|
||||
/>
|
||||
<label className="block mb-1">{t("Description")}</label>
|
||||
<textarea
|
||||
className="textarea w-full min-h-32"
|
||||
className="textarea w-full min-h-32 mb-2"
|
||||
value={editArticle}
|
||||
onChange={(e) => setEditArticle(e.target.value)}
|
||||
disabled={editLoading}
|
||||
/>
|
||||
<label className="flex items-center mb-4">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={editIsPublic}
|
||||
onChange={(e) => setEditIsPublic(e.target.checked)}
|
||||
className="checkbox mr-2"
|
||||
disabled={editLoading}
|
||||
/>
|
||||
{t("Public")}
|
||||
</label>
|
||||
<div className="modal-action">
|
||||
<button className="btn" onClick={onClose} disabled={editLoading}>
|
||||
{t("Cancel")}
|
||||
|
@@ -8,6 +8,7 @@ import { useNavigate } from "react-router";
|
||||
export default function CreateCollectionPage() {
|
||||
const [title, setTitle] = useState<string>("");
|
||||
const [article, setArticle] = useState<string>("");
|
||||
const [isPublic, setIsPublic] = useState<boolean>(true);
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
const [isUploadingimage, setUploadingImage] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
@@ -73,7 +74,7 @@ export default function CreateCollectionPage() {
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
const res = await network.createCollection(title, article);
|
||||
const res = await network.createCollection(title, article, isPublic);
|
||||
if (res.success) {
|
||||
showToast({
|
||||
message: t("Collection created successfully"),
|
||||
@@ -110,6 +111,17 @@ export default function CreateCollectionPage() {
|
||||
onChange={(e) => setArticle(e.target.value)}
|
||||
className="textarea mt-1 w-full min-h-80"
|
||||
/>
|
||||
<div className="mt-4">
|
||||
<label className="flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={isPublic}
|
||||
onChange={(e) => setIsPublic(e.target.checked)}
|
||||
className="checkbox mr-2"
|
||||
/>
|
||||
{t("Public")}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div className={"flex items-center mt-4"}>
|
||||
<button
|
||||
|
@@ -218,24 +218,25 @@ export default function ResourcePage() {
|
||||
</button>
|
||||
<Tags tags={resource.tags} />
|
||||
<p className={"px-3 mt-2"}>
|
||||
{resource.links && resource.links.map((l) => {
|
||||
return (
|
||||
<a href={l.url} target={"_blank"}>
|
||||
<span
|
||||
className={
|
||||
"py-1 px-3 inline-flex items-center m-1 border border-base-300 bg-base-100 opacity-90 rounded-2xl hover:bg-base-200 transition-colors cursor-pointer select-none"
|
||||
}
|
||||
>
|
||||
{l.url.includes("steampowered.com") ? (
|
||||
<BiLogoSteam size={20} />
|
||||
) : (
|
||||
<MdOutlineLink size={20} />
|
||||
)}
|
||||
<span className={"ml-2 text-sm"}>{l.label}</span>
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
{resource.links &&
|
||||
resource.links.map((l) => {
|
||||
return (
|
||||
<a href={l.url} target={"_blank"}>
|
||||
<span
|
||||
className={
|
||||
"py-1 px-3 inline-flex items-center m-1 border border-base-300 bg-base-100 opacity-90 rounded-2xl hover:bg-base-200 transition-colors cursor-pointer select-none"
|
||||
}
|
||||
>
|
||||
{l.url.includes("steampowered.com") ? (
|
||||
<BiLogoSteam size={20} />
|
||||
) : (
|
||||
<MdOutlineLink size={20} />
|
||||
)}
|
||||
<span className={"ml-2 text-sm"}>{l.label}</span>
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
<CollectionDialog rid={resource.id} />
|
||||
</p>
|
||||
|
||||
@@ -1637,7 +1638,7 @@ function CollectionDialog({ rid }: { rid: number }) {
|
||||
};
|
||||
|
||||
if (!app.isLoggedIn()) {
|
||||
return <></>
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -1683,13 +1684,16 @@ function CollectionDialog({ rid }: { rid: number }) {
|
||||
/>
|
||||
)}
|
||||
<div className="modal-action">
|
||||
<Button className="btn-ghost" onClick={() => {
|
||||
const dialog = document.getElementById(
|
||||
"collection_dialog",
|
||||
) as HTMLDialogElement;
|
||||
dialog.close();
|
||||
navigate("/create-collection");
|
||||
}}>
|
||||
<Button
|
||||
className="btn-ghost"
|
||||
onClick={() => {
|
||||
const dialog = document.getElementById(
|
||||
"collection_dialog",
|
||||
) as HTMLDialogElement;
|
||||
dialog.close();
|
||||
navigate("/create-collection");
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<MdOutlineAdd size={20} className={"inline-block mr-1"} />
|
||||
{t("Create")}
|
||||
|
@@ -413,15 +413,17 @@ function Collections({ username }: { username?: string }) {
|
||||
onChange={(e) => delayedSetSearchKeyword(e.target.value)}
|
||||
/>
|
||||
<span className="flex-1" />
|
||||
{username == app.user?.username && <button
|
||||
className="btn btn-primary btn-soft"
|
||||
onClick={() => {
|
||||
navigate("/create-collection");
|
||||
}}
|
||||
>
|
||||
<MdOutlineAdd size={20} className="inline-block mr-1" />
|
||||
{t("Create")}
|
||||
</button>}
|
||||
{username == app.user?.username && (
|
||||
<button
|
||||
className="btn btn-primary btn-soft"
|
||||
onClick={() => {
|
||||
navigate("/create-collection");
|
||||
}}
|
||||
>
|
||||
<MdOutlineAdd size={20} className="inline-block mr-1" />
|
||||
{t("Create")}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<CollectionsList
|
||||
username={username}
|
||||
@@ -522,6 +524,12 @@ function CollectionCard({ collection }: { collection: Collection }) {
|
||||
<MdOutlinePhotoAlbum size={16} className="inline-block" />
|
||||
{collection.resources_count} {t("Resources")}
|
||||
</Badge>
|
||||
<span className="flex-1" />
|
||||
{!collection.isPublic && (
|
||||
<Badge className="badge-soft badge-error text-xs mr-2">
|
||||
<MdOutlineAdd size={16} className="inline-block" /> {t("Private")}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
Reference in New Issue
Block a user