work work work
This commit is contained in:
parent
1dd5084cc9
commit
26a1a0fc0c
@ -3,7 +3,7 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Habit;
|
use App\Models\Habit;
|
||||||
use App\Models\HabitEntry;
|
use App\Models\Entry;
|
||||||
use Carbon\CarbonPeriod;
|
use Carbon\CarbonPeriod;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
|
||||||
|
38
app/Http/Controllers/EntryController.php
Normal file
38
app/Http/Controllers/EntryController.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class EntryController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
return view('entries.create');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store($request)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function show($id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function edit($id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(Request $request, $id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -1,47 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Http\Resources\HabitResource;
|
|
||||||
use App\Models\Habit;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
|
|
||||||
class HabitApiController extends Controller
|
|
||||||
{
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
return HabitResource::collection(Habit::all());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'name' => ['required', 'string'],
|
|
||||||
]);
|
|
||||||
|
|
||||||
return new HabitResource(Habit::create($validated));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function show(Habit $habit)
|
|
||||||
{
|
|
||||||
return new HabitResource($habit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(Request $request, Habit $habit)
|
|
||||||
{
|
|
||||||
$validated = $request->validate([
|
|
||||||
'name' => ['required'],
|
|
||||||
]);
|
|
||||||
|
|
||||||
$habit->update($validated);
|
|
||||||
|
|
||||||
return new HabitResource($habit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(Habit $habit)
|
|
||||||
{
|
|
||||||
$habit->delete();
|
|
||||||
|
|
||||||
return response()->json();
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,7 +3,9 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Http\Requests\HabitsRequest;
|
use App\Http\Requests\HabitsRequest;
|
||||||
|
use App\Models\Category;
|
||||||
use App\Models\Habit;
|
use App\Models\Habit;
|
||||||
|
use App\Models\Tag;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
@ -12,7 +14,7 @@ class HabitController extends Controller
|
|||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
return view('habits.index', [
|
return view('habits.index', [
|
||||||
'habits' => Auth::user()->habits
|
'habits' => Auth::user()->habits->sortBy('category'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,8 +25,28 @@ public function create()
|
|||||||
|
|
||||||
public function store(HabitsRequest $request)
|
public function store(HabitsRequest $request)
|
||||||
{
|
{
|
||||||
$validata = $request->safe()->merge(['user_id' => Auth::id()]);
|
$validata = $request->safe();
|
||||||
Habit::create($validata->all());
|
|
||||||
|
$habit = new Habit($validata->all());
|
||||||
|
$habit->user_id = $request->user()->id;
|
||||||
|
|
||||||
|
$habit->save();
|
||||||
|
|
||||||
|
// Category - add if a name is entered
|
||||||
|
if (!is_null($validata->only('category')['category'])) {
|
||||||
|
$category = Category::firstOrCreate(['name' => $validata->only('category')['category']]);
|
||||||
|
$habit->category()->associate($category);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tags
|
||||||
|
if (!is_null($validata->only('tags')['tags'])) {
|
||||||
|
$tagsArray = explode(', ', $request->only('tags')['tags']);
|
||||||
|
|
||||||
|
foreach ($tagsArray as $tag) {
|
||||||
|
$tag = Tag::firstOrCreate(['name' => $tag], ['habit_id' => $habit->id]);
|
||||||
|
$habit->tags()->sync($tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return redirect()->route('habits.index')->with('status', 'created');
|
return redirect()->route('habits.index')->with('status', 'created');
|
||||||
}
|
}
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Http\Resources\HabitEntryResource;
|
|
||||||
use App\Models\HabitEntry;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
|
|
||||||
class HabitEntryApiController extends Controller
|
|
||||||
{
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
return HabitEntryResource::collection(HabitEntry::all());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store(Request $request)
|
|
||||||
{
|
|
||||||
$request->validate([
|
|
||||||
|
|
||||||
]);
|
|
||||||
|
|
||||||
return new HabitEntryResource(HabitEntry::create($request->validated()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function show(HabitEntry $habitEntry)
|
|
||||||
{
|
|
||||||
return new HabitEntryResource($habitEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(Request $request, HabitEntry $habitEntry)
|
|
||||||
{
|
|
||||||
$request->validate([
|
|
||||||
|
|
||||||
]);
|
|
||||||
|
|
||||||
$habitEntry->update($request->validated());
|
|
||||||
|
|
||||||
return new HabitEntryResource($habitEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function destroy(HabitEntry $habitEntry)
|
|
||||||
{
|
|
||||||
$habitEntry->delete();
|
|
||||||
|
|
||||||
return response()->json();
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,6 +10,8 @@ public function rules(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => ['required', 'string'],
|
'name' => ['required', 'string'],
|
||||||
|
'category' => ['string', 'nullable'],
|
||||||
|
'tags' => ['string', 'nullable'],
|
||||||
'type' => ['required', 'string'],
|
'type' => ['required', 'string'],
|
||||||
'value' => ['numeric'],
|
'value' => ['numeric'],
|
||||||
'suffix' => ['string'],
|
'suffix' => ['string'],
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
/** @mixin \App\Models\HabitEntry */
|
/** @mixin \App\Models\Entry */
|
||||||
class HabitEntryResource extends JsonResource
|
class HabitEntryResource extends JsonResource
|
||||||
{
|
{
|
||||||
public function toArray(Request $request)
|
public function toArray(Request $request)
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||||
|
|
||||||
class HabitEntry extends Model
|
class Entry extends Model
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
@ -5,6 +5,7 @@
|
|||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
|
||||||
class Habit extends Model
|
class Habit extends Model
|
||||||
@ -24,16 +25,16 @@ class Habit extends Model
|
|||||||
'goal_unit'
|
'goal_unit'
|
||||||
];
|
];
|
||||||
|
|
||||||
public function habitEntries(): HasMany {
|
public function entries(): HasMany {
|
||||||
return $this->hasMany(HabitEntry::class);
|
return $this->hasMany(Entry::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function user(): BelongsTo {
|
public function user(): BelongsTo {
|
||||||
return $this->belongsTo(User::class);
|
return $this->belongsTo(User::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tags(): HasMany {
|
public function tags(): BelongsToMany {
|
||||||
return $this->hasMany(Tag::class);
|
return $this->BelongsToMany(Tag::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function category(): BelongsTo {
|
public function category(): BelongsTo {
|
||||||
|
@ -12,7 +12,8 @@ class CategoryFactory extends Factory
|
|||||||
public function definition(): array
|
public function definition(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => $this->faker->name(),
|
'name' => $this->faker->word(),
|
||||||
|
'created_at' => now(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
use App\Models\HabitEntry;
|
use App\Models\Entry;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
class HabitEntryFactory extends Factory
|
class EntryFactory extends Factory
|
||||||
{
|
{
|
||||||
protected $model = HabitEntry::class;
|
protected $model = Entry::class;
|
||||||
|
|
||||||
public function definition()
|
public function definition()
|
||||||
{
|
{
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Database\Factories;
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use App\Models\Category;
|
||||||
use App\Models\Habit;
|
use App\Models\Habit;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
@ -13,8 +14,9 @@ class HabitFactory extends Factory
|
|||||||
public function definition()
|
public function definition()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => $this->faker->name(),
|
'name' => $this->faker->word(),
|
||||||
'user_id' => User::find('1')->first()
|
'user_id' => User::find('1')->first(),
|
||||||
|
'category_id' => Category::all()->shuffle()->first(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,8 @@ class TagFactory extends Factory
|
|||||||
public function definition(): array
|
public function definition(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'name' => $this->faker->name(),
|
'name' => $this->faker->word(),
|
||||||
|
'created_at' => now(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
return new class extends Migration {
|
return new class extends Migration {
|
||||||
public function up()
|
public function up()
|
||||||
{
|
{
|
||||||
Schema::create('habit_entries', function (Blueprint $table) {
|
Schema::create('entries', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
|
|
||||||
$table->foreignId('habit_id')->constrained();
|
$table->foreignId('habit_id')->constrained();
|
||||||
@ -20,6 +20,6 @@ public function up()
|
|||||||
|
|
||||||
public function down()
|
public function down()
|
||||||
{
|
{
|
||||||
Schema::dropIfExists('habit_entries');
|
Schema::dropIfExists('entries');
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -7,7 +7,7 @@
|
|||||||
return new class extends Migration {
|
return new class extends Migration {
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
Schema::create('habits_tags', function (Blueprint $table) {
|
Schema::create('habit_tag', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
|
|
||||||
$table->foreignId('habit_id')->constrained();
|
$table->foreignId('habit_id')->constrained();
|
||||||
@ -19,6 +19,6 @@ public function up(): void
|
|||||||
|
|
||||||
public function down(): void
|
public function down(): void
|
||||||
{
|
{
|
||||||
Schema::dropIfExists('habits_tags');
|
Schema::dropIfExists('habit_tag');
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -3,8 +3,10 @@
|
|||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||||
|
use App\Models\Category;
|
||||||
use App\Models\Habit;
|
use App\Models\Habit;
|
||||||
use App\Models\HabitEntry;
|
use App\Models\Entry;
|
||||||
|
use App\Models\Tag;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
@ -16,6 +18,14 @@ class DatabaseSeeder extends Seeder
|
|||||||
*/
|
*/
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
|
Category::factory()
|
||||||
|
->count(5)
|
||||||
|
->create();
|
||||||
|
|
||||||
|
Tag::factory()
|
||||||
|
->count(10)
|
||||||
|
->create();
|
||||||
|
|
||||||
User::factory()->create([
|
User::factory()->create([
|
||||||
'name' => 'Niisse',
|
'name' => 'Niisse',
|
||||||
'email' => 'nisselommerde@gmail.com',
|
'email' => 'nisselommerde@gmail.com',
|
||||||
@ -25,8 +35,7 @@ public function run(): void
|
|||||||
|
|
||||||
Habit::factory()
|
Habit::factory()
|
||||||
->count(5)
|
->count(5)
|
||||||
->has(HabitEntry::factory()->count(50))
|
->has(Entry::factory()->count(50))
|
||||||
->create();
|
->create();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
7
resources/views/components/pagecard.blade.php
Normal file
7
resources/views/components/pagecard.blade.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-md sm:rounded-lg ">
|
||||||
|
<div class="p-6 text-gray-900 dark:text-gray-100">
|
||||||
|
|
||||||
|
{{ $slot }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
19
resources/views/entries/create.blade.php
Normal file
19
resources/views/entries/create.blade.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<x-app-layout>
|
||||||
|
<x-slot name="header">
|
||||||
|
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
|
||||||
|
{{ __('Habits') }}
|
||||||
|
</h2>
|
||||||
|
</x-slot>
|
||||||
|
|
||||||
|
<div class="py-12">
|
||||||
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||||
|
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
|
||||||
|
<div class="p-6 text-gray-900 dark:text-gray-100">
|
||||||
|
|
||||||
|
test
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</x-app-layout>
|
@ -1,141 +1,165 @@
|
|||||||
<x-app-layout>
|
<x-app-layout>
|
||||||
<x-slot name="header">
|
<x-slot name="header">
|
||||||
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
|
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
|
||||||
{{ __('create new habit') }}
|
Create new habit
|
||||||
</h2>
|
</h2>
|
||||||
</x-slot>
|
</x-slot>
|
||||||
|
|
||||||
<div class="py-12">
|
<div class="py-4">
|
||||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||||
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-md sm:rounded-lg">
|
|
||||||
|
|
||||||
<div class="p-6 text-gray-900 dark:text-gray-100">
|
<form action="{{route('habits.store') }}" method="post">
|
||||||
<div class="w-1/2">
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-5">
|
||||||
<form action="{{route('habits.store') }}" method="post">
|
@csrf
|
||||||
@csrf
|
<x-pagecard>
|
||||||
|
<!-- Name -->
|
||||||
|
<div>
|
||||||
|
<x-input-label for="name" :value="__('Name')"/>
|
||||||
|
<x-text-input id="name" class="block mt-1 w-full" type="text" name="name"
|
||||||
|
placeholder="Habit name" required
|
||||||
|
:value="old('name')" required autofocus autocomplete="name"/>
|
||||||
|
<x-input-error :messages="$errors->get('name')" class="mt-2"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Name -->
|
<!-- Category input -->
|
||||||
<div>
|
<div class="mt-6">
|
||||||
<x-input-label for="name" :value="__('Name')"/>
|
<x-input-label for="category" value="Category"/>
|
||||||
<x-text-input id="name" class="block mt-1 w-full" type="text" name="name"
|
<x-text-input id="category" class="block mt-1 w-full" type="text" name="category"
|
||||||
placeholder="Habit name" required
|
placeholder="Category name"
|
||||||
:value="old('name')" required autofocus autocomplete="name"/>
|
:value="old('category')" autocomplete="category"/>
|
||||||
<x-input-error :messages="$errors->get('name')" class="mt-2"/>
|
<x-input-error :messages="$errors->get('category')" class="mt-2"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- tag input -->
|
||||||
|
<div class="mt-6">
|
||||||
|
<x-input-label for="tag" value="Tag"/>
|
||||||
|
<x-text-input id="tag" class="block mt-1 w-full" type="text" name="tags"
|
||||||
|
placeholder="First tag, second tag, third tag..."
|
||||||
|
:value="old('tag')" autocomplete="tag"/>
|
||||||
|
<x-input-error :messages="$errors->get('tag')" class="mt-2"/>
|
||||||
|
</div>
|
||||||
|
</x-pagecard>
|
||||||
|
|
||||||
|
<x-pagecard>
|
||||||
|
|
||||||
|
<!-- Type -->
|
||||||
|
<div class="">
|
||||||
|
<x-input-label for="habit_type" value="Habit Type"></x-input-label>
|
||||||
|
<div class="flex items-center mb-1">
|
||||||
|
|
||||||
|
<!-- Radio button: todo-->
|
||||||
|
<input id="habit-type-1" type="radio" value="todo" name="type"
|
||||||
|
onclick="toggleHabitValueSuffix(true)" checked
|
||||||
|
class="w-4 h-4 text-blue-600 bg-gray-50 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||||
|
<label for="habit-type-1" class="ml-2">Todo / done</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Type -->
|
<!-- Radio button: value-->
|
||||||
<div class="mt-6">
|
<div class="flex items-center mb-1">
|
||||||
<x-input-label for="habit_type" value="Habit Type"></x-input-label>
|
<input id="habit-type-2" type="radio" value="value" name="type"
|
||||||
<div class="flex items-center mb-1">
|
onclick="toggleHabitValueSuffix(false)"
|
||||||
|
class="w-4 h-4 text-blue-600 bg-gray-50 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||||
<!-- Radio button: todo-->
|
<label for="habit-type-2" class="ml-2 ">Value / suffix</label>
|
||||||
<input id="habit-type-1" type="radio" value="todo" name="type"
|
|
||||||
onclick="toggleHabitValueSuffix(true)" checked
|
|
||||||
class="w-4 h-4 text-blue-600 bg-gray-50 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
|
||||||
<label for="habit-type-1" class="ml-2">Todo / done</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Radio button: value-->
|
|
||||||
<div class="flex items-center mb-1">
|
|
||||||
<input id="habit-type-2" type="radio" value="value" name="type"
|
|
||||||
onclick="toggleHabitValueSuffix(false)"
|
|
||||||
class="w-4 h-4 text-blue-600 bg-gray-50 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
|
||||||
<label for="habit-type-2" class="ml-2 ">Value / suffix</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Value / Suffix -->
|
|
||||||
<x-input-label for="value" value="Value and suffix" class="mt-4"
|
|
||||||
id="habit-suffix-label"/>
|
|
||||||
|
|
||||||
<x-text-input id="habit-value-amount" class="inline-block mt-1" type="number"
|
|
||||||
placeholder="Numeric value" min="0"
|
|
||||||
name="value" required disabled/>
|
|
||||||
<x-input-error :messages="$errors->get('value')" class="mt-2"/>
|
|
||||||
|
|
||||||
<x-text-input id="habit-suffix-name" class="inline-block mt-1 disabled:opacity-50"
|
|
||||||
type="text" name="suffix" disabled required
|
|
||||||
placeholder="Suffix"
|
|
||||||
:value="old('suffix')" autofocus autocomplete="suffix"/>
|
|
||||||
<x-input-error :messages="$errors->get('suffix')" class="mt-2"/>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Schedule -->
|
<!-- Value / Suffix -->
|
||||||
<div class="mt-6">
|
<x-input-label for="value" value="Value and suffix" class="mt-4"
|
||||||
<x-input-label for="schedule-value" value="Schedule"></x-input-label>
|
id="habit-suffix-label"/>
|
||||||
<x-text-input id="schedule-value" class="inline-block mt-1" type="number"
|
|
||||||
placeholder="Numeric value" min="0"
|
|
||||||
name="schedule-value"/>
|
|
||||||
|
|
||||||
<select name="schedule-unit" id="schedule-unit"
|
<x-text-input id="habit-value-amount" class="inline-block mt-1 w-20" type="number"
|
||||||
class="inline-block w-1/2 border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm">
|
placeholder="" min="0" value="1"
|
||||||
<option value="day">Days</option>
|
name="value" required disabled/>
|
||||||
<option value="week">Weeks</option>
|
<x-input-error :messages="$errors->get('value')" class="mt-2"/>
|
||||||
<option value="month">Months</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
|
<x-text-input id="habit-suffix-name" class="inline-block mt-1 disabled:opacity-50 w-1/2"
|
||||||
|
type="text" name="suffix" disabled required
|
||||||
|
placeholder="Suffix"
|
||||||
|
:value="old('suffix')" autocomplete="suffix"/>
|
||||||
|
<x-input-error :messages="$errors->get('suffix')" class="mt-2"/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Schedule -->
|
||||||
|
<div class="mt-6">
|
||||||
|
<x-input-label for="schedule-value" value="Schedule"></x-input-label>
|
||||||
|
<x-text-input id="schedule-value" class="inline-block mt-1 w-20" type="number"
|
||||||
|
placeholder="" min="0" value="1"
|
||||||
|
name="schedule_value"/>
|
||||||
|
<x-input-error :messages="$errors->get('schedule_value')" class="mt-2"/>
|
||||||
|
|
||||||
|
<select name="schedule-unit" id="schedule-unit"
|
||||||
|
class="inline-block w-1/2 border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm">
|
||||||
|
<option value="day">Days</option>
|
||||||
|
<option value="week">Weeks</option>
|
||||||
|
<option value="month">Months</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</x-pagecard>
|
||||||
|
|
||||||
|
<!-- Goal -->
|
||||||
|
<x-pagecard>
|
||||||
|
<div class="">
|
||||||
|
<x-input-label value="Goal Type"></x-input-label>
|
||||||
|
<div class="text-sm my-3">
|
||||||
|
Adding a goal changes the display mode from the value and suffix to a calculated
|
||||||
|
percentage.
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex items-center mb-1">
|
||||||
<!-- Goal -->
|
<input id="goal-type-1" type="radio" value="none" name="goal_type"
|
||||||
<div class="mt-6">
|
onclick="toggleGoalSchedule(true)"
|
||||||
<x-input-label value="Goal Type"></x-input-label>
|
class="w-4 h-4 text-blue-600 bg-gray-50 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||||
<div class="text-sm my-3">
|
<label for="goal-type-1" class="ml-2">No goal</label>
|
||||||
Adding a goal changes the display mode from the value and suffix to a calculated
|
|
||||||
percentage.
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center mb-1">
|
|
||||||
<input id="goal-type-1" type="radio" value="none" name="goal_type"
|
|
||||||
onclick="toggleGoalSchedule(true)"
|
|
||||||
class="w-4 h-4 text-blue-600 bg-gray-50 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
|
||||||
<label for="goal-type-1" class="ml-2">No goal</label>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center mb-1">
|
|
||||||
<input id="goal-type-2" type="radio" value="schedule" name="goal_type"
|
|
||||||
checked onclick="toggleGoalSchedule(true)"
|
|
||||||
class="w-4 h-4 text-blue-600 bg-gray-50 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
|
||||||
<label for="goal-type-2" class="ml-2 ">Same as schedule</label>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center mb-1">
|
|
||||||
<input id="goal-type-3" type="radio" value="custom" name="goal_type"
|
|
||||||
onclick="toggleGoalSchedule(false)"
|
|
||||||
class="w-4 h-4 text-blue-600 bg-gray-50 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
|
||||||
<label for="goal-type-3" class="ml-2 ">Custom schedule</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex items-center mb-1">
|
||||||
<!-- goal schedule -->
|
<input id="goal-type-2" type="radio" value="schedule" name="goal_type"
|
||||||
<div class="mt-6">
|
checked onclick="toggleGoalSchedule(true)"
|
||||||
<x-input-label for="goal-schedule-unit" value="Goal Schedule"></x-input-label>
|
class="w-4 h-4 text-blue-600 bg-gray-50 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||||
|
<label for="goal-type-2" class="ml-2 ">Same as schedule</label>
|
||||||
<x-text-input id="goal-schedule-amount" class="inline-block mt-1" type="number"
|
|
||||||
placeholder="Numeric value" min="0" disabled required
|
|
||||||
name="goal_value"/>
|
|
||||||
|
|
||||||
<select name="goal_unit" id="goal-schedule-unit"
|
|
||||||
disabled required
|
|
||||||
class="inline-block w-1/2 border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm disabled:opacity-50">
|
|
||||||
<option value="day">Days</option>
|
|
||||||
<option value="week">Weeks</option>
|
|
||||||
<option value="month">Months</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex items-center mb-1">
|
||||||
<!-- Priority -->
|
<input id="goal-type-3" type="radio" value="custom" name="goal_type"
|
||||||
|
onclick="toggleGoalSchedule(false)"
|
||||||
<hr class="my-4">
|
class="w-4 h-4 text-blue-600 bg-gray-50 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||||
<!-- Submit -->
|
<label for="goal-type-3" class="ml-2 ">Custom schedule</label>
|
||||||
<div class="mt-4">
|
|
||||||
<x-primary-button>Create habit</x-primary-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</form>
|
<!-- goal schedule -->
|
||||||
</div>
|
<div class="mt-6">
|
||||||
|
<x-input-label for="goal-schedule-unit" value="Goal Schedule"></x-input-label>
|
||||||
|
|
||||||
|
<x-text-input id="goal-schedule-amount" class="inline-block mt-1 w-20" type="number"
|
||||||
|
value="1" placeholder="" min="0" disabled required
|
||||||
|
name="goal_value"/>
|
||||||
|
<x-input-error :messages="$errors->get('goal_value')" class="mt-2"/>
|
||||||
|
|
||||||
|
<select name="goal_unit" id="goal-schedule-unit"
|
||||||
|
disabled required
|
||||||
|
class="inline-block w-1/2 border-gray-300 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 focus:border-indigo-500 dark:focus:border-indigo-600 focus:ring-indigo-500 dark:focus:ring-indigo-600 rounded-md shadow-sm disabled:opacity-50">
|
||||||
|
<option value="day">Days</option>
|
||||||
|
<option value="week">Weeks</option>
|
||||||
|
<option value="month">Months</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Priority -->
|
||||||
|
|
||||||
|
</x-pagecard>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<!-- Submit -->
|
||||||
|
<div class="w-full">
|
||||||
|
<div class=" my-6 float-right">
|
||||||
|
<x-primary-button class="px-20 py-2">Create habit</x-primary-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
function toggleHabitValueSuffix(value) {
|
function toggleHabitValueSuffix(value) {
|
||||||
document.getElementById('habit-value-amount').disabled = value;
|
document.getElementById('habit-value-amount').disabled = value;
|
||||||
|
@ -22,12 +22,18 @@
|
|||||||
<thead class="text-gray-900 bg-gray-100 dark:bg-gray-700 dark:text-gray-200">
|
<thead class="text-gray-900 bg-gray-100 dark:bg-gray-700 dark:text-gray-200">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="px-4 py-2">
|
<th scope="col" class="px-4 py-2">
|
||||||
Habits
|
Category
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="px-4 py-2">
|
||||||
|
Habit
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" class="px-6 py-2">
|
<th scope="col" class="px-6 py-2">
|
||||||
{{-- Edit--}}
|
Tags
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th scope="col" class="px-6 py-2">
|
||||||
|
|
||||||
|
</th>
|
||||||
|
<th scope="col" class="px-6 py-2">
|
||||||
|
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -35,9 +41,23 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
@foreach($habits as $habit)
|
@foreach($habits as $habit)
|
||||||
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 even:bg-gray-50 hover:bg-gray-100 dark:hover:bg-gray-600">
|
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 even:bg-gray-50 hover:bg-gray-100 dark:hover:bg-gray-600">
|
||||||
|
<td class="text-left px-4 py-2">
|
||||||
|
@if(is_null($habit->category))
|
||||||
|
No Category
|
||||||
|
@else
|
||||||
|
{{$habit->category->name}}
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
<td class="text-left px-4 py-2">
|
<td class="text-left px-4 py-2">
|
||||||
{{$habit->name}}
|
{{$habit->name}}
|
||||||
</td>
|
</td>
|
||||||
|
<td class="text-left px-4 py-2">
|
||||||
|
@if(sizeof($habit->tags) != 0)
|
||||||
|
@foreach($habit->tags as $tag)
|
||||||
|
{{$tag->name . " "}}
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
<td class="px-4 py-2">
|
<td class="px-4 py-2">
|
||||||
<form action="{{route('habits.show', $habit)}}" method="get">
|
<form action="{{route('habits.show', $habit)}}" method="get">
|
||||||
@csrf
|
@csrf
|
||||||
@ -45,9 +65,9 @@
|
|||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-4 py-2">
|
<td class="px-4 py-2">
|
||||||
<form action="{{route('habits.edit', $habit)}}" method="get">
|
<form action="{{route('entries.create', $habit)}}" method="get">
|
||||||
@csrf
|
@csrf
|
||||||
<x-primary-button>Edit</x-primary-button>
|
<x-secondary-button type="submit">View</x-secondary-button>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -59,38 +79,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</x-app-layout>
|
</x-app-layout>
|
||||||
|
|
||||||
|
|
||||||
{{-- <div class="w-auto inline-block">--}}
|
|
||||||
{{-- <div class="grid grid-cols-3 gap-x-8 gap-y-2">--}}
|
|
||||||
{{-- <div>--}}
|
|
||||||
{{-- <b>Name</b>--}}
|
|
||||||
{{-- </div>--}}
|
|
||||||
{{-- <div>--}}
|
|
||||||
{{-- <b>Edit</b>--}}
|
|
||||||
{{-- </div>--}}
|
|
||||||
{{-- <div>--}}
|
|
||||||
{{-- <b>Remove</b>--}}
|
|
||||||
{{-- </div>--}}
|
|
||||||
{{-- @foreach($habits as $habit)--}}
|
|
||||||
{{-- <div>--}}
|
|
||||||
{{-- {{ $habit->name }} <br>--}}
|
|
||||||
{{-- </div>--}}
|
|
||||||
{{-- <div>--}}
|
|
||||||
{{-- <form action="{{route('habits.edit', $habit)}}" method="get">--}}
|
|
||||||
{{-- @csrf--}}
|
|
||||||
{{-- <x-primary-button>Edit</x-primary-button>--}}
|
|
||||||
{{-- </form>--}}
|
|
||||||
{{-- </div>--}}
|
|
||||||
{{-- <div>--}}
|
|
||||||
{{-- <form action="{{route('habits.destroy', $habit)}}" method="get">--}}
|
|
||||||
{{-- @csrf--}}
|
|
||||||
{{-- <x-danger-button>Delete</x-danger-button>--}}
|
|
||||||
{{-- </form>--}}
|
|
||||||
{{-- </div>--}}
|
|
||||||
{{-- @endforeach--}}
|
|
||||||
|
|
||||||
{{-- </div>--}}
|
|
||||||
{{-- </div>--}}
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
<!-- Page Heading -->
|
<!-- Page Heading -->
|
||||||
@if (isset($header))
|
@if (isset($header))
|
||||||
<header class="bg-white dark:bg-gray-800 shadow">
|
<header class="bg-white dark:bg-gray-800 shadow">
|
||||||
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
|
<div class="max-w-7xl mx-auto py-6 mb-2 px-4 sm:px-6 lg:px-8">
|
||||||
{{ $header }}
|
{{ $header }}
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Route::apiResource('habits', HabitApiController::class);
|
Route::apiResource('habits', HabitApiController::class);
|
||||||
Route::apiResource('habit-entries', HabitEntryApiController::class);
|
|
||||||
|
|
||||||
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
|
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
|
||||||
return $request->user();
|
return $request->user();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use App\Http\Controllers\DashboardController;
|
use App\Http\Controllers\DashboardController;
|
||||||
|
use App\Http\Controllers\EntryController;
|
||||||
use App\Http\Controllers\HabitController;
|
use App\Http\Controllers\HabitController;
|
||||||
use App\Http\Controllers\ProfileController;
|
use App\Http\Controllers\ProfileController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
@ -30,4 +31,6 @@
|
|||||||
|
|
||||||
Route::resource('/habits', HabitController::class);
|
Route::resource('/habits', HabitController::class);
|
||||||
|
|
||||||
|
Route::resource('/habits/entries', EntryController::class);
|
||||||
|
|
||||||
require __DIR__.'/auth.php';
|
require __DIR__.'/auth.php';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user