mirror of
https://github.com/rjNemo/react_template
synced 2026-06-06 07:56:41 +00:00
refresh
This commit is contained in:
parent
a9a0365b25
commit
473f437fcf
15 changed files with 3710 additions and 3309 deletions
19
package.json
19
package.json
|
|
@ -3,17 +3,16 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/client": "^3.2.5",
|
"@apollo/client": "^3.3.19",
|
||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^5.12.0",
|
||||||
"@testing-library/react": "^9.3.2",
|
"@testing-library/react": "^11.2.7",
|
||||||
"@testing-library/user-event": "^7.1.2",
|
"@testing-library/user-event": "^13.1.9",
|
||||||
"graphql": "^15.3.0",
|
"graphql": "^15.5.0",
|
||||||
"immer": "^9.0.0",
|
"react": "^17.0.2",
|
||||||
"react": "^17.0.0",
|
"react-dom": "^17.0.2",
|
||||||
"react-dom": "^17.0.0",
|
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-scripts": "3.4.4",
|
"react-scripts": "^4.0.3",
|
||||||
"styled-components": "^5.2.0"
|
"styled-components": "^5.3.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
|
|
||||||
123
schema.graphql
123
schema.graphql
|
|
@ -1,61 +1,144 @@
|
||||||
# This file was generated based on ".graphqlconfig". Do not edit manually.
|
# This file was generated based on ".graphqlconfig". Do not edit manually.
|
||||||
|
|
||||||
schema {
|
schema {
|
||||||
query: TodoQuery
|
query: Query
|
||||||
mutation: Mutations
|
mutation: Mutation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"Response interface"
|
||||||
|
interface ResponseField {
|
||||||
|
errorMessage: String
|
||||||
|
isSuccess: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
"Assign an existing task to an existing user"
|
||||||
|
type AssignTodoToUser {
|
||||||
|
result: ResponseField
|
||||||
|
}
|
||||||
|
|
||||||
|
"Close an existing task"
|
||||||
type CloseTodo {
|
type CloseTodo {
|
||||||
todo: TodoType
|
result: TodoResponseField
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"Create a new task."
|
||||||
type CreateTodo {
|
type CreateTodo {
|
||||||
todo: TodoType
|
result: TodoResponseField
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"Register an user"
|
||||||
|
type CreateUser {
|
||||||
|
result: UserResponseField
|
||||||
|
}
|
||||||
|
|
||||||
|
"Deassign an existing task from an existing user"
|
||||||
|
type DeassignTodoToUser {
|
||||||
|
result: ResponseField
|
||||||
|
}
|
||||||
|
|
||||||
|
"Delete an existing task"
|
||||||
type DeleteTodo {
|
type DeleteTodo {
|
||||||
todo: TodoType
|
result: TodoResponseField
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mutations {
|
"Unregister an existing user"
|
||||||
|
type DeleteUser {
|
||||||
|
result: UserResponseField
|
||||||
|
}
|
||||||
|
|
||||||
|
type Mutation {
|
||||||
|
"Assign an existing task to an existing user"
|
||||||
|
assignTodoToUser(todoId: String, userId: String): AssignTodoToUser
|
||||||
|
"Close an existing task"
|
||||||
closeTodo(todoId: String!): CloseTodo
|
closeTodo(todoId: String!): CloseTodo
|
||||||
createTodo(title: String = ""): CreateTodo
|
"Create a new task."
|
||||||
|
createTodo(title: String!): CreateTodo
|
||||||
|
"Register an user"
|
||||||
|
createUser(username: String): CreateUser
|
||||||
|
"Deassign an existing task from an existing user"
|
||||||
|
deassignTodoToUser(todoId: String, userId: String): DeassignTodoToUser
|
||||||
|
"Delete an existing task"
|
||||||
deleteTodo(todoId: String!): DeleteTodo
|
deleteTodo(todoId: String!): DeleteTodo
|
||||||
|
"Unregister an existing user"
|
||||||
|
deleteUser(userId: String!): DeleteUser
|
||||||
|
"Update an existing task"
|
||||||
updateTodo(todo: TodoInputType): UpdateTodo
|
updateTodo(todo: TodoInputType): UpdateTodo
|
||||||
|
"Update user information"
|
||||||
|
updateUser(user: UserInputType): UpdateUser
|
||||||
}
|
}
|
||||||
|
|
||||||
type TodoListResponseField {
|
type Query {
|
||||||
|
"Retrieve an existing tasks"
|
||||||
|
getTodo(todoId: String!): TodoResponseField
|
||||||
|
"Retrieve a registered user"
|
||||||
|
getUser(userId: String!): UserResponseField
|
||||||
|
"List existing tasks"
|
||||||
|
listTodos: TodoListResponseField
|
||||||
|
"List registered users"
|
||||||
|
listUsers: UserListResponseField
|
||||||
|
}
|
||||||
|
|
||||||
|
"Todos list response object"
|
||||||
|
type TodoListResponseField implements ResponseField {
|
||||||
errorMessage: String
|
errorMessage: String
|
||||||
isSuccess: Boolean
|
isSuccess: Boolean
|
||||||
todos: [TodoType]
|
todos: [TodoType]
|
||||||
}
|
}
|
||||||
|
|
||||||
"Defines the query and how to interact with"
|
"Todo response object"
|
||||||
type TodoQuery {
|
type TodoResponseField implements ResponseField {
|
||||||
getTodo(todoId: String!): TodoResponseField
|
|
||||||
listTodos: TodoListResponseField
|
|
||||||
}
|
|
||||||
|
|
||||||
type TodoResponseField {
|
|
||||||
errorMessage: String
|
errorMessage: String
|
||||||
isSuccess: Boolean
|
isSuccess: Boolean
|
||||||
todo: TodoType
|
todo: TodoType
|
||||||
}
|
}
|
||||||
|
|
||||||
"Query Object Type"
|
"Todo Object Type"
|
||||||
type TodoType {
|
type TodoType {
|
||||||
isDone: Boolean
|
isDone: Boolean
|
||||||
title: String
|
title: String
|
||||||
todoId: String
|
todoId: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"Update an existing task"
|
||||||
type UpdateTodo {
|
type UpdateTodo {
|
||||||
todo: TodoType
|
result: TodoResponseField
|
||||||
}
|
}
|
||||||
|
|
||||||
"Mutation Input Object Type"
|
"Update user information"
|
||||||
|
type UpdateUser {
|
||||||
|
result: UserResponseField
|
||||||
|
}
|
||||||
|
|
||||||
|
"User list response object"
|
||||||
|
type UserListResponseField implements ResponseField {
|
||||||
|
errorMessage: String
|
||||||
|
isSuccess: Boolean
|
||||||
|
users: [UserType]
|
||||||
|
}
|
||||||
|
|
||||||
|
"User response object"
|
||||||
|
type UserResponseField implements ResponseField {
|
||||||
|
errorMessage: String
|
||||||
|
isSuccess: Boolean
|
||||||
|
user: UserType
|
||||||
|
}
|
||||||
|
|
||||||
|
"User schema type"
|
||||||
|
type UserType {
|
||||||
|
tasks: [TodoType]
|
||||||
|
userId: String
|
||||||
|
username: String
|
||||||
|
}
|
||||||
|
|
||||||
|
"Todo Input Object"
|
||||||
input TodoInputType {
|
input TodoInputType {
|
||||||
isDone: Boolean = false
|
isDone: Boolean
|
||||||
title: String = ""
|
title: String
|
||||||
todoId: String
|
todoId: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"User input object"
|
||||||
|
input UserInputType {
|
||||||
|
userId: String
|
||||||
|
username: String
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,6 @@ import App from './App';
|
||||||
|
|
||||||
test('renders learn react link', () => {
|
test('renders learn react link', () => {
|
||||||
const { getByText } = render(<App />);
|
const { getByText } = render(<App />);
|
||||||
const linkElement = getByText(/learn react/i);
|
const linkElement = getByText(/Your tasks/i);
|
||||||
expect(linkElement).toBeInTheDocument();
|
expect(linkElement).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import React, { FC } from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Router from './Router';
|
import Router from './Router';
|
||||||
import { Layout } from './components/layout';
|
import { Layout } from './components/layout';
|
||||||
|
|
||||||
const App: FC = () => (
|
const App = () => (
|
||||||
<Layout>
|
<Layout>
|
||||||
<Router />
|
<Router />
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import React, { FC } from 'react';
|
import React from 'react';
|
||||||
import { Route, Switch } from 'react-router-dom';
|
import { Route, Switch } from 'react-router-dom';
|
||||||
|
|
||||||
import { About } from './components/About';
|
import { About } from './containers/about';
|
||||||
import { Home } from './containers/home';
|
import { Home } from './containers/home';
|
||||||
|
|
||||||
const Router: FC = () => (
|
const Router = () => (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/">
|
<Route exact path="/">
|
||||||
<Home />
|
<Home />
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
import React, { FC } from 'react';
|
|
||||||
|
|
||||||
import profileImg from '../assets/about/profile.jpg';
|
|
||||||
|
|
||||||
export const About: FC = () => (
|
|
||||||
<div>
|
|
||||||
<h1>About</h1>
|
|
||||||
<div>
|
|
||||||
<img src={profileImg} alt="profile" width="100%" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import React, { FC } from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import logo from '../assets/logo.svg';
|
import logo from '../assets/logo.svg';
|
||||||
|
|
||||||
export const Header: FC = () => (
|
export const Header = () => (
|
||||||
<header>
|
<header>
|
||||||
<nav>
|
<nav>
|
||||||
<img src={logo} alt="logo" width="50px" />
|
<img src={logo} alt="logo" width="50px" />
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
import styled, { css } from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
|
|
||||||
interface ButtonProps {
|
type ButtonProps = {
|
||||||
readonly primary: boolean;
|
readonly primary: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const Button = styled.button<ButtonProps>`
|
export const Button = styled.button<ButtonProps>`
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import React from 'react';
|
import React, { FC } from 'react';
|
||||||
import { FC } from 'react';
|
|
||||||
|
|
||||||
import { Header } from './Header';
|
import { Header } from './Header';
|
||||||
|
|
||||||
|
|
|
||||||
12
src/containers/about/index.tsx
Normal file
12
src/containers/about/index.tsx
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import profileImg from '../../assets/about/profile.jpg';
|
||||||
|
|
||||||
|
export const About = () => (
|
||||||
|
<div>
|
||||||
|
<h1>About</h1>
|
||||||
|
<div>
|
||||||
|
<img src={profileImg} alt="profile" width="100%" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import React, { FC, memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
|
|
||||||
import Todo from '../../core/models/todo';
|
import Todo from '../../core/models/todo';
|
||||||
|
|
||||||
interface Props {
|
type Props = {
|
||||||
todos: Todo[];
|
todos: Todo[];
|
||||||
}
|
};
|
||||||
|
|
||||||
const TodoList: FC<Props> = ({ todos }) => (
|
const TodoList = ({ todos }: Props) => (
|
||||||
<div>
|
<div>
|
||||||
<ul>
|
<ul>
|
||||||
{todos.map((todo) => (
|
{todos.map((todo) => (
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
import React, { ChangeEvent, FC, FormEvent, useState } from 'react';
|
import React, { ChangeEvent, FormEvent, useState } from 'react';
|
||||||
|
|
||||||
import TodoList from './TodoList';
|
import TodoList from './TodoList';
|
||||||
import { Button } from '../../components/button';
|
import { Button } from '../../components/button';
|
||||||
import { Container } from '../../components/container';
|
import { Container } from '../../components/container';
|
||||||
|
|
||||||
import { useListTodos } from '../../core/services/listTodo';
|
|
||||||
import { useCreateTodo } from '../../core/services/createTodo';
|
import { useCreateTodo } from '../../core/services/createTodo';
|
||||||
|
import { useListTodos } from '../../core/services/listTodo';
|
||||||
|
|
||||||
export const Home: FC = () => {
|
export const Home = () => {
|
||||||
const [todoTitle, setTodoTitle] = useState<string>('');
|
const [todoTitle, setTodoTitle] = useState<string>('');
|
||||||
const { loading, error, data } = useListTodos();
|
const { loading, error, data } = useListTodos();
|
||||||
const { createTodo } = useCreateTodo(todoTitle);
|
const { createTodo } = useCreateTodo(todoTitle);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue