some cleanup, split backend and frontend

This commit is contained in:
2023-07-29 13:04:26 +02:00
parent 14210cf0cf
commit faa0aa62c8
69 changed files with 13194 additions and 12319 deletions

View File

@@ -1,6 +1,5 @@
import { Position, Toaster } from "@blueprintjs/core";
import { isNumber } from "class-validator";
import { IPhotoReqJSON } from "../../src/entity/Photo";
import { IPhotoReqJSON } from "./shared/types";
export const AppToaster = Toaster.create({
className: "recipe-toaster",

View File

@@ -2,29 +2,24 @@ import "./Home.scss";
import {
Alignment,
Breadcrumbs,
Button,
Classes,
IBreadcrumbProps,
Icon,
Menu,
MenuItem,
Navbar,
Popover,
Spinner,
} from "@blueprintjs/core";
import * as React from "react";
import { connect } from "react-redux";
import { Route, RouteComponentProps, Switch, withRouter } from "react-router";
import { animated, config, Transition } from "react-spring/renderprops";
import { Dispatch } from "redux";
import { IUserJSON } from "../../../src/entity/User";
import { IUserJSON } from "../shared/types";
import { Account } from "../Account/Account";
import { Overview } from "../Photos/Overview";
import { toggleDarkMode } from "../redux/localSettings/actions";
import { IAppState } from "../redux/reducers";
import { logoutUser } from "../redux/user/actions";
import { Photo } from "../Photos/Photo";
import { PhotoRoute } from "../Photos/PhotoRoute";
import { UploadStatus } from "./UploadStatus";
@@ -95,28 +90,24 @@ export class HomeComponent extends React.PureComponent<IHomeProps> {
transform: "translate3d(400px,0,0)",
}}
>
{(_location: any) => (style: any) =>
(
<animated.div
style={style}
className="viewComponent"
>
<Switch location={_location}>
<Route
path="/account"
component={Account}
/>
<Route
path="/photos/:id"
component={PhotoRoute}
/>
<Route
path="/"
component={Overview}
/>
</Switch>
</animated.div>
)}
{(_location: any) => (style: any) => (
<animated.div
style={style}
className="viewComponent"
>
<Switch location={_location}>
<Route
path="/account"
component={Account}
/>
<Route
path="/photos/:id"
component={PhotoRoute}
/>
<Route path="/" component={Overview} />
</Switch>
</animated.div>
)}
</Transition>
</div>
</div>

View File

@@ -1,4 +1,4 @@
import { Button, Icon, Popover, Spinner } from "@blueprintjs/core";
import { Button } from "@blueprintjs/core";
import * as React from "react";
import { connect } from "react-redux";
import { IAppState } from "../redux/reducers";
@@ -12,9 +12,9 @@ export interface IUploadStatusComponentProps {
uploadingQueue: number;
}
export const UploadStatusComponent: React.FunctionComponent<IUploadStatusComponentProps> = (
props,
) => {
export const UploadStatusComponent: React.FunctionComponent<
IUploadStatusComponentProps
> = (props) => {
const { creatingNow, creatingQueue, uploadingNow, uploadingQueue } = props;
const uploading =
creatingNow > 0 ||

View File

@@ -3,20 +3,18 @@ import "./Overview.scss";
import * as React from "react";
import { connect } from "react-redux";
import { Dispatch } from "redux";
import { IAppState } from "../redux/reducers";
import { IAppState } from "~/src/redux/reducers";
import {
photosDeleteCancel,
photosDeleteStart,
photosLoadStart,
} from "../redux/photos/actions";
import { IPhotoReqJSON } from "../../../src/entity/Photo";
import { LoadingStub } from "../LoadingStub";
import { IPhotoReqJSON } from "~/src/shared/types";
import { PhotoCard } from "./PhotoCard";
import {
Alignment,
Button,
Classes,
H1,
H2,
H3,
Navbar,
@@ -25,8 +23,7 @@ import {
} from "@blueprintjs/core";
import { UploadButton } from "./UploadButton";
import { Photo } from "./Photo";
import { getPhotoThumbPath } from "../redux/api/photos";
import { showDeletionToast } from "../AppToaster";
import { showDeletionToast } from "~/src/AppToaster";
export interface IOverviewComponentProps {
photos: IPhotoReqJSON[];

View File

@@ -2,13 +2,9 @@ import "./Photo.scss";
import * as React from "react";
import { connect } from "react-redux";
import { Dispatch } from "redux";
import { IPhotoReqJSON } from "../../../src/entity/Photo";
import { IPhotoReqJSON } from "~/src/shared/types";
import { LoadingStub } from "../LoadingStub";
import {
fetchPhoto,
getPhotoImgPath,
getPhotoThumbPath,
} from "../redux/api/photos";
import { getPhotoImgPath, getPhotoThumbPath } from "../redux/api/photos";
import { photoLoadStart } from "../redux/photos/actions";
import { IPhotoState } from "../redux/photos/reducer";
import { IAppState } from "../redux/reducers";

View File

@@ -8,15 +8,14 @@ import {
Spinner,
} from "@blueprintjs/core";
import * as React from "react";
import { IPhotoReqJSON } from "../../../src/entity/Photo";
import { getPhotoImgPath, getPhotoThumbPath } from "../redux/api/photos";
import { IPhotoReqJSON } from "~/src/shared/types";
import { getPhotoThumbPath } from "../redux/api/photos";
import { showDeletionToast } from "../AppToaster";
import { Dispatch } from "redux";
import { photosDeleteCancel, photosDeleteStart } from "../redux/photos/actions";
import { connect } from "react-redux";
import { LoadingStub } from "../LoadingStub";
import { RouteComponentProps, withRouter } from "react-router";
import { LargeSize, PreviewSize } from "./helper";
import { PreviewSize } from "./helper";
export interface IPhotoCardComponentProps extends RouteComponentProps {
photo: IPhotoReqJSON;

View File

@@ -1,7 +1,4 @@
import {
IUserLoginRespBody,
IUserSignupRespBody,
} from "../../../../../src/routes/users";
import { IUserLoginRespBody, IUserSignupRespBody } from "~/src/shared/types";
import { fetchJSON } from "../utils";
export async function login(

View File

@@ -1,12 +1,12 @@
import { IPhotoReqJSON } from "../../../../src/entity/Photo";
import { IPhotoReqJSON } from "~/src/shared/types";
import {
IPhotosByIDGetRespBody,
IPhotosDeleteRespBody,
IPhotosListRespBody,
IPhotosNewRespBody,
IPhotosUploadRespBody,
} from "../../../../src/routes/photos";
import { apiRoot } from "../../env";
} from "~/src/shared/types";
import { apiRoot } from "~src/env";
import { fetchJSONAuth } from "./utils";
export function getPhotoImgPath(photo: IPhotoReqJSON): string {

View File

@@ -1,10 +1,11 @@
import { fetchJSONAuth } from "../utils";
import { IUserEditRespBody, IUserGetRespBody } from "../../../../../src/routes/users";
import { IUserEditRespBody, IUserGetRespBody } from "~/src/shared/types";
export async function fetchUser(): Promise<IUserGetRespBody> {
return (fetchJSONAuth("/users/user", "GET") as unknown) as Promise<
IUserGetRespBody
>;
return fetchJSONAuth(
"/users/user",
"GET",
) as unknown as Promise<IUserGetRespBody>;
}
export async function changeUserPassword(

View File

@@ -1,4 +1,5 @@
import { apiRoot } from "../../env";
import { apiRoot } from "~src/env";
import { IAPIResponse } from "~/src/shared/types";
let token: string | null;
@@ -14,12 +15,12 @@ export function deleteToken(): void {
token = null;
}
export async function fetchJSON(
export async function fetchJSON<T>(
path: string,
method: string,
body?: string | Record<string, unknown> | File,
headers?: Record<string, string>,
): Promise<Record<string, unknown>> {
): Promise<IAPIResponse<T>> {
if (typeof body === "object" && !(body instanceof File)) {
body = JSON.stringify(body);
headers = {
@@ -27,7 +28,7 @@ export async function fetchJSON(
"Content-Type": "application/json",
};
}
// TODO: io-ts or something like that
if (body instanceof File) {
const formData = new FormData();
formData.append("photo", body);
@@ -37,7 +38,7 @@ export async function fetchJSON(
body: formData,
});
const json = (await response.json()) as Record<string, unknown>;
return json;
return json as unknown as IAPIResponse<T>;
}
const response = await fetch(apiRoot + path, {
@@ -46,15 +47,15 @@ export async function fetchJSON(
headers,
});
const json = (await response.json()) as Record<string, unknown>;
return json;
return json as unknown as IAPIResponse<T>;
}
export async function fetchJSONAuth(
export async function fetchJSONAuth<T>(
path: string,
method: string,
body?: string | Record<string, unknown> | File,
headers?: Record<string, unknown>,
): Promise<Record<string, unknown>> {
): Promise<IAPIResponse<T>> {
if (token) {
return fetchJSON(path, method, body, {
...headers,

View File

@@ -1,5 +1,5 @@
import { Action } from "redux";
import { IUserAuthJSON } from "../../../../src/entity/User";
import { IUserAuthJSON } from "~/src/shared/types";
export enum AuthTypes {
AUTH_START = "AUTH_START",

View File

@@ -1,7 +1,7 @@
import { Reducer } from "react";
import { setToken } from "../../redux/api/utils";
import { UserAction, UserTypes } from "../../redux/user/actions";
import { setToken } from "~src/redux/api/utils";
import { UserAction, UserTypes } from "~src/redux/user/actions";
import { AuthAction, AuthTypes } from "./actions";
export interface IAuthState {

View File

@@ -8,7 +8,7 @@ import {
race,
takeLatest,
} from "redux-saga/effects";
import { login, signup } from "../../redux/api/auth";
import { login, signup } from "~src/redux/api/auth";
import {
authFail,

View File

@@ -1,5 +1,5 @@
import { Reducer } from "react";
import { UserAction, UserTypes } from "../../redux/user/actions";
import { UserAction, UserTypes } from "~src/redux/user/actions";
import { LocalSettingsAction, LocalSettingsTypes } from "./actions";

View File

@@ -1,10 +1,10 @@
import { Action } from "redux";
import { IPhotoReqJSON, Photo } from "../../../../src/entity/Photo";
import { IPhotoReqJSON } from "~src/shared/types";
import {
showPhotoCreateFailToast,
showPhotoUploadFileFailToast,
showPhotoUploadJSONFailToast,
} from "../../AppToaster";
} from "~src/AppToaster";
export enum PhotoTypes {
PHOTOS_LOAD_START = "PHOTOS_LOAD",

View File

@@ -1,6 +1,6 @@
import { Reducer } from "redux";
import { IPhotoJSON, IPhotoReqJSON } from "../../../../src/entity/Photo";
import { UserAction, UserTypes } from "../../redux/user/actions";
import { IPhotoReqJSON } from "~/src/shared/types";
import { UserAction, UserTypes } from "~src/redux/user/actions";
import { PhotoAction, PhotoTypes } from "./actions";
export interface IPhotoState {

View File

@@ -1,9 +1,7 @@
import {
all,
call,
cancel,
delay,
fork,
put,
race,
takeLatest,
@@ -18,7 +16,7 @@ import {
fetchPhoto,
fetchPhotosList,
uploadPhoto,
} from "../../redux/api/photos";
} from "~src/redux/api/photos";
import {
IPhotosDeleteStartAction,
IPhotoLoadStartAction,
@@ -35,14 +33,12 @@ import {
photosLoadSuccess,
photosStartFetchingSpinner,
PhotoTypes,
photoUploadFail,
photoUploadFailWithFile,
photoUploadQueue,
photoUploadStart,
photoUploadSuccess,
} from "./actions";
import { IPhotosNewRespBody } from "../../../../src/routes/photos";
import { IPhotosListPagination } from "../../../../src/shared/types";
import { IPhotosNewRespBody, IPhotosListPagination } from "~src/shared/types";
// Thanks, https://dev.to/qortex/compute-md5-checksum-for-a-file-in-typescript-59a4
function computeChecksumMd5(file: File): Promise<string> {

View File

@@ -1,6 +1,9 @@
import { Action } from "redux";
import { IUserAuthJSON, IUserJSON } from "../../../../src/entity/User";
import { showPasswordNotSavedToast, showPasswordSavedToast } from "../../AppToaster";
import { IUserAuthJSON } from "~src/shared/types";
import {
showPasswordNotSavedToast,
showPasswordSavedToast,
} from "~src/AppToaster";
export enum UserTypes {
USER_GET = "USER_GET",

View File

@@ -1,6 +1,6 @@
import { Reducer } from "react";
import { IUserJSON } from "../../../../src/entity/User";
import { AuthAction, AuthTypes } from "../../redux/auth/actions";
import { IUserJSON } from "~/src/entity/User";
import { AuthAction, AuthTypes } from "~src/redux/auth/actions";
import { UserAction, UserTypes } from "./actions";
export interface IUserState {

View File

@@ -1,5 +1,5 @@
import { all, call, delay, put, race, takeLatest } from "redux-saga/effects";
import { changeUserPassword, fetchUser } from "../../redux/api/user";
import { changeUserPassword, fetchUser } from "~src/redux/api/user";
import {
getUserFail,

1
frontend/src/shared Symbolic link
View File

@@ -0,0 +1 @@
../../shared