Skip to content

Commit

Permalink
SPA (#5)
Browse files Browse the repository at this point in the history
* Add SPA
  • Loading branch information
evanilukhin authored Oct 13, 2019
1 parent d88d4d8 commit 79e6544
Show file tree
Hide file tree
Showing 21 changed files with 629 additions and 114 deletions.
6 changes: 0 additions & 6 deletions app/javascript/channels/consumer.js

This file was deleted.

5 changes: 0 additions & 5 deletions app/javascript/channels/index.js

This file was deleted.

25 changes: 25 additions & 0 deletions app/javascript/components/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react'
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";

import People from "./People";
import Person from "./Person";
import PersonEdit from "./PersonEdit";
import PersonCreate from "./PersonCreate";

export default function App() {
return (
<Router>
<Switch>
<Route path="/people/:id/edit" component={PersonEdit}/>
<Route path="/people/create" component={PersonCreate}/>
<Route path="/people/:id" component={Person}/>
<Route path="/" component={People}/>
</Switch>
</Router>
)
}
15 changes: 15 additions & 0 deletions app/javascript/components/People.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'
import Table from "./People/Table";
import {Link} from "react-router-dom";

class People extends React.Component {
render() {
return (
<div>
<Table/>
<Link to={'/people/create'}> Создать пользователя </Link>
</div>
)
}
}
export default People
85 changes: 85 additions & 0 deletions app/javascript/components/People/Table.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React from 'react'
import {Link} from 'react-router-dom';
import axios from 'axios'

// Table for people with links
class Table extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
items: []
};
}

handleClick = userId => {
axios.delete('/api/v1/people/' + userId)
.then((response) => {
alert('Пользователь успешно удалён');
this.componentDidMount();
})
.catch((error) => {
alert(error);
});
};


componentDidMount() {
axios.get('/api/v1/people')
.then((response) => {
this.setState({
isLoaded: true,
items: response.data
});
})
.catch((error) => {
this.setState({
isLoaded: true,
error
});
});
}

render() {
const {error, isLoaded, items} = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<table>
<thead>
<tr>
<th> Имя</th>
<th> Фамилия</th>
<th> Отчество</th>
<th> ФИО</th>
<th> Пол</th>
<th> Действия</th>
</tr>
</thead>
<tbody>
{items.map(item => (
<tr key={item.id}>
<td>{item.first_name}</td>
<td>{item.last_name}</td>
<td>{item.middle_name}</td>
<td>{item.full_name}</td>
<td>{item.sex_name}</td>
<td>
<Link to={'/people/' + item.id}>Показать</Link>
<Link to={'/people/' + item.id + '/edit'}>Редактировать</Link>
<button onClick={() => { this.handleClick(item.id) }}>Удалить</button>
</td>
</tr>
))}
</tbody>
</table>
);
}
}
}

export default Table
73 changes: 73 additions & 0 deletions app/javascript/components/Person.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from 'react'
import axios from "axios";
import {Link} from "react-router-dom";

class Person extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
person: null
};
}

componentDidMount() {
const {match: {params}} = this.props;
axios.get(`/api/v1/people/${params.id}`)
.then((response) => {
this.setState({
isLoaded: true,
person: response.data
});
})
.catch((error) => {
this.setState({
isLoaded: true,
error
});
});
}

render() {
const {error, isLoaded, person} = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<div>
<div> <b> Пользователь: </b> {person.full_name} </div>
<div> <b> Пол: </b> {person.sex_name} </div>
<Link to={'/people/' + person.id + '/edit'}>Редактировать</Link>
<table>
<thead>
<tr>
<th> Имя</th>
<th> Фамилия</th>
<th> Отчество</th>
<th> ФИО</th>
<th> Падеж </th>
</tr>
</thead>
<tbody>
{person.declensions.map(declension => (
<tr key={declension.name_case}>
<td>{declension.first_name}</td>
<td>{declension.last_name}</td>
<td>{declension.middle_name}</td>
<td>{declension.full_name}</td>
<td>{declension.name_case}</td>
</tr>
))}
</tbody>
</table>
<Link to='/'> 🡐 на главную </Link>
</div>
);
}
}
}

export default Person
58 changes: 58 additions & 0 deletions app/javascript/components/PersonCreate.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react'
import {Link} from "react-router-dom";
import {Formik, Field} from "formik";
import axios from "axios";

class PersonCreate extends React.Component {

submitForm = (values, _) => {
axios.post('/api/v1/people', {
person: {
first_name: values.first_name,
last_name: values.last_name,
middle_name: values.middle_name,
sex: values.sex || null
}
})
.then((response) => {
alert(`Пользователь ${response.data.full_name} успешно создан`);
})
.catch((error) => {
alert(
'Здесь должна происходить корректная обработка ошибок с бэка:\n' +
JSON.stringify(error.response.data, null, 2)
);
});
};

render() {
return (
<div>
<h1>Создание пользователя</h1>
<Formik
initialValues={{ first_name: 'Ивааан' }}
onSubmit={(values, actions) => {this.submitForm(values, actions)}}
render={props => (
<form onSubmit={props.handleSubmit}>
<label htmlFor="first_name"> Имя </label>
<Field name="first_name" placeholder="Имя(обязательное поле)"/>
<label htmlFor="last_name"> Фамилия </label>
<Field name="last_name"/>
<label htmlFor="middle_name"> Отчество </label>
<Field name="middle_name"/>
<label htmlFor="sex"> Пол </label>
<Field name="sex" component="select" defaultValue=''>
<option value=''>Не задан</option>
<option value="male">Мужской</option>
<option value="female">Женский</option>
</Field>
<button type="submit">Создать</button>
</form>
)}
/>
<Link to='/'> 🡐 на главную </Link>
</div>
)
}
}
export default PersonCreate
100 changes: 100 additions & 0 deletions app/javascript/components/PersonEdit.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import React from 'react'
import {Link} from "react-router-dom";
import {Formik, Field} from "formik";
import axios from "axios";

class PersonEdit extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
isLoaded: false,
person: null
};
}

componentDidMount() {
const {match: {params}} = this.props;
axios.get(`/api/v1/people/${params.id}`)
.then((response) => {
this.setState({
isLoaded: true,
person: response.data
});
})
.catch((error) => {
this.setState({
isLoaded: true,
error
});
});
}

submitForm = (values, _) => {
axios.patch(`/api/v1/people/${this.state.person.id}`, {
person: {
first_name: values.first_name,
last_name: values.last_name,
middle_name: values.middle_name,
sex: values.sex || null
}
})
.then((response) => {
alert(`Пользователь ${response.data.full_name} успешно обновлён`);
})
.catch((error) => {
alert(
'Здесь должна происходить корректная обработка ошибок с бэка:\n' +
JSON.stringify(error.response.data, null, 2)
);
});
};

render() {
const {error, isLoaded, person} = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<div>
<h1>Изменение пользователя</h1>
<Formik
initialValues={
{
first_name: person.first_name,
middle_name: person.middle_name,
last_name: person.last_name,
sex: person.sex
}
}
onSubmit={(values, actions) => {
this.submitForm(values, actions)
}}
render={props => (
<form onSubmit={props.handleSubmit}>
<label htmlFor="first_name"> Имя </label>
<Field name="first_name" placeholder="Имя(обязательное поле)"/>
<label htmlFor="last_name"> Фамилия </label>
<Field name="last_name"/>
<label htmlFor="middle_name"> Отчество </label>
<Field name="middle_name"/>
<label htmlFor="sex"> Пол </label>
<Field name="sex" component="select" defaultValue=''>
<option value=''>Не задан</option>
<option value="male">Мужской</option>
<option value="female">Женский</option>
</Field>
<button type="submit">Обновить</button>
</form>
)}
/>
<Link to='/'> 🡐 на главную </Link>
</div>
)
}
}
}

export default PersonEdit
3 changes: 0 additions & 3 deletions app/javascript/packs/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
// that code so it'll be compiled.

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")


// Uncomment to copy all static images under ../images to the output folder and reference
Expand Down
Loading

0 comments on commit 79e6544

Please sign in to comment.