Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions templates/backend-and-client/base44/agents/task_manager.jsonc

This file was deleted.

16 changes: 0 additions & 16 deletions templates/backend-and-client/base44/entities/task.jsonc

This file was deleted.

16 changes: 0 additions & 16 deletions templates/backend-and-client/components.json

This file was deleted.

1 change: 0 additions & 1 deletion templates/backend-and-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
},
"dependencies": {
"@base44/sdk": "^0.8.3",
"lucide-react": "^0.475.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
146 changes: 4 additions & 142 deletions templates/backend-and-client/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,147 +1,9 @@
import { useState, useEffect } from "react";
import { base44 } from "@/api/base44Client";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Base44Logo } from "@/components/Base44Logo";
import { Plus, Trash2, CheckCircle2 } from "lucide-react";

const Task = base44.entities.Task;

export default function App() {
const [tasks, setTasks] = useState([]);
const [newTaskTitle, setNewTaskTitle] = useState("");
const [isLoading, setIsLoading] = useState(true);

const fetchTasks = async () => {
const data = await Task.list();
setTasks(data);
setIsLoading(false);
};

useEffect(() => {
fetchTasks();
}, []);

const handleSubmit = async (e) => {
e.preventDefault();
if (!newTaskTitle.trim()) return;
await Task.create({ title: newTaskTitle.trim(), completed: false });
setNewTaskTitle("");
fetchTasks();
};

const toggleTask = async (id, completed) => {
await Task.update(id, { completed });
fetchTasks();
};

const deleteTask = async (id) => {
await Task.delete(id);
fetchTasks();
};

const clearCompleted = async () => {
await Promise.all(
tasks.filter((t) => t.completed).map((t) => Task.delete(t.id))
);
fetchTasks();
};

const completedCount = tasks.filter((t) => t.completed).length;
const totalCount = tasks.length;

return (
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-white to-orange-50/30">
<div className="max-w-lg mx-auto px-6 py-16">
{/* Header */}
<div className="text-center mb-12">
<h1 className="text-3xl font-semibold text-slate-900 tracking-tight">
<span className="inline-flex items-center gap-2 align-middle">
<Base44Logo className="w-9 h-9" />
<span className="font-bold">Base44</span>
<span>Tasks</span>
</span>
</h1>
{totalCount > 0 && (
<p className="text-slate-500 mt-2 text-sm">
{completedCount} of {totalCount} completed
</p>
)}
</div>

{/* Add Task Form */}
<form onSubmit={handleSubmit} className="mb-8">
<div className="flex gap-3">
<Input
type="text"
value={newTaskTitle}
onChange={(e) => setNewTaskTitle(e.target.value)}
placeholder="What needs to be done?"
className="flex-1 h-12 bg-white border-slate-200 rounded-xl shadow-sm"
/>
<Button
type="submit"
disabled={!newTaskTitle.trim()}
className="h-12 px-5 rounded-xl bg-slate-900 hover:bg-slate-800 shadow-sm"
>
<Plus className="w-5 h-5" />
</Button>
</div>
</form>

{/* Task List */}
<div className="space-y-2">
{isLoading ? (
<div className="flex items-center justify-center py-12">
<div className="w-6 h-6 border-2 border-slate-200 border-t-orange-500 rounded-full animate-spin" />
</div>
) : tasks.length === 0 ? (
<div className="text-center py-12">
<p className="text-slate-400">No tasks yet. Add one above!</p>
</div>
) : (
tasks.map((task) => (
<div
key={task.id}
className="group flex items-center gap-4 p-4 bg-white rounded-xl border border-slate-100 shadow-sm hover:shadow-md transition-all duration-200"
>
<Checkbox
checked={task.completed}
onCheckedChange={(checked) => toggleTask(task.id, checked)}
className="w-5 h-5 rounded-md border-slate-300 data-[state=checked]:bg-orange-500 data-[state=checked]:border-orange-500"
/>
<span
className={`flex-1 text-slate-700 transition-all ${
task.completed ? "line-through text-slate-400" : ""
}`}
>
{task.title}
</span>
<Button
variant="ghost"
size="icon"
onClick={() => deleteTask(task.id)}
className="opacity-0 group-hover:opacity-100 h-8 w-8 text-slate-400 hover:text-red-500 hover:bg-red-50 transition-all"
>
<Trash2 className="w-4 h-4" />
</Button>
</div>
))
)}
</div>

{/* Footer */}
{completedCount > 0 && (
<div className="mt-8 text-center">
<button
onClick={clearCompleted}
className="text-sm text-slate-400 hover:text-slate-600 transition-colors"
>
Clear completed
</button>
</div>
)}
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-white to-orange-50/30 flex items-center justify-center">
<div className="text-center">
<h1 className="text-4xl font-bold text-slate-900 mb-4">Hello World</h1>
<p className="text-slate-500">Welcome to your Base44 app</p>
</div>
</div>
);
Expand Down
15 changes: 0 additions & 15 deletions templates/backend-and-client/src/components/Base44Logo.jsx

This file was deleted.

23 changes: 0 additions & 23 deletions templates/backend-and-client/src/components/ui/button.jsx

This file was deleted.

20 changes: 0 additions & 20 deletions templates/backend-and-client/src/components/ui/checkbox.jsx

This file was deleted.

13 changes: 0 additions & 13 deletions templates/backend-and-client/src/components/ui/input.jsx

This file was deleted.

28 changes: 2 additions & 26 deletions templates/backend-and-client/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,12 @@
@tailwind components;
@tailwind utilities;

@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;
--radius: 0.5rem;
}
}

@layer base {
* {
@apply border-border;
}

body {
@apply bg-background text-foreground antialiased;
}
}
}