zapnetapi

buat model dan migration

php artisan make:model NamaModel -m

buat folder app/Interfaces

buat folder app/Repositories

buat provider

php artisan make:provider RepositoryServiceProvider

buat file app/Interfaces/NamaRepositoryInterface.php

buat file app/Repositories/NamaRepository.php

buat register app/Providers/RepositoryServiceProvider.php

buat controller

php artisan make:controller NamaController --api

buat resource

php artisan make:resource NamaResource

buat app/Http/Resources/PaginatedResource.php

buat app/route/api

buat factory

php artisan make:factory NamaFactory

buat seeder

php artisan make:seed NamaSeeder

buat data

php artisan db:seed NamaSeeder

buat request

php artisan make:request NamaStoreRequest
php artisan make:request NamaUpdateRequest

buat bahasa

php artisan lang:publish

buat bahasa indinesia lang/id/validation.php

buat permission

buat folder dan file app/Traits/UUID.php

<?php

namespace App\Traits;

use Illuminate\Support\Str;

trait UUID
{
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($model) {
            if ($model->getKey() === null) {
                $model->setAttribute($model->getKeyName(), Str::uuid()->toString());
            }
        });
    }

    public function getIncrementing()
    {
        return false;
    }

    public function getKeyType()
    {
        return 'String';
    }
}

buat folder dan file app/Helpers/ResponseHelper.php

<?php

/**
 * supaya response dari api nya tidak berantakan
 * agar sesuai dengan ini
 */

namespace App\Helpers;

use Illuminate\Http\JsonResponse;

class ResponseHelper
{
    public static function jsonResponse($success, $message, $data, $statusCode): JsonResponse
    {
        return response()->json([
            'success' => $success,
            'message' => $message,
            'data' => $data,
        ], $statusCode);
    }
}

Pasang api

php artisan install:api
php artisan make:model PersonalAccessToken

edit app/Models/PersonalAccessToken.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Str;
use Laravel\Sanctum\PersonalAccessToken as SanctumPersonalAccessToken;


class PersonalAccessToken extends SanctumPersonalAccessToken
{
    use HasFactory;
    //     public $keyType = 'string';

    //     public $incrementing = false;

    //     public static function boot()
    //     {
    //         parent::boot();

    //         static::creating(function ($model) {
    //             $model->id = (string) Str::uuid();
    //         });
    //     }
    // }

    protected $primaryKey = 'uuid';   // 👈 kasih tahu primary key
    public $incrementing = false;
    protected $keyType = 'string';

    protected static function boot()
    {
        parent::boot();

        static::creating(function ($model) {
            if (empty($model->uuid)) {
                $model->uuid = (string) Str::uuid();
            }
        });
    }
}

edit app/Providers/AppServiceProvider.php

<?php

namespace App\Providers;

use App\Models\PersonalAccessToken;
use Illuminate\Support\ServiceProvider;
use Laravel\Sanctum\Sanctum;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        //
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        //
        Sanctum::usePersonalAccessTokenModel(PersonalAccessToken::class);
    }
}

edit database/migrations/2025_09_17_131012_create_personal_access_tokens_table.php

<?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('personal_access_tokens', function (Blueprint $table) {
            $table->uuid()->primary(); // ubah menjadi uuid dan primary
            $table->uuidMorphs('tokenable'); // ubah menjadi uuid
            $table->text('name');
            $table->string('token', 64)->unique();
            $table->text('abilities')->nullable();
            $table->timestamp('last_used_at')->nullable();
            $table->timestamp('expires_at')->nullable()->index();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('personal_access_tokens');
    }
};

Pasang spatie/laravel-permission

composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"

edit bootstrap/providers.php

<?php

return [
    App\Providers\AppServiceProvider::class,
    Spatie\Permission\PermissionServiceProvider::class, // Tambahkan
];

edit bootstrap/app.php

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__ . '/../routes/web.php',
        api: __DIR__ . '/../routes/api.php',
        commands: __DIR__ . '/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware): void {

        // Tambahkan ==================================
        $middleware->alias([
            'role' => \Spatie\Permission\Middleware\RoleMiddleware::class,
            'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class,
            'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class,
        ]);
        // ===========================================

    })
    ->withExceptions(function (Exceptions $exceptions): void {
        //
    })->create();

buat PermissionSeeder

php artisan make:seeder PermissionSeeder

edit semua database/seeders/PermissionSeeder.php dengan

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;

class PermissionSeeder extends Seeder
{
    private $permissions = [
        'dashboard' => [
            'menu'
        ],

        'head-of-family' => [
            'menu',
            'list',
            'create',
            'edit',
            'delete'
        ],

        'family-member' => [
            'menu',
            'list',
            'create',
            'edit',
            'delete'
        ],

        'social-assistance' => [
            'menu',
            'list',
            'create',
            'edit',
            'delete'
        ],

        'social-assistance-recipient' => [
            'menu',
            'list',
            'create',
            'edit',
            'delete'
        ],

        'event' => [
            'menu',
            'list',
            'create',
            'edit',
            'delete'
        ],

        'event-participant' => [
            'menu',
            'list',
            'create',
            'edit',
            'delete'
        ],

        'development' => [
            'menu',
            'list',
            'create',
            'edit',
            'delete'
        ],

        'development-applicant' => [
            'menu',
            'list',
            'create',
            'edit',
            'delete'
        ],

        'profile' => [
            'menu',
            'create',
            'edit',
        ],


    ];
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        foreach ($this->permissions as $key => $value) {
            foreach ($value as $permission) {
                Permission::firstOrCreate([
                    'name' => $key . '-' . $permission,
                    'guard_name' => 'sanctum'
                ]);
            }
        }
    }
}

edit database/migrations/2025_09_04_105112_create_permission_tables.php , ganti semua supaya gampang ,jika menggunakan uuid ,jika tidak abaikan step ini

<?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
    {
        $teams = config('permission.teams');
        $tableNames = config('permission.table_names');
        $columnNames = config('permission.column_names');
        $pivotRole = $columnNames['role_pivot_key'] ?? 'role_id';
        $pivotPermission = $columnNames['permission_pivot_key'] ?? 'permission_id';

        if (empty($tableNames)) {
            throw new \Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.');
        }
        if ($teams && empty($columnNames['team_foreign_key'] ?? null)) {
            throw new \Exception('Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.');
        }

        Schema::create($tableNames['permissions'], function (Blueprint $table) {
            $table->bigIncrements('id'); // permission id
            $table->string('name');       // For MySQL 8.0 use string('name', 125);
            $table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125);
            $table->timestamps();

            $table->unique(['name', 'guard_name']);
        });

        Schema::create($tableNames['roles'], function (Blueprint $table) use ($teams, $columnNames) {
            $table->bigIncrements('id'); // role id
            if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing
                $table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable();
                $table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index');
            }
            $table->string('name');       // For MySQL 8.0 use string('name', 125);
            $table->string('guard_name'); // For MySQL 8.0 use string('guard_name', 125);
            $table->timestamps();
            if ($teams || config('permission.testing')) {
                $table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']);
            } else {
                $table->unique(['name', 'guard_name']);
            }
        });

        Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames, $pivotPermission, $teams) {
            $table->unsignedBigInteger($pivotPermission);

            $table->string('model_type');
            $table->uuid($columnNames['model_morph_key']);
            $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index');

            $table->foreign($pivotPermission)
                ->references('id') // permission id
                ->on($tableNames['permissions'])
                ->onDelete('cascade');
            if ($teams) {
                $table->unsignedBigInteger($columnNames['team_foreign_key']);
                $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index');

                $table->primary(
                    [$columnNames['team_foreign_key'], $pivotPermission, $columnNames['model_morph_key'], 'model_type'],
                    'model_has_permissions_permission_model_type_primary'
                );
            } else {
                $table->primary(
                    [$pivotPermission, $columnNames['model_morph_key'], 'model_type'],
                    'model_has_permissions_permission_model_type_primary'
                );
            }
        });

        Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames, $pivotRole, $teams) {
            $table->unsignedBigInteger($pivotRole);

            $table->string('model_type');
            $table->uuid($columnNames['model_morph_key']);
            $table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index');

            $table->foreign($pivotRole)
                ->references('id') // role id
                ->on($tableNames['roles'])
                ->onDelete('cascade');
            if ($teams) {
                $table->unsignedBigInteger($columnNames['team_foreign_key']);
                $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index');

                $table->primary(
                    [$columnNames['team_foreign_key'], $pivotRole, $columnNames['model_morph_key'], 'model_type'],
                    'model_has_roles_role_model_type_primary'
                );
            } else {
                $table->primary(
                    [$pivotRole, $columnNames['model_morph_key'], 'model_type'],
                    'model_has_roles_role_model_type_primary'
                );
            }
        });

        Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames, $pivotRole, $pivotPermission) {
            $table->unsignedBigInteger($pivotPermission);
            $table->unsignedBigInteger($pivotRole);

            $table->foreign($pivotPermission)
                ->references('id') // permission id
                ->on($tableNames['permissions'])
                ->onDelete('cascade');

            $table->foreign($pivotRole)
                ->references('id') // role id
                ->on($tableNames['roles'])
                ->onDelete('cascade');

            $table->primary([$pivotPermission, $pivotRole], 'role_has_permissions_permission_id_role_id_primary');
        });

        app('cache')
            ->store(config('permission.cache.store') != 'default' ? config('permission.cache.store') : null)
            ->forget(config('permission.cache.key'));
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        $tableNames = config('permission.table_names');

        if (empty($tableNames)) {
            throw new \Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.');
        }

        Schema::drop($tableNames['role_has_permissions']);
        Schema::drop($tableNames['model_has_roles']);
        Schema::drop($tableNames['model_has_permissions']);
        Schema::drop($tableNames['roles']);
        Schema::drop($tableNames['permissions']);
    }
};

buat RoleSeeder

php artisan make:seeder RoleSeeder

edit database/seeders/RoleSeeder.php

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

class RoleSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        Role::firstOrCreate([
            'name' => 'admin',
            'guard_name' => 'sanctum'
        ])->givePermissionTo(Permission::all());

        Role::firstOrCreate([
            'name' => 'head-of-family',
            'guard_name' => 'sanctum'
        ])->givePermissionTo([
            'dashboard-menu',

            'family-member-menu',
            'family-member-list',
            'family-member-create',
            'family-member-edit',
            'family-member-delete',

            'social-assistance-menu',
            'social-assistance-list',

            'social-assistance-recipient-menu',
            'social-assistance-recipient-list',
            'social-assistance-recipient-create',
            'social-assistance-recipient-edit',
            'social-assistance-recipient-delete',

            'event-menu',
            'event-list',

            'event-participant-menu',
            'event-participant-list',
            'event-participant-create',
            'event-participant-edit',
            'event-participant-delete',

            'development-menu',
            'development-list',

            'development-applicant-menu',
            'development-applicant-list',
            'development-applicant-create',
            'development-applicant-edit',
            'development-applicant-delete',

            'profile-menu',

        ]);
    }
}

edit config/auth.php

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option defines the default authentication "guard" and password
    | reset "broker" for your application. You may change these values
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard' => env('AUTH_GUARD', 'sanctum'), // edit dari web menjadi sanctum
        'passwords' => env('AUTH_PASSWORD_BROKER', 'users'),
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | which utilizes session storage plus the Eloquent user provider.
    |
    | All authentication guards have a user provider, which defines how the
    | users are actually retrieved out of your database or other storage
    | system used by the application. Typically, Eloquent is utilized.
    |
    | Supported: "session"
    |
    */

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        // Tambahan ======================
        'api' => [
            'driver' => 'sanctum',
            'provider' => 'users',
            'hash' => 'false',
        ],

        'sanctum' => [
            'driver' => 'sanctum',
            'provider' => 'users',
            'hash' => 'false',
        ],
        // =================================
    ],

buat app/Interfaces/AuthRepositoryInterface.php

<?php

/**
 * definisikan fungsi fungsi yang akan kita buat
 */

namespace App\Interfaces;

interface AuthRepositoryInterface
{
    public function login(
        array $data
    );

    public function logout();
    public function me();
}

buat app/Repositories/AuthRepository.php

<?php

namespace App\repositories;

use App\Http\Resources\HeadOfFamilyResource;
use App\Interfaces\AuthRepositoryInterface;
use App\Models\Event;
use Exception;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class AuthRepository implements AuthRepositoryInterface
{

    public function login(array $data)
    {
        if (!Auth::guard('web')->attempt($data)) {
            return response([
                'success' => false,
                'message' => 'Unauthorized',
            ], 401);
        }

        $user = Auth::user();

        $token = $user->createToken('auth_token')->plainTextToken;

        return response()->json([
            'success' => true,
            'token' => $token,
            'message' => "Login Success"
        ]);
    }

    public function logout()
    {


        $user = Auth::user();

        $user->currentAccessToken()->delete();

        $response = [
            'success' => true,
            'message' => "Logout Success"
        ];

        return response($response, 200);
    }

    public function me()
    {
        if (Auth::check()) {
            $user = Auth::user();

            $user->load('roles.permissions');

            $permissions = $user->roles->flatMap->permissions->pluck('name');

            $role = $user->roles->first()->name;

            return response()->json([
                'message' => 'User data',
                'data' => [
                    'id' => $user->id,
                    'name' => $user->name,
                    'email' => $user->email,
                    'permissions' => $permissions,
                    'role' => $role,
                    // 'head_of_family' => new HeadOfFamilyResource($user->headOfFamily)
                    'head_of_family' => $user->headOfFamily
                        ? new HeadOfFamilyResource($user->headOfFamily)
                        : null,


                ],
            ]);
        }
        return response()->json([
            'message' => 'You are not logged in'
        ], 401);
    }
}

buat AuthController

php artisan make:controller AuthController

edit AuthController.php

<?php

namespace App\Http\Controllers;

use App\Http\Requests\LoginStoreRequest;
use App\Interfaces\AuthRepositoryInterface;
use Illuminate\Http\Request;

class AuthController extends Controller
{
    private AuthRepositoryInterface $authRepository;

    public function __construct(AuthRepositoryInterface $authRepository)
    {
        $this->authRepository = $authRepository;
    }

    public function login(LoginStoreRequest $request)
    {
        $request = $request->validated();

        return $this->authRepository->login($request);
    }

    public function logout()
    {

        return $this->authRepository->logout();
    }

    public function me()
    {
        return $this->authRepository->me();
    }
}

buat request LoginStoreRequest

php artisan make:request LoginStoreRequest

edit app/Http/Requests/LoginStoreRequest.php

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class LoginStoreRequest extends FormRequest
{


    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'email' => 'required|email',
            'password' => 'required'
        ];
    }

    public function attributes()
    {
        return [
            'email' => 'Email',
            'password' => 'Kata Sandi'
        ];
    }
}

edit Models/User.php

<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;

use App\Traits\UUID;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable, UUID, SoftDeletes, HasRoles, HasApiTokens;

    /**
     * The attributes that are mass assignable.
     *
     * @var list<string>
     */
    protected $fillable = ['name', 'email', 'password'];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list<string>
     */
    protected $hidden = ['password', 'remember_token'];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }

    public function scopeSearch($query, $search)
    {
        return $query->where('name', 'like', '%' . $search . '%')
            ->orWhere('email', 'like', '%' . $search . '%');
    }
    // satu user hanya memiliki 1 head family

    public function headOfFamily()
    {
        return $this->hasOne(HeadOfFamily::class);
    }
}

buat UserRepositoryInterface.php

<?php

/**
 * definisikan fungsi fungsi yang akan kita buat
 */

namespace App\Interfaces;

interface UserRepositoryInterface
{
    public function getAll(
        ?string $search, // ketika search langsung di terima di fungsi getall
        ?int $limit, // kita bisa melimit data yang ingin di tampilkan
        bool $execute // akan exe langsung ,tapi di paginasi tidak 
    );

    public function getAllPaginated(
        ?string $search, // ketika search langsung di terima di fungsi getall
        ?int $rowPerPage, // kita bisa melimit data yang ingin di tampilkan
    );

    public function getById(
        string $id
    );

    public function create(
        array $data
    );

    public function update(
        string $id,
        array $data
    );

    public function delete(
        string $id
    );
}

buat UserRepository.php

<?php

namespace App\repositories;

use App\Interfaces\UserRepositoryInterface;
use App\Models\User;
use Exception;
use Illuminate\Support\Facades\DB;

class UserRepository implements UserRepositoryInterface
{
    public function getAll(?string $search, ?int $limit, bool $execute)
    {
        $query = User::where(function ($query) use ($search) {
            //jika ada parameter search dia akan melakukan search, yang kita definisikan pada model user
            if ($search) {
                $query->search($search);
            }
        });

        if ($limit) {
            // take adalah mengambil beberapa berdsarkan limit
            $query->take($limit);
        }

        if ($execute) {
            return $query->get();
        }

        return $query;
    }

    public function getAllPaginated(?string $search, ?int $rowPerPage)
    {
        $query = $this->getAll(
            $search,
            $rowPerPage,
            false
        );

        return $query->paginate($rowPerPage);
    }

    public function getById(string $id)
    {
        $query = User::where('id', $id);

        return $query->first();
    }


    public function create(array $data)
    {
        // jika ada data yang salah tidak akan langsung di dinput 
        DB::beginTransaction();

        try {
            $user = new User;
            $user->name = $data['name'];
            $user->email = $data['email'];
            $user->password = bcrypt($data['password']);
            $user->save();

            DB::commit();

            return $user;
        } catch (\Exception $e) {
            DB::rollBack();

            throw new Exception($e->getMessage());
        }
    }

    public function update(string $id, array $data)
    {
        // jika ada data yang salah tidak akan langsung di dinput 
        DB::beginTransaction();

        try {
            $user = User::find($id);
            $user->name = $data['name'];
            // $user->email = $data['email'];

            if (isset($data['password'])) {
                $user->password = bcrypt($data['password']);
            }

            $user->save();

            DB::commit();

            return $user;
        } catch (\Exception $e) {
            DB::rollBack();

            throw new Exception($e->getMessage());
        }
    }

    public function delete(string $id)
    {
        // jika ada data yang salah tidak akan langsung di dinput 
        DB::beginTransaction();

        try {
            $user = User::find($id);
            $user->delete();

            DB::commit();

            return $user;
        } catch (\Exception $e) {
            DB::rollBack();

            throw new Exception($e->getMessage());
        }
    }
}

register di RepositoryServiceProvider.php

<?php

/**
 * di gunakan untuk mendaftarkan repositories dan interfaces
 */

namespace App\Providers;

use App\Interfaces\AuthRepositoryInterface;
use App\Interfaces\DashboardRepositoryInterface;
use App\Interfaces\DevelopmentApplicantRepositoryInterface;
use App\Interfaces\DevelopmentRepositoryInterface;
use App\Interfaces\EventParticipantRepositoryInterface;
use App\Interfaces\EventRepositoryInterface;
use App\Interfaces\FamilyMemberRepositoryInterface;
use App\Interfaces\HeadOfFamilyRepositoryInterface;
use App\Interfaces\ProfileRepositoryInterface;
use App\Interfaces\SocialAssistanceRecipientRepositoryInterface;
use App\Interfaces\SocialAssistanceRepositoryInterface;
use App\Interfaces\UserRepositoryInterface;
use App\repositories\AuthRepository;
use App\repositories\DashboardRepository;
use App\repositories\DevelopmentApplicantRepository;
use App\repositories\DevelopmentRepository;
use App\repositories\EventParticipantRepository;
use App\repositories\EventRepository;
use App\repositories\FamilyMemberRepository;
use App\repositories\HeadOfFamilyRepository;
use App\repositories\ProfileRepository;
use App\repositories\SocialAssistanceRecipientRepository;
use App\repositories\SocialAssistanceRepository;
use App\repositories\UserRepository;
use Illuminate\Support\ServiceProvider;

class RepositoryServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register(): void
    {
        //
        $this->app->bind(UserRepositoryInterface::class, UserRepository::class);
        $this->app->bind(HeadOfFamilyRepositoryInterface::class, HeadOfFamilyRepository::class);
        $this->app->bind(FamilyMemberRepositoryInterface::class, FamilyMemberRepository::class);
        $this->app->bind(SocialAssistanceRepositoryInterface::class, SocialAssistanceRepository::class);
        $this->app->bind(SocialAssistanceRecipientRepositoryInterface::class, SocialAssistanceRecipientRepository::class);
        $this->app->bind(EventRepositoryInterface::class, EventRepository::class);
        $this->app->bind(EventParticipantRepositoryInterface::class, EventParticipantRepository::class);
        $this->app->bind(DevelopmentRepositoryInterface::class, DevelopmentRepository::class);
        $this->app->bind(DevelopmentApplicantRepositoryInterface::class, DevelopmentApplicantRepository::class);
        $this->app->bind(ProfileRepositoryInterface::class, ProfileRepository::class);
        $this->app->bind(AuthRepositoryInterface::class, AuthRepository::class);
        $this->app->bind(DashboardRepositoryInterface::class, DashboardRepository::class);
    }

    /**
     * Bootstrap services.
     */
    public function boot(): void
    {
        //
    }
}

buat UserResource.php

php artisan make:resource UserResource

edit UserResource.php

<?php

/**
 * menampilkan apa saja yang kita ingin kana agar json rapih
 */

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        // return parent::toArray($request);
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email
        ];
    }
}

Buat UserController

php artisan make:controller UserController --api

Edit UserController.php

<?php

namespace App\Http\Controllers;

use App\Helpers\ResponseHelper;
use App\Http\Requests\UserStoreRequest;
use App\Http\Requests\UserUpdateRequest;
use App\Http\Resources\PaginateResource;
use App\Http\Resources\UserResource;
use App\Interfaces\UserRepositoryInterface;
use Illuminate\Http\Request;

class UserController extends Controller
{
    private UserRepositoryInterface $userRepository;

    public function __construct(UserRepositoryInterface $userRepository)
    {
        $this->userRepository = $userRepository;
    }
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        //
        try {
            $users = $this->userRepository->getAll($request->search, $request->limit, true);
            return ResponseHelper::jsonResponse(true, 'Data User Berhasil Diambil', UserResource::collection($users), 200);
        } catch (\Exception $e) {
            return ResponseHelper::jsonResponse(false, $e->getMessage(), null, 500);
        }
    }

    public function getAllPaginated(Request $request)
    {
        $request = $request->validate([
            'search' => 'nullable|string',
            'row_per_page' => 'required|integer'
        ]);

        try {
            $users = $this->userRepository->getAllPaginated(
                $request['search'] ?? null,
                $request['row_per_page'],
            );
            return ResponseHelper::jsonResponse(true, 'Data User Berhasil Diambil', PaginateResource::make($users, UserResource::class), 200);
        } catch (\Exception $e) {
            return ResponseHelper::jsonResponse(false, $e->getMessage(), null, 500);
        }
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(UserStoreRequest $request)
    {
        $request = $request->validated();

        try {
            $user = $this->userRepository->create($request);
            return ResponseHelper::jsonResponse(true, 'User berhasil ditambahkan', new UserResource($user), 201);
        } catch (\Exception $e) {
            return ResponseHelper::jsonResponse(false, $e->getMessage(), null, 500);
        }
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        try {
            $user = $this->userRepository->getById($id);
            if (!$user) {
                return ResponseHelper::jsonResponse(false, 'User tidak ditemukan', null, 404);
            }
            return ResponseHelper::jsonResponse(true, 'Detail user berhasil di ambil', new UserResource($user), 200);
        } catch (\Exception $e) {
            return ResponseHelper::jsonResponse(false, $e->getMessage(), null, 500);
        }
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(UserUpdateRequest $request, string $id)
    {
        $request = $request->validated();

        try {
            $user = $this->userRepository->getById($id);
            if (!$user) {
                return ResponseHelper::jsonResponse(false, 'User tidak ditemukan', null, 404);
            }

            $user = $this->userRepository->update(
                $id,
                $request
            );

            return ResponseHelper::jsonResponse(true, 'Data user berhasil diupdate', new UserResource($user), 200);
        } catch (\Exception $e) {
            return ResponseHelper::jsonResponse(false, $e->getMessage(), null, 500);
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        try {
            $user = $this->userRepository->getById($id);
            if (!$user) {
                return ResponseHelper::jsonResponse(false, 'User tidak ditemukan', null, 404);
            }

            $user = $this->userRepository->delete(
                $id,
            );

            return ResponseHelper::jsonResponse(true, 'Data user berhasil dihapus', new UserResource($user), 200);
        } catch (\Exception $e) {
            return ResponseHelper::jsonResponse(false, $e->getMessage(), null, 500);
        }
    }
}

buat user store dan update request

php artisan make:request UserStoreRequest
php artisan make:request UserUpdateRequest

edit UserStoreRequest.php

<?php

/**
 * untuk validasi
 */

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UserStoreRequest extends FormRequest
{


    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:8'
        ];
    }

    public function attributes()
    {
        return [
            'name' => 'Nama',
            'email' => 'Email',
            'password' => 'Kata Sandi'
        ];
    }

    // public function messages()
    // {
    //     return [
    //         'required' => ':attribute harus diisi',
    //         'string' => ':attribute harus berupa string',
    //         'max' => ':attribute maksimal :max karakter',
    //         'min' => ':attribute minimal :min karakter',
    //         'unique' => ':attribute sudah ada',
    //         'email' => ':attribute harus berupa email',
    //     ];
    // }
}

edit UserUpdateRequest.php

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UserUpdateRequest extends FormRequest
{


    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {
        return [
            'name' => 'required|string|max:255',
            'password' => 'nullable|string|min:8'
        ];
    }

    public function attributes()
    {
        return [
            'name' => 'Nama',
            'password' => 'Password'
        ];
    }

    // public function messages()
    // {
    //     return [
    //         'required' => ':attribute harus diisi',
    //         'string' => ':attribute harus berupa string',
    //         'max' => ':attribute maksimal :max karakter',
    //         'min' => ':attribute minimal :min karakter',
    //     ];
    // }
}

buat UserSeeder

php artisan make:seeder UserSeeder

edit UserSeeder.php

<?php

namespace Database\Seeders;

use App\Models\User;
use Database\Factories\UserFactory;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class UserSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        //

        User::create([
            'name' => 'Admin',
            'email' => 'admin@app.com',
            'password' => bcrypt('password')
        ])->assignRole('admin');

        User::create([
            'name' => 'Kepala Keluarga',
            'email' => 'headoffamily@app.com',
            'password' => bcrypt('password')
        ])->assignRole('head-of-family');

        UserFactory::new()->count(15)->create();
    }
}

buat PaginateResource.php

edit PaginateResource.php

buat RepositoryServiceProvider.php

edit providers.php

publish lang

php artisan lang:publish

buat lang/id

buat model dan migration HeadOfFamily

php artisan make:model HeadOfFamily -m
php artisan make:interface HeadOfFamilyRepositoryInterface
php artisan make:resource HeadOfFamilyResource
php artisan make:controller HeadOfFamilyController --api
php artisan make:request HeadOfFamilyStoreRequest
php artisan make:request HeadOfFamilyUpdateRequest
php artisan make:factory HeadOfFamilyFactory
php artisan make:seeder HeadOfFamilySeeder

edit

  • edit HeadOfFamily.php
  • edit 2025_09_01_132434_create_head_of_families_table.php
  • edit HeadOfFamilyRepositoryInterface.php
  • buat HeadOfFamilyRepository.php
  • edit RepositoryServiceProvider.php
  • edit HeadOfFamilyResource.php
  • edit HeadOfFamilyController.php
  • edit HeadOfFamilyStoreRequest.php
  • edit HeadOfFamilyUpdateRequest.php
  • edit HeadOfFamilyFactory.php
  • edit HeadOfFamilySeeder.php
  • edit DatabaseSeeder.php
  • edit api.php

Leave a Reply