mirror of
https://github.com/usatiuk/photos.git
synced 2025-10-29 07:47:47 +01:00
some cleanup, split backend and frontend
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 ||
|
||||
|
||||
@@ -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[];
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
1
frontend/src/shared
Symbolic link
@@ -0,0 +1 @@
|
||||
../../shared
|
||||
Reference in New Issue
Block a user