mirror of
https://github.com/barthuijgen/factorio-sites.git
synced 2024-12-04 10:44:44 +02:00
Fix: my favorites link, date format, editing protection
This commit is contained in:
parent
d277adb856
commit
9da8a1bf6e
@ -1,10 +1,12 @@
|
||||
import { useState } from "react";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import { css } from "@emotion/react";
|
||||
import { BlueprintPage } from "@factorio-sites/types";
|
||||
import { format } from "date-fns";
|
||||
import { Box, Text } from "@chakra-ui/react";
|
||||
import { MdFavorite } from "react-icons/md";
|
||||
import { useState } from "react";
|
||||
import { BlueprintPage } from "@factorio-sites/types";
|
||||
import { getLocaleDateFormat } from "@factorio-sites/web-utils";
|
||||
|
||||
const linkStyles = css`
|
||||
margin: 5px 10px 5px 0;
|
||||
@ -51,11 +53,6 @@ const linkStyles = css`
|
||||
}
|
||||
`;
|
||||
|
||||
const formatDate = (datenum: number) => {
|
||||
const date = new Date(datenum * 1000);
|
||||
return date.toLocaleString();
|
||||
};
|
||||
|
||||
interface BlueprintLinkProps {
|
||||
blueprint: Pick<BlueprintPage, "id" | "title" | "image_hash" | "favorite_count" | "updated_at">;
|
||||
editLink?: boolean;
|
||||
@ -105,7 +102,7 @@ export const BlueprintLink: React.FC<BlueprintLinkProps> = ({
|
||||
</Box>
|
||||
{type === "row" && (
|
||||
<Box>
|
||||
<Text>{formatDate(blueprint.updated_at)}</Text>
|
||||
<Text>{format(blueprint.updated_at * 1000, getLocaleDateFormat(true))}</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { Box } from "@chakra-ui/react";
|
||||
import { format } from "date-fns";
|
||||
import Link from "next/link";
|
||||
import { BlueprintPage } from "@factorio-sites/types";
|
||||
import styled from "@emotion/styled";
|
||||
import { BlueprintPage } from "@factorio-sites/types";
|
||||
import { getLocaleDateFormat } from "@factorio-sites/web-utils";
|
||||
|
||||
const StyledBox = styled(Box)`
|
||||
dl {
|
||||
@ -49,12 +50,12 @@ export const BlueprintInfo: React.FC<BlueprintInfoProps> = ({ blueprint_page })
|
||||
<hr />
|
||||
<dl>
|
||||
<dt>Last updated:</dt>
|
||||
<dd>{format(new Date(blueprint_page.updated_at * 1000), "dd/mm/yyyy")}</dd>
|
||||
<dd>{format(new Date(blueprint_page.updated_at * 1000), getLocaleDateFormat())}</dd>
|
||||
</dl>
|
||||
<hr />
|
||||
<dl>
|
||||
<dt>Created:</dt>
|
||||
<dd>{format(new Date(blueprint_page.created_at * 1000), "dd/mm/yyyy")}</dd>
|
||||
<dd>{format(new Date(blueprint_page.created_at * 1000), getLocaleDateFormat())}</dd>
|
||||
</dl>
|
||||
<hr />
|
||||
<dl>
|
||||
|
@ -1,4 +1,9 @@
|
||||
import { createBlueprint, editBlueprintPage, createBlueprintBook } from "@factorio-sites/database";
|
||||
import {
|
||||
createBlueprint,
|
||||
editBlueprintPage,
|
||||
createBlueprintBook,
|
||||
getBlueprintPageById,
|
||||
} from "@factorio-sites/database";
|
||||
import { parseBlueprintString } from "@factorio-sites/node-utils";
|
||||
import { parseDatabaseError } from "../../../utils/api.utils";
|
||||
import { apiHandler } from "../../../utils/api-handler";
|
||||
@ -12,7 +17,13 @@ const handler = apiHandler(async (req, res, { session }) => {
|
||||
|
||||
const { id, title, description, string, tags } = req.body;
|
||||
|
||||
const parsed = await parseBlueprintString(string).catch(() => null);
|
||||
const existing = await getBlueprintPageById(id);
|
||||
if (!existing) {
|
||||
return res.status(404).json({ status: "Blueprint not found" });
|
||||
}
|
||||
if (existing?.user_id !== session.user_id) {
|
||||
return res.status(403).json({ status: "Unauthorised" });
|
||||
}
|
||||
|
||||
// Validation
|
||||
const errors: Record<string, string> = {};
|
||||
@ -20,6 +31,9 @@ const handler = apiHandler(async (req, res, { session }) => {
|
||||
if (!title) errors.title = "Required";
|
||||
if (!description) errors.description = "Required";
|
||||
if (!string) errors.string = "Required";
|
||||
|
||||
const parsed = await parseBlueprintString(string).catch(() => null);
|
||||
|
||||
if (!parsed) errors.string = "Not recognised as a blueprint string";
|
||||
|
||||
if (Object.keys(errors).length) {
|
||||
|
@ -28,7 +28,7 @@ export const UserBlueprints: NextPage<UserBlueprintsProps> = ({ blueprints }) =>
|
||||
</Box>
|
||||
<Box>
|
||||
{blueprints.length !== 0 ? (
|
||||
blueprints.map((bp) => <BlueprintLink key={bp.id} blueprint={bp} editLink type="row" />)
|
||||
blueprints.map((bp) => <BlueprintLink key={bp.id} blueprint={bp} type="row" />)
|
||||
) : (
|
||||
<p css={{ marginTop: "10px" }}>You don't have any favorites yet</p>
|
||||
)}
|
||||
|
@ -15,6 +15,7 @@ const mapBlueprintPageEntityToObject = (
|
||||
id: entity.id,
|
||||
blueprint_id: entity.blueprint_id ?? null,
|
||||
blueprint_book_id: entity.blueprint_book_id ?? null,
|
||||
user_id: entity.user_id,
|
||||
title: entity.title,
|
||||
description_markdown: entity.description_markdown || "",
|
||||
tags: entity.tags,
|
||||
@ -105,19 +106,27 @@ export async function searchBlueprintPages({
|
||||
conditionals.push(sqltag`blueprint_page.title ILIKE ${`%${query}%`}`);
|
||||
}
|
||||
if (entities) {
|
||||
conditionals.push(sqltag`blueprint.data -> 'entities' ?& array[${join(entities)}::text]`);
|
||||
const matchSql = mode === "AND" ? sqltag`?&` : sqltag`?|`;
|
||||
conditionals.push(
|
||||
sqltag`blueprint.data -> 'entities' ${matchSql} array[${join(entities)}::text]`
|
||||
);
|
||||
requires_blueprint_join = true;
|
||||
}
|
||||
if (items) {
|
||||
conditionals.push(sqltag`blueprint.data -> 'items' ?& array[${join(items)}::text]`);
|
||||
const matchSql = mode === "AND" ? sqltag`?&` : sqltag`?|`;
|
||||
conditionals.push(sqltag`blueprint.data -> 'items' ${matchSql} array[${join(items)}::text]`);
|
||||
requires_blueprint_join = true;
|
||||
}
|
||||
if (recipes) {
|
||||
conditionals.push(sqltag`blueprint.data -> 'recipes' ?& array[${join(recipes)}::text]`);
|
||||
const matchSql = mode === "AND" ? sqltag`?&` : sqltag`?|`;
|
||||
conditionals.push(
|
||||
sqltag`blueprint.data -> 'recipes' ${matchSql} array[${join(recipes)}::text]`
|
||||
);
|
||||
requires_blueprint_join = true;
|
||||
}
|
||||
if (tags) {
|
||||
conditionals.push(sqltag`blueprint_page.tags @> array[${join(tags)}::varchar]`);
|
||||
const matchSql = mode === "AND" ? sqltag`@>` : sqltag`&&`;
|
||||
conditionals.push(sqltag`blueprint_page.tags ${matchSql} array[${join(tags)}::varchar]`);
|
||||
}
|
||||
if (user) {
|
||||
conditionals.push(sqltag`blueprint_page.user_id = ${user}`);
|
||||
|
@ -45,6 +45,7 @@ export interface BlueprintPage {
|
||||
id: string;
|
||||
blueprint_id: string | null;
|
||||
blueprint_book_id: string | null;
|
||||
user_id: string | null;
|
||||
title: string;
|
||||
description_markdown: string;
|
||||
tags: string[];
|
||||
|
@ -116,3 +116,12 @@ export function chakraResponsive({
|
||||
const breakpoints = ["30em", "48em", "62em", "80em"];
|
||||
|
||||
export const mq = breakpoints.map((bp) => `@media (min-width: ${bp})`);
|
||||
|
||||
export function getLocaleDateFormat(withHours?: boolean) {
|
||||
const format = new Date(2013, 11, 31)
|
||||
.toLocaleDateString()
|
||||
.replace("31", "dd")
|
||||
.replace("12", "MM")
|
||||
.replace("2013", "yyyy");
|
||||
return withHours ? `${format} HH:mm` : format;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user