sototh 1 semana atrás
pai
commit
878ea0e1f6

+ 172 - 0
app/Http/Controllers/Api/FormDataController.php

@@ -0,0 +1,172 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Http\Controllers\Controller;
+use Illuminate\Http\Request;
+use App\Models\FormData;
+use App\Models\Category;
+use App\Models\Comment;
+use Illuminate\Support\Str;
+
+class FormDataController extends Controller
+{
+    /**
+     * Display a listing of the resource.
+     */
+    public function index(Request $request)
+    {
+        $query = FormData::with(['category', 'comments.user'])
+            ->active();
+        
+        if ($request->has('gender')) {
+            $gender = filter_var($request->gender, FILTER_VALIDATE_BOOLEAN);
+            if ($gender) {
+                $query->male();
+            } else {
+                $query->female();
+            }
+        }
+
+        if ($request->has('email')) {
+            $query->byEmail($request->email);
+        }
+
+        if ($request->has('today') && $request->boolean('today')) {
+            $query->today();
+        }
+
+        if ($request->has('long_message') && $request->boolean('long_message')) {
+            $query->withLongMessage(50);
+        }
+
+        $perPage = $request->get('per_page', 15);
+        $formData = $query->paginate($perPage);
+
+        return FormDataResource::collection($formData);
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     */
+    public function store(Request $request)
+    {
+       $validator = Validator::make($request->all(), [
+            'name' => 'required|min:2|max:100',
+            'email' => 'required|email',
+            'phone' => 'required|digits:11',
+            'gender' => 'boolean',
+            'message' => 'required|min:10|max:1000',
+            'category_id' => 'nullable|exists:categories,id',
+        ]);
+
+        if ($validator->fails()) {
+            return response()->json([
+                'success' => false,
+                'errors' => $validator->errors()
+            ], 422);
+        }
+
+        $formData = FormData::create($validator->validated());
+
+        return response()->json([
+            'success' => true,
+            'message' => 'Form data created successfully',
+            'data' => new FormDataResource($formData)
+        ], 201);
+    }
+
+    /**
+     * Display the specified resource.
+     */
+    public function show(FormData $formData)
+    {
+        $formData->load(['category', 'comments.user']);
+        return new FormDataResource($formData);    }
+
+    /**
+     * Update the specified resource in storage.
+     */
+    public function update(Request $request, FormData $formData)
+    {
+        $validator = Validator::make($request->all(), [
+            'name' => 'sometimes|min:2|max:100',
+            'email' => 'sometimes|email',
+            'phone' => 'sometimes|digits:11',
+            'gender' => 'sometimes|boolean',
+            'message' => 'sometimes|min:10|max:1000',
+            'category_id' => 'nullable|exists:categories,id',
+        ]);
+
+        if ($validator->fails()) {
+            return response()->json([
+                'success' => false,
+                'errors' => $validator->errors()
+            ], 422);
+        }
+
+        $formData->update($validator->validated());
+
+        return response()->json([
+            'success' => true,
+            'message' => 'Form data updated successfully',
+            'data' => new FormDataResource($formData->fresh())
+        ]);    }
+
+    /**
+     * Remove the specified resource from storage.
+     */
+    public function destroy(FormData $formData)
+    {
+        $formData->delete();
+        return response()->json([
+            'success' => true,
+            'message' => 'Form data soft deleted successfully'
+        ]);
+    }
+
+
+    public function addComment(Request $request, FormData $formData)
+    {
+        $validator = Validator::make($request->all(), [
+            'content' => 'required|min:5|max:500',
+            'user_id' => 'nullable|exists:users,id',
+        ]);
+
+        if ($validator->fails()) {
+            return response()->json([
+                'success' => false,
+                'errors' => $validator->errors()
+            ], 422);
+        }
+
+        $comment = $formData->comments()->create($validator->validated());
+
+        return response()->json([
+            'success' => true,
+            'message' => 'Comment added successfully',
+            'data' => $comment
+        ], 201);
+    }
+
+    public function statistics()
+    {
+        $total = FormData::count();
+        $maleCount = FormData::male()->count();
+        $femaleCount = FormData::female()->count();
+        $todayCount = FormData::today()->count();
+        $withLongMessage = FormData::withLongMessage(100)->count();
+
+        return response()->json([
+            'success' => true,
+            'data' => [
+                'total' => $total,
+                'male' => $maleCount,
+                'female' => $femaleCount,
+                'today' => $todayCount,
+                'with_long_message' => $withLongMessage,
+                'average_message_length' => round(FormData::avg(\DB::raw('LENGTH(message)')), 2),
+            ]
+        ]);
+    }
+}

+ 96 - 16
app/Http/Controllers/FormController.php

@@ -5,12 +5,16 @@ namespace App\Http\Controllers;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Storage;
 use Illuminate\Support\Str;
+use App\Models\FormData;
+use App\Models\Category;
+use App\Models\Comments;
 
 class FormController extends Controller
 {
     public function showForm()
     {
-        return view('form');
+        $categories = Category::active()->get();
+        return view('form', compact('categories')); 
     }
 
     public function submitForm(Request $request)
@@ -21,34 +25,110 @@ class FormController extends Controller
             'phone' => 'required|digits:11',
             'gender' => 'boolean',
             'message' => 'required|min:10|max:1000',
+            'category_id' => 'nullable|exists:categories,id',
         ]);
-        $filename = 'form-data-' . Str::uuid() . '.json';
-        Storage::put("form-data/{$filename}", json_encode([
-            'id' => Str::uuid(),
+
+        $formData = FormData::create([
+            'uuid' => Str::uuid(),
             'name' => $validated['name'],
             'email' => $validated['email'],
             'phone' => $validated['phone'],
-            'gender' => array_key_exists('gender', $validated) ? $validated['gender'] : 0,
+            'gender' => $validated['gender'] ?? false,
             'message' => $validated['message'],
-            'submitted_at' => now()->timezone('Asia/Irkutsk')->toDateISOString(),
-        ], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
+            'category_id' => $validated['category_id'] ?? null,
+        ]);
+
+        if ($request->has('comment') && !empty($request->comment)) {
+            $formData->comments()->create([
+                'content' => $request->comment,
+                'user_id' => auth()->id() ?? null,
+            ]);
+        }
 
         return redirect()->route('form.show')
-            ->with('success', 'Данные успешно сохранены!');
+            ->with('success', 'Данные успешно сохранены в базе данных! ID: ' . $formData->id);
     }
 
-    public function showData()
+    public function showData(Request $request)
     {
-        $files = Storage::files('form-data');
-        $data = [];
+        $query = FormData::with(['category', 'comments']);
 
-        foreach ($files as $file) {
-            if (pathinfo($file, PATHINFO_EXTENSION) === 'json') {
-                $content = Storage::get($file);
-                $data[] = json_decode($content, true);
+        if ($request->has('gender') && in_array($request->gender, ['male', 'female'])) {
+            if ($request->gender === 'male') {
+                $query->male();
+            } else {
+                $query->female();
             }
+        }   
+
+        if ($request->has('today') && $request->boolean('today')) {
+            $query->today();
         }
 
-        return view('data', compact('data'));
+        $data = $query->latest()->paginate(10);
+
+        $categories = Category::all();
+        
+        return view('data', compact('data', 'categories'));
+    }
+
+    public function show($id)
+    {
+        $formData = FormData::with(['category', 'comments.user'])
+            ->findOrFail($id);
+            
+        return view('form-data.show', compact('formData'));
+    }
+
+    public function edit($id)
+    {
+        $formData = FormData::findOrFail($id);
+        $categories = Category::active()->get();
+        
+        return view('form-data.edit', compact('formData', 'categories'));
+    }
+
+    public function update(Request $request, $id)
+    {
+        $formData = FormData::findOrFail($id);
+        
+        $validated = $request->validate([
+            'name' => 'required|min:2|max:100',
+            'email' => 'required|email',
+            'phone' => 'required|digits:11',
+            'gender' => 'boolean',
+            'message' => 'required|min:10|max:1000',
+            'category_id' => 'nullable|exists:categories,id',
+        ]);
+
+        $formData->update($validated);
+
+        return redirect()->route('data.show')
+            ->with('success', 'Данные успешно обновлены!');
+    }
+
+    public function destroy($id)
+    {
+        $formData = FormData::findOrFail($id);
+        $formData->delete();
+
+        return redirect()->route('data.show')
+            ->with('success', 'Данные перемещены в корзину!');
+    }
+
+    public function addComment(Request $request, $id)
+    {
+        $formData = FormData::findOrFail($id);
+        
+        $validated = $request->validate([
+            'content' => 'required|min:5|max:500',
+        ]);
+
+        $formData->comments()->create([
+            'content' => $validated['content'],
+            'user_id' => auth()->id() ?? null,
+        ]);
+
+        return back()->with('success', 'Комментарий добавлен!');
     }
 }

+ 50 - 0
app/Http/Resources/FormDataResource.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class FormDataResource extends JsonResource
+{
+    /**
+     * Transform the resource into an array.
+     *
+     * @return array<string, mixed>
+     */
+    public function toArray(Request $request): array
+    {
+        return [
+            'id' => $this->id,
+            'uuid' => $this->uuid,
+            'name' => $this->name,
+            'email' => $this->email,
+            'phone' => $this->phone,
+            'gender' => $this->gender ? 'Male' : 'Female',
+            'message' => $this->message,
+            'submitted_at' => $this->submitted_at->format('Y-m-d H:i:s'),
+            'created_at' => $this->created_at->format('Y-m-d H:i:s'),
+            'updated_at' => $this->updated_at->format('Y-m-d H:i:s'),
+            'category' => $this->whenLoaded('category', function () {
+                return [
+                    'id' => $this->category->id,
+                    'name' => $this->category->name,
+                ];
+            }),
+            'comments' => $this->whenLoaded('comments', function () {
+                return $this->comments->map(function ($comment) {
+                    return [
+                        'id' => $comment->id,
+                        'content' => $comment->content,
+                        'user' => $comment->user ? $comment->user->name : 'Anonymous',
+                    ];
+                });
+            }),
+            'links' => [
+                'self' => route('api.form-data.show', $this->id),
+                'edit' => route('api.form-data.update', $this->id),
+                'delete' => route('api.form-data.destroy', $this->id),
+            ],
+        ];
+    }
+}

+ 34 - 0
app/Models/Category.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\SoftDeletes;
+use Illuminate\Database\Eloquent\Builder;
+
+class Category extends Model
+{
+    use HasFactory, SoftDeletes;
+
+    protected $fillable = [
+        'name',
+        'description',
+        'is_active'
+    ];
+
+    protected $casts = [
+        'is_active' => 'boolean',
+    ];
+
+
+    public function formData(): HasMany
+    {
+        return $this->hasMany(FormData::class);
+    }
+
+    public function scopeActive($query)
+    {
+        return $query->where('is_active', true);
+    }
+}

+ 42 - 0
app/Models/Comments.php

@@ -0,0 +1,42 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\SoftDeletes;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+class Comments extends Model
+{
+    use HasFactory, SoftDeletes;
+
+    protected $fillable = [
+        'content',
+        'commentable_id',
+        'commentable_type',
+        'user_id',
+        'is_banned'
+    ];
+
+    public function commentable(): MorphTo
+    {
+        return $this->morphTo();
+    }
+
+    public function user(): BelongsTo
+    {
+        return $this->belongsTo(User::class);
+    }
+
+    public function scopeBanned($query)
+    {
+        return $query->where('is_banned', true);
+    }
+
+    public function scopeActive($query)
+    {
+        return $query->where('is_banned', false);
+    }
+}

+ 69 - 0
app/Models/FormData.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\SoftDeletes;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Database\Eloquent\Relations\MorphMany;
+use Illuminate\Database\Eloquent\Builder;
+
+class FormData extends Model
+{
+    use HasFactory, SoftDeletes;
+
+    protected $fillable = [
+        'uuid',
+        'name',
+        'email',
+        'phone',
+        'gender',
+        'message',
+        'submitted_at',
+        'category_id'
+    ];
+
+    protected $casts = [
+        'gender' => 'boolean',
+        'submitted_at' => 'datetime',
+        'is_banned' => 'boolean',
+    ];
+
+    protected static function booted()
+    {
+        static::creating(function ($model) {
+            if (empty($model->uuid)) {
+                $model->uuid = \Illuminate\Support\Str::uuid()->toString();
+            }
+            if (empty($model->submitted_at)) {
+                $model->submitted_at = now();
+            }
+        });
+    }
+
+    public function comments(): MorphMany
+    {
+        return $this->morphMany(Comments::class, 'commentable');
+    }
+
+    public function category(): BelongsTo
+    {
+        return $this->belongsTo(Category::class);
+    }
+
+    public function scopeMale(Builder $query): Builder
+    {
+        return $query->where('gender', true);
+    }
+
+    public function scopeFemale(Builder $query)
+    {
+        return $query->where('gender', false);
+    }
+
+    public function scopeToday(Builder $query): Builder
+    {
+        return $query->whereDate('submitted_at', today());
+    }
+}

+ 5 - 0
app/Models/User.php

@@ -45,4 +45,9 @@ class User extends Authenticatable
             'password' => 'hashed',
         ];
     }
+
+    public function comments(): HasMany
+    {
+        return $this->hasMany(Comments::class);
+    }
 }

+ 27 - 0
database/factories/CategoryFactory.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace Database\Factories;
+
+use Illuminate\Database\Eloquent\Factories\Factory;
+
+/**
+ * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Category>
+ */
+class CategoryFactory extends Factory
+{
+    /**
+     * Define the model's default state.
+     *
+     * @return array<string, mixed>
+     */
+    public function definition(): array
+    {
+        $name = $this->faker->word();
+        
+        return [
+            'name' => ucfirst($name),
+            'description' => $this->faker->sentence(),
+            'is_active' => $this->faker->boolean(80),
+        ];
+    }
+}

+ 24 - 0
database/factories/CommentsFactory.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace Database\Factories;
+
+use Illuminate\Database\Eloquent\Factories\Factory;
+
+/**
+ * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Model>
+ */
+class CommentsFactory extends Factory
+{
+    /**
+     * Define the model's default state.
+     *
+     * @return array<string, mixed>
+     */
+    public function definition(): array
+    {
+        return [
+            'content' => $this->faker->paragraph(),
+            'is_banned' => $this->faker->boolean(70),
+        ];
+    }
+}

+ 35 - 0
database/factories/FormDataFactory.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace Database\Factories;
+
+use Illuminate\Database\Eloquent\Factories\Factory;
+use App\Models\Category;
+use App\Models\FormData;
+use App\Models\Comments;
+use Illuminate\Database\Console\Seeds\WithoutModelEvents;
+use Illuminate\Database\Seeder;
+use Illuminate\Support\Str;
+
+/**
+ * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\FormData>
+ */
+class FormDataFactory extends Factory
+{
+    /**
+     * Define the model's default state.
+     *
+     * @return array<string, mixed>
+     */
+    public function definition(): array
+    {
+        return [
+            'uuid' => Str::uuid(),
+            'name' => $this->faker->name(),
+            'email' => $this->faker->unique()->safeEmail(),
+            'phone' => '7' . $this->faker->numerify('##########'),
+            'gender' => $this->faker->boolean(),
+            'message' => $this->faker->paragraphs(3, true),
+            'submitted_at' => $this->faker->dateTimeBetween('-1 year', 'now'),
+        ];
+    }
+}

+ 36 - 0
database/migrations/2025_12_15_073531_create_form_data_table.php

@@ -0,0 +1,36 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('form_data', function (Blueprint $table) {
+            $table->id();
+            $table->string('uuid')->unique();
+            $table->string('name');
+            $table->string('email');
+            $table->string('phone', 11);
+            $table->boolean('gender')->default(false);
+            $table->text('message');
+            $table->timestamp('submitted_at')->nullable();
+            $table->foreignId('category_id')->nullable()->constrained()->nullOnDelete();
+            $table->softDeletes();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('form_data');
+    }
+};

+ 32 - 0
database/migrations/2025_12_15_074945_create_categories_table.php

@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('categories', function (Blueprint $table) {
+            $table->id();
+            $table->text('name');
+            $table->text('description')->nullable();
+            $table->boolean('is_active')->default(true);
+
+            $table->timestamps();
+            $table->softDeletes();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('categories');
+    }
+};

+ 33 - 0
database/migrations/2025_12_15_084451_create_comments_table.php

@@ -0,0 +1,33 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::create('comments', function (Blueprint $table) {
+            $table->id();
+            $table->text('content')->nullable();
+            $table->morphs('commentable');
+            $table->foreignId('user_id')->nullable()->constrained()->nullOnDelete();
+            $table->boolean('is_banned')->default(false);
+
+            $table->timestamps();
+            $table->softDeletes();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('comments');
+    }
+};

+ 22 - 4
database/seeders/DatabaseSeeder.php

@@ -3,6 +3,9 @@
 namespace Database\Seeders;
 
 use App\Models\User;
+use App\Models\Category;
+use App\Models\FormData;
+use App\Models\Comments;
 use Illuminate\Database\Console\Seeds\WithoutModelEvents;
 use Illuminate\Database\Seeder;
 
@@ -15,11 +18,26 @@ class DatabaseSeeder extends Seeder
      */
     public function run(): void
     {
-        // User::factory(10)->create();
-
-        User::factory()->create([
+        User::where('email', 'test@example.com')->delete();
+        $user = User::factory()->create([
             'name' => 'Test User',
             'email' => 'test@example.com',
+            'password' => bcrypt('password'), 
         ]);
+
+        $categories = Category::factory()->count(5)->create();
+
+        FormData::factory()->count(50)->create()->each(function ($formData) use ($categories, $user) {
+            $formData->category()->associate($categories->random());
+            $formData->save();
+
+            Comments::factory()->count(rand(0, 3))->create([
+                'commentable_id' => $formData->id,
+                'commentable_type' => FormData::class,
+                'user_id' => rand(0, 1) ? $user->id : null,
+            ]);
+        });
+
+        $this->command->info('Database seeded successfully!');
     }
-}
+}

+ 199 - 29
resources/views/data.blade.php

@@ -3,45 +3,215 @@
 @section('title', 'Просмотр данных')
 
 @section('content')
-<div>
-    <div>
-        <h4>Все отправленные данные</h4>
+<div class="container mx-auto px-4 py-8">
+    <div class="mb-6">
+        <div class="flex justify-between items-center">
+            <h4 class="text-2xl font-bold text-gray-800">Все отправленные данные</h4>
+            <div class="flex space-x-2">
+                <a href="{{ route('form.show') }}" 
+                   class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition">
+                    Добавить новую
+                </a>
+                <a href="{{ route('api.form-data.statistics') }}" 
+                   target="_blank"
+                   class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 transition">
+                    API Статистика
+                </a>
+            </div>
+        </div>
+        
+        <!-- Фильтры -->
+        <div class="mt-4 bg-white rounded-lg shadow p-4">
+            <form method="GET" action="{{ route('data.show') }}" class="flex flex-wrap gap-4">
+                <div>
+                    <label class="block text-sm font-medium text-gray-700 mb-1">Пол</label>
+                    <select name="gender" class="px-3 py-2 border border-gray-300 rounded">
+                        <option value="">Все</option>
+                        <option value="male" {{ request('gender') == 'male' ? 'selected' : '' }}>Мужской</option>
+                        <option value="female" {{ request('gender') == 'female' ? 'selected' : '' }}>Женский</option>
+                    </select>
+                </div>
+                
+                <div>
+                    <label class="block text-sm font-medium text-gray-700 mb-1">Категория</label>
+                    <select name="category_id" class="px-3 py-2 border border-gray-300 rounded">
+                        <option value="">Все категории</option>
+                        @foreach($categories as $category)
+                            <option value="{{ $category->id }}" {{ request('category_id') == $category->id ? 'selected' : '' }}>
+                                {{ $category->name }}
+                            </option>
+                        @endforeach
+                    </select>
+                </div>
+                
+                <div class="flex items-end">
+                    <label class="inline-flex items-center mt-2">
+                        <input type="checkbox" 
+                               name="today" 
+                               value="1" 
+                               {{ request('today') ? 'checked' : '' }}
+                               class="h-4 w-4 text-blue-600">
+                        <span class="ml-2 text-gray-700">За сегодня</span>
+                    </label>
+                </div>
+                
+                <div class="flex items-end space-x-2">
+                    <button type="submit" 
+                            class="px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700 transition">
+                        Фильтровать
+                    </button>
+                    <a href="{{ route('data.show') }}" 
+                       class="px-4 py-2 border border-gray-300 text-gray-700 rounded hover:bg-gray-50 transition">
+                        Сбросить
+                    </a>
+                </div>
+            </form>
+        </div>
     </div>
-    <div>
-        @if(empty($data))
-            <div>
-                Данные отсутствуют. <a href="{{ route('form.show') }}">Отправьте форму</a> чтобы добавить данные.
-            </div>
-        @else
-            <div>
-                <table>
-                    <thead>
+
+    @if($data->isEmpty())
+        <div class="bg-white rounded-lg shadow-md p-8 text-center">
+            <p class="text-gray-600 text-lg mb-4">Данные отсутствуют.</p>
+            <a href="{{ route('form.show') }}" 
+               class="px-6 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition">
+                Отправьте форму
+            </a> чтобы добавить данные.
+        </div>
+    @else
+        <div class="bg-white rounded-lg shadow-md overflow-hidden">
+            <div class="overflow-x-auto">
+                <table class="min-w-full divide-y divide-gray-200">
+                    <thead class="bg-gray-50">
                         <tr>
-                            <th>ID</th>
-                            <th>Имя</th>
-                            <th>Email</th>
-                            <th>Телефон</th>
-                            <th>Пол</th>
-                            <th>Сообщение</th>
-                            <th>Дата отправки</th>
+                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">ID</th>
+                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Имя</th>
+                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Email</th>
+                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Телефон</th>
+                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Пол</th>
+                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Категория</th>
+                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Сообщение</th>
+                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Дата</th>
+                            <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Действия</th>
                         </tr>
                     </thead>
-                    <tbody>
+                    <tbody class="bg-white divide-y divide-gray-200">
                         @foreach($data as $item)
-                        <tr>
-                            <td><small>{{ substr($item['id'], 0, 8) }}...</small></td>
-                            <td>{{ $item['name'] }}</td>
-                            <td>{{ $item['email'] }}</td>
-                            <td>{{ $item['phone'] }}</td>
-                            <td>{{ $item['gender'] ? 'Male' : 'female' }}</td>
-                            <td>{{ Str::limit($item['message'], 50) }}</td>
-                            <td>{{ \Carbon\Carbon::parse($item['submitted_at'])->timezone('Asia/Irkutsk')->format('d.m.Y H:i') }}</td>
+                        <tr class="hover:bg-gray-50 transition">
+                            <td class="px-6 py-4 whitespace-nowrap">
+                                <small class="text-gray-500">{{ substr($item->uuid, 0, 8) }}...</small>
+                            </td>
+                            <td class="px-6 py-4 whitespace-nowrap">
+                                <a href="{{ route('form-data.show', $item->id) }}" 
+                                   class="text-blue-600 hover:text-blue-800 font-medium">
+                                    {{ $item->name }}
+                                </a>
+                            </td>
+                            <td class="px-6 py-4 whitespace-nowrap">{{ $item->email }}</td>
+                            <td class="px-6 py-4 whitespace-nowrap">{{ $item->phone }}</td>
+                            <td class="px-6 py-4 whitespace-nowrap">
+                                <span class="px-2 py-1 text-xs rounded-full {{ $item->gender ? 'bg-blue-100 text-blue-800' : 'bg-pink-100 text-pink-800' }}">
+                                    {{ $item->gender ? 'Male' : 'Female' }}
+                                </span>
+                            </td>
+                            <td class="px-6 py-4 whitespace-nowrap">
+                                @if($item->category)
+                                    <span class="px-2 py-1 bg-gray-100 text-gray-800 text-xs rounded">
+                                        {{ $item->category->name }}
+                                    </span>
+                                @else
+                                    <span class="text-gray-400">—</span>
+                                @endif
+                            </td>
+                            <td class="px-6 py-4">
+                                <div class="max-w-xs truncate">
+                                    {{ Str::limit($item->message, 50) }}
+                                </div>
+                            </td>
+                            <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
+                                {{ $item->submitted_at->timezone('Asia/Irkutsk')->format('d.m.Y H:i') }}
+                            </td>
+                            <td class="px-6 py-4 whitespace-nowrap text-sm">
+                                <div class="flex space-x-2">
+                                    <a href="{{ route('form-data.show', $item->id) }}" 
+                                       class="text-blue-600 hover:text-blue-800" title="Просмотр">
+                                        👁️
+                                    </a>
+                                    <a href="{{ route('form-data.edit', $item->id) }}" 
+                                       class="text-yellow-600 hover:text-yellow-800" title="Редактировать">
+                                        ✏️
+                                    </a>
+                                    <form action="{{ route('form-data.destroy', $item->id) }}" 
+                                          method="POST" 
+                                          class="inline"
+                                          onsubmit="return confirm('Удалить эту запись?')">
+                                        @csrf
+                                        @method('DELETE')
+                                        <button type="submit" 
+                                                class="text-red-600 hover:text-red-800" 
+                                                title="Удалить">
+                                            🗑️
+                                        </button>
+                                    </form>
+                                </div>
+                            </td>
                         </tr>
                         @endforeach
                     </tbody>
                 </table>
             </div>
-        @endif
+            
+            
+            <div class="px-6 py-4 border-t border-gray-200">
+                {{ $data->onEachSide(1)->links('pagination::simple-bootstrap-5') }}
+            </div>
+        </div>
+
+        
+        <div class="mt-6 grid grid-cols-1 md:grid-cols-4 gap-4">
+            <div class="bg-white rounded-lg shadow p-4">
+                <div class="text-sm text-gray-500">Всего записей</div>
+                <div class="text-2xl font-bold text-gray-800">{{ $data->total() }}</div>
+            </div>
+            <div class="bg-white rounded-lg shadow p-4">
+                <div class="text-sm text-gray-500">Мужчины</div>
+                <div class="text-2xl font-bold text-blue-600">
+                    {{ \App\Models\FormData::male()->count() }}
+                </div>
+            </div>
+            <div class="bg-white rounded-lg shadow p-4">
+                <div class="text-sm text-gray-500">Женщины</div>
+                <div class="text-2xl font-bold text-pink-600">
+                    {{ \App\Models\FormData::female()->count() }}
+                </div>
+            </div>
+            <div class="bg-white rounded-lg shadow p-4">
+                <div class="text-sm text-gray-500">Сегодня</div>
+                <div class="text-2xl font-bold text-green-600">
+                    {{ \App\Models\FormData::today()->count() }}
+                </div>
+            </div>
+        </div>
+    @endif
+    
+    <div class="mt-8 bg-gray-50 rounded-lg p-6">
+        <h5 class="text-lg font-semibold text-gray-800 mb-4">API Endpoints</h5>
+        <div class="space-y-2">
+            <div class="flex items-center">
+                <span class="bg-blue-100 text-blue-800 text-xs font-medium px-2 py-1 rounded mr-2">GET</span>
+                <code class="text-sm">/api/v1/form-data</code>
+                <span class="ml-2 text-gray-600">— Список данных</span>
+            </div>
+            <div class="flex items-center">
+                <span class="bg-green-100 text-green-800 text-xs font-medium px-2 py-1 rounded mr-2">POST</span>
+                <code class="text-sm">/api/v1/form-data</code>
+                <span class="ml-2 text-gray-600">— Создание записи</span>
+            </div>
+            <div class="flex items-center">
+                <span class="bg-yellow-100 text-yellow-800 text-xs font-medium px-2 py-1 rounded mr-2">GET</span>
+                <code class="text-sm">/api/v1/form-data/statistics</code>
+                <span class="ml-2 text-gray-600">— Статистика</span>
+            </div>
+        </div>
     </div>
 </div>
 @endsection

+ 139 - 0
resources/views/form-data/edit.blade.php

@@ -0,0 +1,139 @@
+@extends('layouts.app')
+
+@section('title', 'Редактирование данных формы')
+
+@section('content')
+<div class="container mx-auto px-4 py-8">
+    <div class="max-w-2xl mx-auto bg-white rounded-lg shadow-md p-6">
+        <div class="mb-6">
+            <h4 class="text-2xl font-bold text-gray-800">Редактирование данных формы #{{ $formData->id }}</h4>
+            <p class="text-gray-600 mt-2">Измените необходимые поля</p>
+        </div>
+        
+        <form method="POST" action="{{ route('form-data.update', $formData->id) }}" class="space-y-6">
+            @csrf
+            @method('PUT')
+            
+            <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
+                <div>
+                    <label for="name" class="block text-sm font-medium text-gray-700 mb-1">
+                        Имя *
+                    </label>
+                    <input type="text" 
+                           id="name" 
+                           name="name" 
+                           value="{{ old('name', $formData->name) }}" 
+                           required
+                           class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition">
+                    @error('name')
+                        <div class="mt-1 text-sm text-red-600">{{ $message }}</div>
+                    @enderror
+                </div>
+
+                <div>
+                    <label for="email" class="block text-sm font-medium text-gray-700 mb-1">
+                        Email *
+                    </label>
+                    <input type="email" 
+                           id="email" 
+                           name="email" 
+                           value="{{ old('email', $formData->email) }}" 
+                           required
+                           class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition">
+                    @error('email')
+                        <div class="mt-1 text-sm text-red-600">{{ $message }}</div>
+                    @enderror
+                </div>
+            </div>
+
+            <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
+                <div>
+                    <label for="phone" class="block text-sm font-medium text-gray-700 mb-1">
+                        Телефон *
+                    </label>
+                    <input type="tel" 
+                           id="phone" 
+                           name="phone" 
+                           value="{{ old('phone', $formData->phone) }}" 
+                           required
+                           class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition">
+                    @error('phone')
+                        <div class="mt-1 text-sm text-red-600">{{ $message }}</div>
+                    @enderror
+                </div>
+
+                <div>
+                    <label for="category_id" class="block text-sm font-medium text-gray-700 mb-1">
+                        Категория
+                    </label>
+                    <select id="category_id" 
+                            name="category_id"
+                            class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition">
+                        <option value="">Выберите категорию</option>
+                        @foreach($categories as $category)
+                            <option value="{{ $category->id }}" {{ old('category_id', $formData->category_id) == $category->id ? 'selected' : '' }}>
+                                {{ $category->name }}
+                            </option>
+                        @endforeach
+                    </select>
+                    @error('category_id')
+                        <div class="mt-1 text-sm text-red-600">{{ $message }}</div>
+                    @enderror
+                </div>
+            </div>
+
+            <div>
+                <label class="block text-sm font-medium text-gray-700 mb-3">
+                    Пол *
+                </label>
+                <div class="flex space-x-4">
+                    <label class="inline-flex items-center">
+                        <input type="radio" 
+                               name="gender" 
+                               value="1" 
+                               {{ old('gender', $formData->gender) == 1 ? 'checked' : '' }}
+                               class="h-4 w-4 text-blue-600 focus:ring-blue-500">
+                        <span class="ml-2 text-gray-700">Мужской</span>
+                    </label>
+                    <label class="inline-flex items-center">
+                        <input type="radio" 
+                               name="gender" 
+                               value="0" 
+                               {{ old('gender', $formData->gender) == 0 ? 'checked' : '' }}
+                               class="h-4 w-4 text-blue-600 focus:ring-blue-500">
+                        <span class="ml-2 text-gray-700">Женский</span>
+                    </label>
+                </div>
+                @error('gender')
+                    <div class="mt-1 text-sm text-red-600">{{ $message }}</div>
+                @enderror
+            </div>
+
+            <div>
+                <label for="message" class="block text-sm font-medium text-gray-700 mb-1">
+                    Сообщение *
+                </label>
+                <textarea id="message" 
+                          name="message" 
+                          rows="5" 
+                          required
+                          class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition">{{ old('message', $formData->message) }}</textarea>
+                @error('message')
+                    <div class="mt-1 text-sm text-red-600">{{ $message }}</div>
+                @enderror
+            </div>
+
+            <div class="flex justify-end space-x-4">
+                <a href="{{ route('form-data.show', $formData->id) }}" 
+                   class="px-6 py-2 border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50 transition">
+                    Отмена
+                </a>
+                <button type="submit" 
+                        class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:ring-4 focus:ring-blue-300 transition">
+                    Обновить
+                </button>
+            </div>
+        </form>
+    </div>
+</div>
+@endsection

+ 166 - 0
resources/views/form-data/show.blade.php

@@ -0,0 +1,166 @@
+@extends('layouts.app')
+
+@section('title', 'Просмотр данных формы')
+
+@section('content')
+<div class="container mx-auto px-4 py-8">
+    <div class="max-w-4xl mx-auto">
+        <div class="flex justify-between items-center mb-6">
+            <div>
+                <h4 class="text-2xl font-bold text-gray-800">Данные формы #{{ $formData->id }}</h4>
+                <p class="text-gray-600 text-sm">UUID: {{ $formData->uuid }}</p>
+            </div>
+            <div class="flex space-x-2">
+                <a href="{{ route('form-data.edit', $formData->id) }}" 
+                   class="px-4 py-2 bg-yellow-500 text-white rounded hover:bg-yellow-600 transition">
+                    Редактировать
+                </a>
+                <form action="{{ route('form-data.destroy', $formData->id) }}" method="POST" class="inline">
+                    @csrf
+                    @method('DELETE')
+                    <button type="submit" 
+                            class="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600 transition"
+                            onclick="return confirm('Удалить эту запись?')">
+                        Удалить
+                    </button>
+                </form>
+                <a href="{{ route('data.show') }}" 
+                   class="px-4 py-2 bg-gray-500 text-white rounded hover:bg-gray-600 transition">
+                    Назад к списку
+                </a>
+            </div>
+        </div>
+
+        <div class="bg-white rounded-lg shadow-md p-6 mb-6">
+            <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
+                <div>
+                    <h5 class="text-lg font-semibold text-gray-700 mb-4">Персональные данные</h5>
+                    <div class="space-y-3">
+                        <div>
+                            <span class="text-gray-600 text-sm">Имя:</span>
+                            <p class="text-gray-800 font-medium">{{ $formData->name }}</p>
+                        </div>
+                        <div>
+                            <span class="text-gray-600 text-sm">Email:</span>
+                            <p class="text-gray-800 font-medium">{{ $formData->email }}</p>
+                        </div>
+                        <div>
+                            <span class="text-gray-600 text-sm">Телефон:</span>
+                            <p class="text-gray-800 font-medium">{{ $formData->phone }}</p>
+                        </div>
+                        <div>
+                            <span class="text-gray-600 text-sm">Пол:</span>
+                            <p class="text-gray-800 font-medium">{{ $formData->gender ? 'Мужской' : 'Женский' }}</p>
+                        </div>
+                    </div>
+                </div>
+                
+                <div>
+                    <h5 class="text-lg font-semibold text-gray-700 mb-4">Дополнительная информация</h5>
+                    <div class="space-y-3">
+                        <div>
+                            <span class="text-gray-600 text-sm">Категория:</span>
+                            <p class="text-gray-800 font-medium">
+                                {{ $formData->category ? $formData->category->name : 'Не указана' }}
+                            </p>
+                        </div>
+                        <div>
+                            <span class="text-gray-600 text-sm">Дата отправки:</span>
+                            <p class="text-gray-800 font-medium">
+                                {{ $formData->submitted_at->format('d.m.Y H:i') }}
+                            </p>
+                        </div>
+                        <div>
+                            <span class="text-gray-600 text-sm">Создано:</span>
+                            <p class="text-gray-800 font-medium">
+                                {{ $formData->created_at->format('d.m.Y H:i') }}
+                            </p>
+                        </div>
+                        <div>
+                            <span class="text-gray-600 text-sm">Обновлено:</span>
+                            <p class="text-gray-800 font-medium">
+                                {{ $formData->updated_at->format('d.m.Y H:i') }}
+                            </p>
+                        </div>
+                    </div>
+                </div>
+            </div>
+
+            <div class="mt-6">
+                <h5 class="text-lg font-semibold text-gray-700 mb-4">Сообщение</h5>
+                <div class="bg-gray-50 rounded p-4">
+                    <p class="text-gray-800 whitespace-pre-line">{{ $formData->message }}</p>
+                </div>
+            </div>
+        </div>
+
+        <div class="bg-white rounded-lg shadow-md p-6">
+            <div class="flex justify-between items-center mb-6">
+                <h5 class="text-lg font-semibold text-gray-700">Комментарии ({{ $formData->comments->count() }})</h5>
+                <button onclick="toggleCommentForm()"
+                        class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition text-sm">
+                    Добавить комментарий
+                </button>
+            </div>
+
+            <div id="commentForm" class="hidden mb-6">
+                    <form action="/form-data/{{ $formData->id }}/comment" method="POST">
+                    @csrf
+                    <div class="mb-4">
+                        <textarea name="content" 
+                                  rows="3" 
+                                  required
+                                  class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
+                                  placeholder="Введите ваш комментарий"></textarea>
+                    </div>
+                    <div class="flex justify-end space-x-2">
+                        <button type="button" 
+                                onclick="toggleCommentForm()"
+                                class="px-4 py-2 border border-gray-300 text-gray-700 rounded hover:bg-gray-50 transition">
+                            Отмена
+                        </button>
+                        <button type="submit" 
+                                class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 transition">
+                            Отправить
+                        </button>
+                    </div>
+                </form>
+            </div>
+
+            @if($formData->comments->count() > 0)
+                <div class="space-y-4">
+                    @foreach($formData->comments as $comment)
+                        <div class="border-l-4 border-blue-500 pl-4 py-2">
+                            <div class="flex justify-between items-start mb-2">
+                                <div>
+                                    <p class="font-medium text-gray-800">
+                                        {{ $comment->user ? $comment->user->name : 'Аноним' }}
+                                    </p>
+                                    <p class="text-sm text-gray-500">
+                                        {{ $comment->created_at->format('d.m.Y H:i') }}
+                                    </p>
+                                </div>
+                                @if($comment->is_banned)
+                                    <span class="px-2 py-1 bg-green-100 text-green-800 text-xs rounded">
+                                        Одобрено
+                                    </span>
+                                @endif
+                            </div>
+                            <p class="text-gray-700">{{ $comment->content }}</p>
+                        </div>
+                    @endforeach
+                </div>
+            @else
+                <p class="text-gray-500 text-center py-4">Комментариев пока нет</p>
+            @endif
+        </div>
+    </div>
+</div>
+
+<script>
+function toggleCommentForm() {
+    const form = document.getElementById('commentForm');
+    form.classList.toggle('hidden');
+}
+</script>
+@endsection

+ 124 - 35
resources/views/form.blade.php

@@ -3,63 +3,152 @@
 @section('title', 'Форма отправки')
 
 @section('content')
-<div>
-    <div>
+<div class="container mx-auto px-4 py-8">
+    <div class="max-w-2xl mx-auto bg-white rounded-lg shadow-md p-6">
+        <div class="mb-6">
+            <h4 class="text-2xl font-bold text-gray-800">Форма обратной связи</h4>
+            <p class="text-gray-600 mt-2">Заполните все обязательные поля (*)</p>
+        </div>
+        
         <div>
-            <div>
-                <h4>Форма обратной связи</h4>
-            </div>
-            <div>
-                <form method="POST" action="{{ route('form.submit') }}">
-                    @csrf
-                    
+            <form method="POST" action="{{ route('form.submit') }}" class="space-y-6">
+                @csrf
+                
+                <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                     <div>
-                        <label for="name">Имя *</label>
-                        <input type="text"   
-                               id="name" name="name" value="{{ old('name') }}" required>
+                        <label for="name" class="block text-sm font-medium text-gray-700 mb-1">
+                            Имя *
+                        </label>
+                        <input type="text" 
+                               id="name" 
+                               name="name" 
+                               value="{{ old('name') }}" 
+                               required
+                               class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
+                               placeholder="Введите ваше имя">
                         @error('name')
-                            <div>{{ $message }}</div>
+                            <div class="mt-1 text-sm text-red-600">{{ $message }}</div>
                         @enderror
                     </div>
 
                     <div>
-                        <label for="email">Email *</label>
-                        <input type="email"   
-                               id="email" name="email" value="{{ old('email') }}" required>
+                        <label for="email" class="block text-sm font-medium text-gray-700 mb-1">
+                            Email *
+                        </label>
+                        <input type="email" 
+                               id="email" 
+                               name="email" 
+                               value="{{ old('email') }}" 
+                               required
+                               class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
+                               placeholder="example@email.com">
                         @error('email')
-                            <div>{{ $message }}</div>
+                            <div class="mt-1 text-sm text-red-600">{{ $message }}</div>
                         @enderror
                     </div>
+                </div>
 
+                <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                     <div>
-                        <label for="phone">Phone *</label>
-                        <input type="phone"   
-                               id="phone" name="phone" value="{{ old('phone') }}" required>
+                        <label for="phone" class="block text-sm font-medium text-gray-700 mb-1">
+                            Телефон *
+                        </label>
+                        <input type="tel" 
+                               id="phone" 
+                               name="phone" 
+                               value="{{ old('phone') }}" 
+                               required
+                               class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
+                               placeholder="79991234567">
                         @error('phone')
-                            <div>{{ $message }}</div>
+                            <div class="mt-1 text-sm text-red-600">{{ $message }}</div>
                         @enderror
                     </div>
 
                     <div>
-                        <label for="gender">gender *</label>
-                        <input type="checkbox" name="gender" value="1" @checked(old("terms"))>
-                        @error('gender')
-                            <div>{{ $message }}</div>
+                        <label for="category_id" class="block text-sm font-medium text-gray-700 mb-1">
+                            Категория
+                        </label>
+                        <select id="category_id" 
+                                name="category_id"
+                                class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition">
+                            <option value="">Выберите категорию</option>
+                            @foreach($categories as $category)
+                                <option value="{{ $category->id }}" {{ old('category_id') == $category->id ? 'selected' : '' }}>
+                                    {{ $category->name }}
+                                </option>
+                            @endforeach
+                        </select>
+                        @error('category_id')
+                            <div class="mt-1 text-sm text-red-600">{{ $message }}</div>
                         @enderror
                     </div>
+                </div>
 
-                    <div>
-                        <label for="message">Сообщение *</label>
-                        <textarea   
-                                  id="message" name="message" rows="5" required>{{ old('message') }}</textarea>
-                        @error('message')
-                            <div>{{ $message }}</div>
-                        @enderror
+                <div>
+                    <label class="block text-sm font-medium text-gray-700 mb-3">
+                        Пол *
+                    </label>
+                    <div class="flex space-x-4">
+                        <label class="inline-flex items-center">
+                            <input type="radio" 
+                                   name="gender" 
+                                   value="1" 
+                                   {{ old('gender') == '1' ? 'checked' : '' }}
+                                   class="h-4 w-4 text-blue-600 focus:ring-blue-500">
+                            <span class="ml-2 text-gray-700">Мужской</span>
+                        </label>
+                        <label class="inline-flex items-center">
+                            <input type="radio" 
+                                   name="gender" 
+                                   value="0" 
+                                   {{ old('gender') == '0' ? 'checked' : '' }}
+                                   class="h-4 w-4 text-blue-600 focus:ring-blue-500">
+                            <span class="ml-2 text-gray-700">Женский</span>
+                        </label>
                     </div>
+                    @error('gender')
+                        <div class="mt-1 text-sm text-red-600">{{ $message }}</div>
+                    @enderror
+                </div>
+
+                <div>
+                    <label for="message" class="block text-sm font-medium text-gray-700 mb-1">
+                        Сообщение *
+                    </label>
+                    <textarea id="message" 
+                              name="message" 
+                              rows="5" 
+                              required
+                              class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
+                              placeholder="Введите ваше сообщение (минимум 10 символов)">{{ old('message') }}</textarea>
+                    @error('message')
+                        <div class="mt-1 text-sm text-red-600">{{ $message }}</div>
+                    @enderror
+                </div>
+
+                <div>
+                    <label for="comment" class="block text-sm font-medium text-gray-700 mb-1">
+                        Комментарий (необязательно)
+                    </label>
+                    <textarea id="comment" 
+                              name="comment" 
+                              rows="2"
+                              class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 transition"
+                              placeholder="Добавьте комментарий, если необходимо">{{ old('comment') }}</textarea>
+                </div>
 
-                    <button type="submit">Отправить</button>
-                </form>
-            </div>
+                <div class="flex justify-end space-x-4">
+                    <button type="reset" 
+                            class="px-6 py-2 border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50 transition">
+                        Сбросить
+                    </button>
+                    <button type="submit" 
+                            class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:ring-4 focus:ring-blue-300 transition">
+                        Отправить
+                    </button>
+                </div>
+            </form>
         </div>
     </div>
 </div>

+ 14 - 0
routes/api.php

@@ -0,0 +1,14 @@
+<?php
+
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Route;
+use App\Http\Controllers\Api\FormDataController;
+
+Route::middleware('api')->prefix('v1')->name('api.')->group(function () {
+    Route::apiResource('form-data', FormDataController::class);
+    
+    Route::post('/form-data/{id}/comment', [FormDataController::class, 'addComment'])
+        ->name('api.form-data.comment');
+    // Route::get('/form-data/statistics', [FormDataController::class, 'statistics'])
+    //     ->name('api.form-data.statistics');
+});

+ 16 - 1
routes/web.php

@@ -2,11 +2,26 @@
 
 use Illuminate\Support\Facades\Route;
 use App\Http\Controllers\FormController;
+use App\Http\Controllers\CategoryController;
 
 Route::get('/', function () {
     return view('welcome');
 });
 
+// Основные маршруты формы
 Route::get('/form', [FormController::class, 'showForm'])->name('form.show');
 Route::post('/form', [FormController::class, 'submitForm'])->name('form.submit');
-Route::get('/data', [FormController::class, 'showData'])->name('data.show');
+Route::get('/data', [FormController::class, 'showData'])->name('data.show');
+
+// Маршруты для работы с данными формы
+Route::prefix('form-data')->name('form-data.')->group(function () {
+    Route::get('/{id}', [FormController::class, 'show'])->name('show');
+    Route::get('/{id}/edit', [FormController::class, 'edit'])->name('edit');
+    Route::put('/{id}', [FormController::class, 'update'])->name('update');
+    Route::delete('/{id}', [FormController::class, 'destroy'])->name('destroy');
+    Route::post('/{id}/comment', [FormController::class, 'addComment'])->name('comment');
+});
+Route::resource('categories', CategoryController::class)->except(['show']);
+Route::get('/form-data/statistics', [FormController::class, 'statistics'])->name('api.form-data.statistics');
+
+Route::apiResource('form-data', FormDataController::class);