To create a login, registration, and ToDo application using PHP for the backend and React.js for the frontend, you would follow these steps:
Backend (PHP)
You'll create an API using PHP to handle the login, registration, and CRUD operations for the ToDo application.
1. Database Setup:
- Create a MySQL database, e.g.,
todoapp
. - Create two tables:
-
users
for storing user credentials. -
todos
for storing tasks.
-
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL
);
CREATE TABLE todos (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
task VARCHAR(255) NOT NULL,
completed BOOLEAN DEFAULT FALSE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
2. PHP API Endpoints:
Create a file named api.php
that will handle the backend logic.
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT');
header('Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With');
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "todoapp";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Get the request method
$method = $_SERVER['REQUEST_METHOD'];
$request = explode('/', trim($_SERVER['PATH_INFO'],'/'));
switch($request[0]) {
case 'register':
if ($method == 'POST') {
$data = json_decode(file_get_contents("php://input"), true);
$username = $data['username'];
$password = password_hash($data['password'], PASSWORD_DEFAULT);
$sql = "INSERT INTO users (username, password) VALUES ('$username', '$password')";
if ($conn->query($sql) === TRUE) {
echo json_encode(["message" => "User registered successfully!"]);
} else {
echo json_encode(["error" => "Error: " . $sql . "<br>" . $conn->error]);
}
}
break;
case 'login':
if ($method == 'POST') {
$data = json_decode(file_get_contents("php://input"), true);
$username = $data['username'];
$password = $data['password'];
$sql = "SELECT * FROM users WHERE username = '$username'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$user = $result->fetch_assoc();
if (password_verify($password, $user['password'])) {
echo json_encode(["message" => "Login successful!", "user_id" => $user['id']]);
} else {
echo json_encode(["error" => "Invalid password!"]);
}
} else {
echo json_encode(["error" => "User not found!"]);
}
}
break;
case 'todos':
if ($method == 'GET') {
$user_id = intval($request[1]);
$sql = "SELECT * FROM todos WHERE user_id = $user_id";
$result = $conn->query($sql);
$todos = [];
while($row = $result->fetch_assoc()) {
$todos[] = $row;
}
echo json_encode($todos);
} elseif ($method == 'POST') {
$data = json_decode(file_get_contents("php://input"), true);
$user_id = $data['user_id'];
$task = $data['task'];
$sql = "INSERT INTO todos (user_id, task) VALUES ($user_id, '$task')";
if ($conn->query($sql) === TRUE) {
echo json_encode(["message" => "Task added successfully!"]);
} else {
echo json_encode(["error" => "Error: " . $sql . "<br>" . $conn->error]);
}
} elseif ($method == 'PUT') {
$data = json_decode(file_get_contents("php://input"), true);
$id = intval($request[1]);
$task = $data['task'];
$completed = $data['completed'] ? 1 : 0;
$sql = "UPDATE todos SET task='$task', completed=$completed WHERE id=$id";
if ($conn->query($sql) === TRUE) {
echo json_encode(["message" => "Task updated successfully!"]);
} else {
echo json_encode(["error" => "Error: " . $sql . "<br>" . $conn->error]);
}
} elseif ($method == 'DELETE') {
$id = intval($request[1]);
$sql = "DELETE FROM todos WHERE id=$id";
if ($conn->query($sql) === TRUE) {
echo json_encode(["message" => "Task deleted successfully!"]);
} else {
echo json_encode(["error" => "Error: " . $sql . "<br>" . $conn->error]);
}
}
break;
default:
echo json_encode(["message" => "Invalid request"]);
break;
}
$conn->close();
?>
Frontend (React.js)
You would create a simple React.js application that interacts with the PHP API.
1. React Project Setup:
- Initialize a new React project.
- Set up React Router for navigation.
- Install Axios for making API calls.
npx create-react-app todo-app
cd todo-app
npm install axios react-router-dom
2. Login Component:
import React, { useState } from 'react';
import axios from 'axios';
const Login = ({ setUser }) => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleLogin = async (e) => {
e.preventDefault();
try {
const response = await axios.post('http://localhost/api.php/login', {
username,
password
});
setUser(response.data.user_id);
} catch (error) {
console.error("Login failed", error);
}
};
return (
<form onSubmit={handleLogin}>
<input type="text" value={username} onChange={(e) => setUsername(e.target.value)} placeholder="Username" required />
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Password" required />
<button type="submit">Login</button>
</form>
);
};
export default Login;
3. Register Component:
import React, { useState } from 'react';
import axios from 'axios';
const Register = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleRegister = async (e) => {
e.preventDefault();
try {
const response = await axios.post('http://localhost/api.php/register', {
username,
password
});
alert(response.data.message);
} catch (error) {
console.error("Registration failed", error);
}
};
return (
<form onSubmit={handleRegister}>
<input type="text" value={username} onChange={(e) => setUsername(e.target.value)} placeholder="Username" required />
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Password" required />
<button type="submit">Register</button>
</form>
);
};
export default Register;
4. Todo Component:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const TodoApp = ({ user }) => {
const [todos, setTodos] = useState([]);
const [task, setTask] = useState('');
useEffect(() => {
const fetchTodos = async () => {
try {
const response = await axios.get(`http://localhost/api.php/todos/${user}`);
setTodos(response.data);
} catch (error) {
console.error("Error fetching tasks", error);
}
};
fetchTodos();
}, [user]);
const addTask = async (e) => {
e.preventDefault();
try {
const response = await axios.post('http://localhost/api.php/todos', {
user_id: user,
task
});
setTask('');
setTodos([...todos, response.data]);
} catch (error) {
console.error("Error adding task", error);
}
};
const toggleComplete = async (id, completed) => {
try {
await axios.put(`http://localhost/api.php/todos/${id}`, {
completed: !completed
});
setTodos(todos.map(todo => todo.id === id ? { ...todo, completed: !completed } : todo));
} catch (error) {
console.error("Error updating task", error);
}
};
const deleteTask = async (id) => {
try {
await axios.delete(`http://localhost/api.php/todos/${id}`);
setTodos(todos.filter(todo => todo.id !== id));
} catch (error) {
console.error("Error deleting task", error);
}
};
return (
<div>
<h2>Your Todo List</h2>
<form onSubmit={addTask}>
<input
type="text"
value={task}
onChange={(e) => setTask(e.target.value)}
placeholder="New Task"
required
/>
<button type="submit">Add Task</button>
</form>
<ul>
{todos.map((todo) => (
<li key={todo.id}>
<span
style={{
textDecoration: todo.completed ? 'line-through' : 'none'
}}
onClick={() => toggleComplete(todo.id, todo.completed)}
>
{todo.task}
</span>
<button onClick={() => deleteTask(todo.id)}>Delete</button>
</li>
))}
</ul>
</div>
);
};
export default TodoApp;
5. App Component and Routing:
import React, { useState } from 'react';
import { BrowserRouter as Router, Route, Routes, Link } from 'react-router-dom';
import Login from './Login';
import Register from './Register';
import TodoApp from './TodoApp';
const App = () => {
const [user, setUser] = useState(null);
return (
<Router>
<nav>
<Link to="/">Login</Link>
<Link to="/register">Register</Link>
{user && <Link to="/todos">TodoApp</Link>}
</nav>
<Routes>
<Route path="/" element={<Login setUser={setUser} />} />
<Route path="/register" element={<Register />} />
{user && <Route path="/todos" element={<TodoApp user={user} />} />}
</Routes>
</Router>
);
};
export default App;
6. Running the Application:
-
Backend:
- Make sure your Apache server is running (or any other server that supports PHP).
- Place your
api.php
file in the appropriate directory (e.g.,htdocs
if using XAMPP). - Ensure the MySQL database and tables are created as described.
-
Frontend:
- Start your React application:
npm start
- Your React app should now be running at
http://localhost:3000
.
7. Testing the Application:
-
Register: Go to
/register
, create a new user. - Login: After registering, log in with the newly created user.
- Todo App: After logging in, access the todo list, add, update, and delete tasks.
Summary
You've now set up a full-stack application with a PHP backend for handling user registration, login, and CRUD operations on a ToDo list, and a React.js frontend to interact with these API endpoints. This setup gives you a basic structure to build upon, adding more features as required.
Top comments (0)