diff --git a/.gitignore b/.gitignore
index 70ba85b..bddaeda 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
.env
__pycache__/
*.py[cod]
+.vscode/*
\ No newline at end of file
diff --git a/client/src/App.js b/client/src/App.js
index 281352b..e34fe38 100644
--- a/client/src/App.js
+++ b/client/src/App.js
@@ -1,30 +1,62 @@
-import React from 'react';
+import React, {useEffect, useState} from 'react';
import { BrowserRouter, Switch, Route, NavLink } from 'react-router-dom';
import UserList from './components/UsersList';
-
+import UserForm from './components/UserForm';
+import AuthContext from './auth'
function App() {
+ const [fetchWithCSRF, setFetchWithCSRF] = useState(() => fetch);
+ const authContextValue = {
+ fetchWithCSRF,
+ };
+ useEffect(() => {
+ async function restoreCSRF() {
+ const response = await fetch('/api/csrf/restore', {
+ method: 'GET',
+ credentials: 'include'
+ });
+ if (response.ok) {
+ const authData = await response.json();
+ setFetchWithCSRF(() => {
+ return (resource, init) => {
+ if (init.headers) {
+ init.headers['X-CSRFToken'] = authData.csrf_token;
+ } else {
+ init.headers = {
+ 'X-CSRFToken': authData.csrf_token
+ }
+ }
+ return fetch(resource, init);
+ }
+ });
+ }
+ }
+ restoreCSRF();
+ }, []);
return (
-
-
-
-
-
-
-
-
- My Home Page
-
-
-
+
+
+
+
+
+
+
+
+
+ My Home Page
+
+
+
+
);
}
-export default App;
+export default App;
\ No newline at end of file
diff --git a/client/src/auth.js b/client/src/auth.js
new file mode 100644
index 0000000..082e4fe
--- /dev/null
+++ b/client/src/auth.js
@@ -0,0 +1,5 @@
+import React from 'react';
+
+const AuthContext = React.createContext({});
+
+export default AuthContext;
\ No newline at end of file
diff --git a/client/src/components/User.js b/client/src/components/User.js
index 7684d78..ad115f5 100644
--- a/client/src/components/User.js
+++ b/client/src/components/User.js
@@ -1,11 +1,17 @@
-import React from 'react';
-
+import React, {} from 'react';
+import { Link } from 'react-router-dom';
function User(props) {
return (
<>
Username: {props.user.username}
Email: {props.user.email}
+ Edit
>
);
diff --git a/client/src/components/UserForm.js b/client/src/components/UserForm.js
new file mode 100644
index 0000000..21a62c4
--- /dev/null
+++ b/client/src/components/UserForm.js
@@ -0,0 +1,56 @@
+import React, {useState, useContext} from 'react';
+import AuthContext from '../auth'
+
+function UserForm(props) {
+ const { id } = props.location.state.user;
+ console.log(id)
+ const [username, setUsername] = useState(props.location.state.user.username);
+ const [email, setEmail] = useState(props.location.state.user.email);
+
+ const [errors, setErrors] = useState([]);
+ const {fetchWithCSRF} = useContext(AuthContext);
+
+ const submitForm = (e) => {
+ e.preventDefault();
+
+ async function updateUser() {
+ const response = await fetchWithCSRF(`/api/users/${id}`, {
+ method: 'POST',
+ headers: {
+ "Content-Type": "application/json",
+ },
+ credentials: 'include',
+ body: JSON.stringify({
+ username,
+ email
+ })
+ });
+
+ const responseData = await response.json();
+ if (!response.ok) {
+ setErrors(responseData.errors);
+ }
+ }
+ updateUser();
+ }
+ return (
+
+ );
+}
+export default UserForm;
\ No newline at end of file
diff --git a/client/src/components/UsersList.js b/client/src/components/UsersList.js
index c458245..2090077 100644
--- a/client/src/components/UsersList.js
+++ b/client/src/components/UsersList.js
@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useState, createContext } from 'react';
import User from './User';
@@ -13,7 +13,6 @@ function UsersList (props) {
}
fetchData();
}, []);
-
const userComponents = users.map((user) => )
return (
<>
diff --git a/starter_app/__init__.py b/starter_app/__init__.py
index edb283d..f1d5b49 100644
--- a/starter_app/__init__.py
+++ b/starter_app/__init__.py
@@ -12,6 +12,7 @@
app = Flask(__name__)
app.config.from_object(Config)
+CSRFProtect(app)
app.register_blueprint(user_routes, url_prefix='/api/users')
db.init_app(app)
@@ -34,3 +35,6 @@ def react_root(path):
if path == 'favicon.ico':
return app.send_static_file('favicon.ico')
return app.send_static_file('index.html')
+@app.route('/api/csrf/restore')
+def restore_csrf():
+ return {'csrf_token': generate_csrf()}
diff --git a/starter_app/api/user_routes.py b/starter_app/api/user_routes.py
index b6fd740..2838a11 100644
--- a/starter_app/api/user_routes.py
+++ b/starter_app/api/user_routes.py
@@ -3,7 +3,13 @@
user_routes = Blueprint('users', __name__)
+
@user_routes.route('/')
def index():
- response = User.query.all()
- return { "users": [user.to_dict() for user in response]}
\ No newline at end of file
+ response = User.query.all()
+ return {"users": [user.to_dict() for user in response]}
+
+
+@user_routes.route('/', methods=['GET', 'POST'])
+def user_detail(id):
+ return {}
\ No newline at end of file