Europa docs: From local dev to CI environment doc page
The todoapp example contains a Netlify plan which uses the latest dagger additions: do & Client API. We are thinking of merging the examples repository into this one to make working with this easier. This is a step in that direction. We are not using the yarn package so that we can revert https://github.com/dagger/dagger/pull/1673 without breaking this implementation. The GitHub Action is WIP, we will continue with that tomorrow: https://github.com/dagger/dagger-for-github/issues/24 Signed-off-by: Gerhard Lazu <gerhard@lazu.co.uk>
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
|
||||
function FilterButton(props) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className="btn toggle-btn"
|
||||
aria-pressed={props.isPressed}
|
||||
onClick={() => props.setFilter(props.name)}
|
||||
>
|
||||
<span className="visually-hidden">Show </span>
|
||||
<span>{props.name}</span>
|
||||
<span className="visually-hidden"> tasks</span>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export default FilterButton;
|
@@ -0,0 +1,45 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
function Form(props) {
|
||||
const [name, setName] = useState('');
|
||||
|
||||
|
||||
function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
if (!name.trim()) {
|
||||
return;
|
||||
}
|
||||
props.addTask(name);
|
||||
setName("");
|
||||
}
|
||||
|
||||
|
||||
function handleChange(e) {
|
||||
setName(e.target.value);
|
||||
}
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<h2 className="label-wrapper">
|
||||
<label htmlFor="new-todo-input" className="label__lg">
|
||||
What needs to be done?
|
||||
</label>
|
||||
</h2>
|
||||
|
||||
<input
|
||||
type="text"
|
||||
id="new-todo-input"
|
||||
className="input input__lg"
|
||||
name="text"
|
||||
autoComplete="off"
|
||||
value={name}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<button type="submit" className="btn btn__primary btn__lg">
|
||||
Add
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
export default Form;
|
113
pkg/universe.dagger.io/examples/todoapp/src/components/Todo.js
Normal file
113
pkg/universe.dagger.io/examples/todoapp/src/components/Todo.js
Normal file
@@ -0,0 +1,113 @@
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
|
||||
|
||||
function usePrevious(value) {
|
||||
const ref = useRef();
|
||||
useEffect(() => {
|
||||
ref.current = value;
|
||||
});
|
||||
return ref.current;
|
||||
}
|
||||
|
||||
export default function Todo(props) {
|
||||
const [isEditing, setEditing] = useState(false);
|
||||
const [newName, setNewName] = useState('');
|
||||
|
||||
const editFieldRef = useRef(null);
|
||||
const editButtonRef = useRef(null);
|
||||
|
||||
const wasEditing = usePrevious(isEditing);
|
||||
|
||||
function handleChange(e) {
|
||||
setNewName(e.target.value);
|
||||
}
|
||||
|
||||
function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
if (!newName.trim()) {
|
||||
return;
|
||||
}
|
||||
props.editTask(props.id, newName);
|
||||
setNewName("");
|
||||
setEditing(false);
|
||||
}
|
||||
|
||||
const editingTemplate = (
|
||||
<form className="stack-small" onSubmit={handleSubmit}>
|
||||
<div className="form-group">
|
||||
<label className="todo-label" htmlFor={props.id}>
|
||||
New name for {props.name}
|
||||
</label>
|
||||
<input
|
||||
id={props.id}
|
||||
className="todo-text"
|
||||
type="text"
|
||||
value={newName || props.name}
|
||||
onChange={handleChange}
|
||||
ref={editFieldRef}
|
||||
/>
|
||||
</div>
|
||||
<div className="btn-group">
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="btn todo-cancel"
|
||||
onClick={() => setEditing(false)}
|
||||
>
|
||||
Cancel
|
||||
<span className="visually-hidden">renaming {props.name}</span>
|
||||
</button>
|
||||
<button type="submit" className="btn btn__primary todo-edit">
|
||||
Save
|
||||
<span className="visually-hidden">new name for {props.name}</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
|
||||
const viewTemplate = (
|
||||
<div className="stack-small">
|
||||
<div className="c-cb">
|
||||
<input
|
||||
id={props.id}
|
||||
type="checkbox"
|
||||
defaultChecked={props.completed}
|
||||
onChange={() => props.toggleTaskCompleted(props.id)}
|
||||
/>
|
||||
<label className="todo-label" htmlFor={props.id}>
|
||||
{props.name}
|
||||
</label>
|
||||
</div>
|
||||
<div className="btn-group">
|
||||
<button
|
||||
type="button"
|
||||
className="btn"
|
||||
onClick={() => setEditing(true)}
|
||||
ref={editButtonRef}
|
||||
>
|
||||
Edit <span className="visually-hidden">{props.name}</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn__danger"
|
||||
onClick={() => props.deleteTask(props.id)}
|
||||
>
|
||||
Delete <span className="visually-hidden">{props.name}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (!wasEditing && isEditing) {
|
||||
editFieldRef.current.focus();
|
||||
}
|
||||
if (wasEditing && !isEditing) {
|
||||
editButtonRef.current.focus();
|
||||
}
|
||||
}, [wasEditing, isEditing]);
|
||||
|
||||
|
||||
return <li className="todo">{isEditing ? editingTemplate : viewTemplate}</li>;
|
||||
}
|
Reference in New Issue
Block a user