mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-26 13:17:15 -05:00
Error if saving a profile without widgets
This commit is contained in:
@@ -22,6 +22,8 @@
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: var(--s-2);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import { Link, useFetcher, useLoaderData, useMatches } from "react-router";
|
||||
import * as R from "remeda";
|
||||
import * as v from "valibot";
|
||||
import { SendouButton } from "~/components/elements/Button";
|
||||
import { FormMessage } from "~/components/FormMessage";
|
||||
import { Image } from "~/components/Image";
|
||||
import { Input } from "~/components/Input";
|
||||
import { MainSlotIcon } from "~/components/icons/MainSlot";
|
||||
@@ -69,6 +70,7 @@ export default function EditWidgetsPage() {
|
||||
Array<Tables["UserWidget"]["widget"]>
|
||||
>(data.currentWidgets);
|
||||
const [expandedWidgetId, setExpandedWidgetId] = useState<string | null>(null);
|
||||
const [emptySaveAttempted, setEmptySaveAttempted] = useState(false);
|
||||
|
||||
const hasUnsavedChangesRef = useRef<
|
||||
Parameters<typeof useUnsavedChangesChecker>[0]["current"]
|
||||
@@ -144,6 +146,11 @@ export default function EditWidgetsPage() {
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (selectedWidgets.length === 0) {
|
||||
setEmptySaveAttempted(true);
|
||||
return;
|
||||
}
|
||||
|
||||
const invalidWidgetIds = computeInvalidWidgetIds(selectedWidgets);
|
||||
const firstInvalid = selectedWidgets.find((w) =>
|
||||
invalidWidgetIds.has(w.id),
|
||||
@@ -198,6 +205,11 @@ export default function EditWidgetsPage() {
|
||||
<SendouButton onClick={handleSubmit}>
|
||||
{t("common:actions.save")}
|
||||
</SendouButton>
|
||||
{emptySaveAttempted && selectedWidgets.length === 0 ? (
|
||||
<FormMessage type="error" spaced={false}>
|
||||
{t("user:widgets.emptyError")}
|
||||
</FormMessage>
|
||||
) : null}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
@@ -11,4 +11,12 @@ describe("widgetsEditSchema", () => {
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
test("rejects an empty widget list", () => {
|
||||
const result = v.safeParse(widgetsEditSchema(false), {
|
||||
widgets: JSON.stringify([]),
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -177,6 +177,7 @@ export const widgetsEditSchema = (isSupporter: boolean) => {
|
||||
safeJSONParse,
|
||||
v.pipe(
|
||||
v.array(widgetSettingsSchema),
|
||||
v.minLength(1),
|
||||
v.maxLength(max.main + max.side),
|
||||
v.check((widgets) => {
|
||||
let mainCount = 0;
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
"widgets.add": "",
|
||||
"widgets.remove": "",
|
||||
"widgets.maxReached": "",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "",
|
||||
"widgets.category.misc": "",
|
||||
"widgets.category.trophies": "",
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
"widgets.add": "",
|
||||
"widgets.remove": "",
|
||||
"widgets.maxReached": "",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "",
|
||||
"widgets.category.misc": "",
|
||||
"widgets.category.trophies": "",
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
"widgets.add": "Add",
|
||||
"widgets.remove": "Remove",
|
||||
"widgets.maxReached": "Maximum widgets reached",
|
||||
"widgets.emptyError": "Your profile needs at least one widget",
|
||||
"widgets.search": "Search widgets...",
|
||||
"widgets.category.misc": "Miscellaneous",
|
||||
"widgets.category.trophies": "Trophies",
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
"widgets.add": "Añadir",
|
||||
"widgets.remove": "Quitar",
|
||||
"widgets.maxReached": "Límite máximo de widgets alcanzado",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "Buscar widgets...",
|
||||
"widgets.category.misc": "Miscelánea",
|
||||
"widgets.category.trophies": "Trofeos",
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
"widgets.add": "Añadir",
|
||||
"widgets.remove": "Quitar",
|
||||
"widgets.maxReached": "Límite máximo de widgets alcanzado",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "Buscar widgets...",
|
||||
"widgets.category.misc": "Miscelánea",
|
||||
"widgets.category.trophies": "Trofeos",
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
"widgets.add": "",
|
||||
"widgets.remove": "",
|
||||
"widgets.maxReached": "",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "",
|
||||
"widgets.category.misc": "",
|
||||
"widgets.category.trophies": "",
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
"widgets.add": "",
|
||||
"widgets.remove": "",
|
||||
"widgets.maxReached": "",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "",
|
||||
"widgets.category.misc": "",
|
||||
"widgets.category.trophies": "",
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
"widgets.add": "",
|
||||
"widgets.remove": "",
|
||||
"widgets.maxReached": "",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "",
|
||||
"widgets.category.misc": "",
|
||||
"widgets.category.trophies": "",
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
"widgets.add": "",
|
||||
"widgets.remove": "",
|
||||
"widgets.maxReached": "",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "",
|
||||
"widgets.category.misc": "",
|
||||
"widgets.category.trophies": "",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"widgets.add": "",
|
||||
"widgets.remove": "",
|
||||
"widgets.maxReached": "",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "",
|
||||
"widgets.category.misc": "",
|
||||
"widgets.category.trophies": "",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"widgets.add": "",
|
||||
"widgets.remove": "",
|
||||
"widgets.maxReached": "",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "",
|
||||
"widgets.category.misc": "",
|
||||
"widgets.category.trophies": "",
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
"widgets.add": "",
|
||||
"widgets.remove": "",
|
||||
"widgets.maxReached": "",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "",
|
||||
"widgets.category.misc": "",
|
||||
"widgets.category.trophies": "",
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
"widgets.add": "",
|
||||
"widgets.remove": "",
|
||||
"widgets.maxReached": "",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "",
|
||||
"widgets.category.misc": "",
|
||||
"widgets.category.trophies": "",
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
"widgets.add": "",
|
||||
"widgets.remove": "",
|
||||
"widgets.maxReached": "",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "",
|
||||
"widgets.category.misc": "",
|
||||
"widgets.category.trophies": "",
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
"widgets.add": "",
|
||||
"widgets.remove": "",
|
||||
"widgets.maxReached": "",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "",
|
||||
"widgets.category.misc": "",
|
||||
"widgets.category.trophies": "",
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"widgets.add": "添加",
|
||||
"widgets.remove": "移除",
|
||||
"widgets.maxReached": "已达到小组件上限",
|
||||
"widgets.emptyError": "",
|
||||
"widgets.search": "搜索小组件...",
|
||||
"widgets.category.misc": "其他",
|
||||
"widgets.category.trophies": "",
|
||||
|
||||
Reference in New Issue
Block a user