todo riot, avec router
This commit is contained in:
@@ -105,6 +105,5 @@ Le modèle utilise PDO, en php. Il vous faudra créér une table avec les attrib
|
|||||||
1. Complétez le fichier index.php
|
1. Complétez le fichier index.php
|
||||||
2. Testez votre api à la ligne de commandes en utilisant `curl`.
|
2. Testez votre api à la ligne de commandes en utilisant `curl`.
|
||||||
3. Connectez votre application todolist avec l'api.
|
3. Connectez votre application todolist avec l'api.
|
||||||
|
4. Connectez votre api à l'application [todo](./src/todo-riot). Il faut
|
||||||
Écrivez un module "abstrait" en javascript pour l'interaction
|
complétez le fichier api.js. Prenez soin de modifier le fichier `htaccess`.
|
||||||
avec l'api. Ce module devra pouvoir être changer pour utiliser firebase **sans que l'application cliente ne change**.
|
|
||||||
|
|||||||
74
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/app.riot
Normal file
74
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/app.riot
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<app>
|
||||||
|
<router base = {base}>
|
||||||
|
<route path="/:filter?"
|
||||||
|
on-before-mount = { changeFilter }
|
||||||
|
on-before-update = { changeFilter }
|
||||||
|
>
|
||||||
|
|
||||||
|
<h1>To Do List</h1>
|
||||||
|
|
||||||
|
<todo-form
|
||||||
|
add = { add } />
|
||||||
|
|
||||||
|
<todo-nav
|
||||||
|
selection = {state.filter}
|
||||||
|
left = {this.state.todos.filter(todo => !todo.done).length} />
|
||||||
|
|
||||||
|
<todo-list
|
||||||
|
todos = { filterTodos() }
|
||||||
|
toggle = { toggle }
|
||||||
|
remove = { remove } />
|
||||||
|
|
||||||
|
</route>
|
||||||
|
</router>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
base : '/~denis/web_2024/tp5/todo-riot/', // Votre URL
|
||||||
|
state : {
|
||||||
|
todos : [],
|
||||||
|
filter : 'all'
|
||||||
|
},
|
||||||
|
changeFilter(r){
|
||||||
|
this.state.filter = r.params.filter || 'all'
|
||||||
|
},
|
||||||
|
|
||||||
|
async onBeforeMount(props, state) {
|
||||||
|
let todos = await this.serviceData.getTodos()
|
||||||
|
this.state.todos = todos;
|
||||||
|
this.update()
|
||||||
|
},
|
||||||
|
filterTodos(){
|
||||||
|
|
||||||
|
if (this.state.filter === 'all')
|
||||||
|
return this.state.todos
|
||||||
|
|
||||||
|
if (this.state.filter === 'active')
|
||||||
|
return this.state.todos.filter(e=> !e.done)
|
||||||
|
|
||||||
|
if (this.state.filter === 'done')
|
||||||
|
return this.state.todos.filter(e=> e.done)
|
||||||
|
},
|
||||||
|
async remove(e,todo){
|
||||||
|
e.preventDefault()
|
||||||
|
let res = await this.serviceData.removeTodo(todo)
|
||||||
|
let todos = await this.serviceData.getTodos()
|
||||||
|
this.state.todos = todos
|
||||||
|
this.update()
|
||||||
|
},
|
||||||
|
|
||||||
|
async add(text) {
|
||||||
|
let res = await this.serviceData.addTodo({title : text , done : false})
|
||||||
|
let todos = await this.serviceData.getTodos()
|
||||||
|
this.state.todos = todos
|
||||||
|
this.update()
|
||||||
|
},
|
||||||
|
|
||||||
|
async toggle(todo) {
|
||||||
|
let res = await this.serviceData.toggleTodo(todo);
|
||||||
|
let todos = await this.serviceData.getTodos()
|
||||||
|
this.state.todos = todos
|
||||||
|
this.update()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</app>
|
||||||
16
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/css/todo.css
Normal file
16
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/css/todo.css
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
p.todo {
|
||||||
|
display : flex;
|
||||||
|
justify-content : space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.done {
|
||||||
|
text-decoration: line-through;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
.is-active {
|
||||||
|
color : #8EB901;
|
||||||
|
}
|
||||||
|
.delete {
|
||||||
|
background-color :#9B2318;
|
||||||
|
}
|
||||||
|
|
||||||
8
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/htaccess
Normal file
8
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/htaccess
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<IfModule mod_rewrite.c>
|
||||||
|
RewriteEngine On
|
||||||
|
RewriteBase /~denis/web_2024/tp5/todo-riot/ # votre url
|
||||||
|
RewriteRule ^index\.html$ - [L]
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
RewriteCond %{REQUEST_FILENAME} !-d
|
||||||
|
RewriteRule . index.html [L]
|
||||||
|
</IfModule>
|
||||||
56
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/index.html
Normal file
56
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/index.html
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<!doctype html>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Riot todo</title>
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<base href="/~denis/web_2024/tp5/todo-riot/">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/riot@10.0.0/riot+compiler.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@riotjs/route@10.0.0/index.umd.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="css/todo.css">
|
||||||
|
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
|
||||||
|
>
|
||||||
|
<!-- composants riot -->
|
||||||
|
|
||||||
|
<script src="app.riot" type="riot"></script>
|
||||||
|
<script src="todo-list.riot" type="riot"></script>
|
||||||
|
<script src="todo-nav.riot" type="riot"></script>
|
||||||
|
<script src="todo-form.riot" type="riot"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<main class="container">
|
||||||
|
<app />
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
|
||||||
|
import makeDataService from "./js/api.js";
|
||||||
|
|
||||||
|
riot.register('router', route.Router);
|
||||||
|
riot.register('route', route.Route);
|
||||||
|
|
||||||
|
riot.compile().then(async () => {
|
||||||
|
|
||||||
|
let sa = makeDataService();
|
||||||
|
|
||||||
|
riot.install(function(component){
|
||||||
|
if (component.name === "app")
|
||||||
|
component.serviceData = sa;
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
riot.mount('app')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
45
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/js/api.js
Normal file
45
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/js/api.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
export default function makeDataService(){
|
||||||
|
let url = 'http://localhost/~denis/web_2024/tp5/api_php/todo/'
|
||||||
|
let service = {
|
||||||
|
getTodos : getTodos,
|
||||||
|
addTodo : addTodo,
|
||||||
|
removeTodo : removeTodo,
|
||||||
|
toggleTodo : toggleTodo,
|
||||||
|
};
|
||||||
|
|
||||||
|
async function getTodos()
|
||||||
|
{
|
||||||
|
let res = await fetch(url,{
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
;
|
||||||
|
let json = await res.json();
|
||||||
|
return json.results;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
async function addTodo(todo)
|
||||||
|
{
|
||||||
|
const response = await fetch(url, {
|
||||||
|
headers: {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(todo)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function removeTodo(todo)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
async function toggleTodo(todo)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
return service;
|
||||||
|
}
|
||||||
31
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/todo-form.riot
Normal file
31
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/todo-form.riot
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<todo-form>
|
||||||
|
<form onsubmit = { add }>
|
||||||
|
<fieldset role="group">
|
||||||
|
<input type="text" placeholder="Buy milk and eggs..." oninput = { edit }>
|
||||||
|
<button disabled = { !state.text } ><i class="fas fa-plus"></i></button>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
state : {
|
||||||
|
text:''
|
||||||
|
},
|
||||||
|
|
||||||
|
edit(e) {
|
||||||
|
// update only the text state
|
||||||
|
this.state.text = e.target.value
|
||||||
|
this.update()
|
||||||
|
},
|
||||||
|
add(e) {
|
||||||
|
e.preventDefault()
|
||||||
|
this.props.add(this.state.text);
|
||||||
|
},
|
||||||
|
clear(e){
|
||||||
|
e.preventDefault();
|
||||||
|
this.props.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</todo-form>
|
||||||
17
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/todo-list.riot
Normal file
17
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/todo-list.riot
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<todo-list>
|
||||||
|
<article>
|
||||||
|
<div each={ todo in props.todos } key={todo.id}>
|
||||||
|
<p class="todo">
|
||||||
|
<label class={ todo.done ? 'completed' : null }>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
checked={ todo.done }
|
||||||
|
onclick={ () => props.toggle(todo) } />
|
||||||
|
<span class = {todo.done ? 'done':''}> { todo.title } </span>
|
||||||
|
</label>
|
||||||
|
<a href="#" onclick={(e)=>props.remove(e,todo)}><i class="fa-solid fa-trash"></i></a>
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</todo-list>
|
||||||
12
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/todo-nav.riot
Normal file
12
R4.01_R4.A.10/td_tp/tp6/src/todo-riot/todo-nav.riot
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<todo-nav>
|
||||||
|
<nav>
|
||||||
|
<ul>
|
||||||
|
<li><a class={props.selection === 'active'?'is-active':null} href="active"><i class="far fa-circle"></i></a></li>
|
||||||
|
<li><a class={props.selection === 'done'?'is-active':null} href="done"><i class="fas fa-circle"></i></a></li>
|
||||||
|
<li><a class={props.selection === 'all'?'is-active':null} href="all"><i class="fas fa-adjust"></i></a></li>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li>{props.left} todos left</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</todo-nav>
|
||||||
Reference in New Issue
Block a user