create user login activity
This commit is contained in:
44
app/Http/Controllers/ActivityController.php
Normal file
44
app/Http/Controllers/ActivityController.php
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\DataTableRequest;
|
||||||
|
use App\Models\Login;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Inertia\Inertia;
|
||||||
|
|
||||||
|
class ActivityController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function login()
|
||||||
|
{
|
||||||
|
return Inertia::render('Superuser/Activity/Login');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \App\Http\Requests\DataTableRequest $request
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function logins(DataTableRequest $request)
|
||||||
|
{
|
||||||
|
$request->validated();
|
||||||
|
|
||||||
|
return Login::join('users', 'login_activities.user_id', '=', 'users.id')
|
||||||
|
->where(function (Builder $query) use ($request) {
|
||||||
|
$search = '%' . $request->search . '%';
|
||||||
|
|
||||||
|
$query->where('users.name', 'like', $search)
|
||||||
|
->orWhere('users.username', 'like', $search)
|
||||||
|
->orWhere('login_activities.ip_address', 'like', $search)
|
||||||
|
->orWhere('login_activities.browser', 'like', $search)
|
||||||
|
->orWhere('login_activities.platform', 'like', $search)
|
||||||
|
->orWhere('login_activities.created_at', 'like', $search);
|
||||||
|
})
|
||||||
|
->select(['users.*', 'login_activities.*'])
|
||||||
|
->orderBy($request->input('order.key') ?: 'created_at', $request->input('order.dir') ?: 'asc')
|
||||||
|
->paginate($request->per_page ?: 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
33
app/Http/Requests/DataTableRequest.php
Normal file
33
app/Http/Requests/DataTableRequest.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class DataTableRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'search' => 'nullable|string',
|
||||||
|
'per_page' => 'nullable|integer|min:0|max:10',
|
||||||
|
'order.key' => 'nullable|string',
|
||||||
|
'order.dir' => 'nullable|in:asc,desc',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,4 +23,12 @@ class Login extends Model
|
|||||||
'browser',
|
'browser',
|
||||||
'platform',
|
'platform',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
|
*/
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->hasOne(User::class, 'id', 'user_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,5 +98,23 @@ class MenuSeeder extends Seeder
|
|||||||
'create menu', 'read menu', 'update menu', 'delete menu',
|
'create menu', 'read menu', 'update menu', 'delete menu',
|
||||||
])->get(['id'])
|
])->get(['id'])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$activities = Menu::create([
|
||||||
|
'name' => 'activities',
|
||||||
|
'icon' => 'address-card',
|
||||||
|
'position' => 3,
|
||||||
|
'deleteable' => false,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$activities->childs()->create([
|
||||||
|
'name' => 'login',
|
||||||
|
'route_or_url' => 'superuser.activity.login',
|
||||||
|
'icon' => 'user-clock',
|
||||||
|
'position' => 1,
|
||||||
|
'deleteable' => false,
|
||||||
|
'actives' => [
|
||||||
|
'superuser.activity.login',
|
||||||
|
],
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
62
resources/js/Pages/Superuser/Activity/Login.vue
Normal file
62
resources/js/Pages/Superuser/Activity/Login.vue
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<script setup>
|
||||||
|
import { getCurrentInstance, ref, onMounted } from 'vue';
|
||||||
|
import DashboardLayout from '@/Layouts/DashboardLayout.vue';
|
||||||
|
import Card from '@/Components/Card.vue';
|
||||||
|
import Icon from '@/Components/Icon.vue';
|
||||||
|
import Builder from '@/Components/DataTable/Builder.vue';
|
||||||
|
import Th from '@/Components/DataTable/Th.vue';
|
||||||
|
|
||||||
|
const self = getCurrentInstance()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DashboardLayout title="Login Activity">
|
||||||
|
<Card class="bg-white dark:bg-gray-700 dark:text-gray-200">
|
||||||
|
<template #header>
|
||||||
|
<div class="flex items-center space-x-2 bg-gray-200 dark:bg-gray-800 p-2">
|
||||||
|
<p class="lowercase first-letter:capitalize font-semibold">login activities</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #body>
|
||||||
|
<Builder :url="route('api.v1.superuser.activity.login')">
|
||||||
|
<template #thead="table">
|
||||||
|
<tr class="bg-gray-200 dark:bg-gray-800 border-gray-300 dark:border-gray-900">
|
||||||
|
<Th class="border px-3 py-2 text-center" :table="table" :sort="false">no</Th>
|
||||||
|
<Th class="border px-3 py-2 text-center whitespace-nowrap" :table="table" :sort="true" name="users.name">name</Th>
|
||||||
|
<Th class="border px-3 py-2 text-center whitespace-nowrap" :table="table" :sort="true" name="users.username">username</Th>
|
||||||
|
<Th class="border px-3 py-2 text-center whitespace-nowrap" :table="table" :sort="true" name="login_activities.ip_address">ip address</Th>
|
||||||
|
<Th class="border px-3 py-2 text-center whitespace-nowrap" :table="table" :sort="true" name="login_activities.browser">browser</Th>
|
||||||
|
<Th class="border px-3 py-2 text-center whitespace-nowrap" :table="table" :sort="true" name="login_activities.platform">platform</Th>
|
||||||
|
<Th class="border px-3 py-2 text-center whitespace-nowrap" :table="table" :sort="true" name="login_activities.created_at">at</Th>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #tfoot="table">
|
||||||
|
<tr class="bg-gray-200 dark:bg-gray-800 border-gray-300 dark:border-gray-900">
|
||||||
|
<Th class="border px-3 py-2 text-center" :table="table" :sort="false">no</Th>
|
||||||
|
<Th class="border px-3 py-2 text-center whitespace-nowrap" :table="table" :sort="false">name</Th>
|
||||||
|
<Th class="border px-3 py-2 text-center whitespace-nowrap" :table="table" :sort="false">username</Th>
|
||||||
|
<Th class="border px-3 py-2 text-center whitespace-nowrap" :table="table" :sort="false">ip address</Th>
|
||||||
|
<Th class="border px-3 py-2 text-center whitespace-nowrap" :table="table" :sort="false">browser</Th>
|
||||||
|
<Th class="border px-3 py-2 text-center whitespace-nowrap" :table="table" :sort="false">platform</Th>
|
||||||
|
<Th class="border px-3 py-2 text-center whitespace-nowrap" :table="table" :sort="false">at</Th>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #tbody="{ data }">
|
||||||
|
<tr v-for="(activity, i) in data" :key="i" class="dark:hover:bg-gray-600 dark:border-gray-800 transition-all">
|
||||||
|
<td class="px-2 py-1 border border-inherit text-center">{{ i + 1 }}</td>
|
||||||
|
<td class="px-2 py-1 border border-inherit uppercase">{{ activity.name }}</td>
|
||||||
|
<td class="px-2 py-1 border border-inherit uppercase">{{ activity.username }}</td>
|
||||||
|
<td class="px-2 py-1 border border-inherit uppercase">{{ activity.ip_address }}</td>
|
||||||
|
<td class="px-2 py-1 border border-inherit uppercase">{{ activity.browser }}</td>
|
||||||
|
<td class="px-2 py-1 border border-inherit uppercase">{{ activity.platform }}</td>
|
||||||
|
<td class="px-2 py-1 border border-inherit uppercase">{{ new Date(activity.created_at).toLocaleString('id') }}</td>
|
||||||
|
</tr>
|
||||||
|
</template>
|
||||||
|
</Builder>
|
||||||
|
</template>
|
||||||
|
</Card>
|
||||||
|
</DashboardLayout>
|
||||||
|
</template>
|
||||||
@@ -22,6 +22,7 @@ Route::prefix('/v1')->name('api.v1.')->group(function () {
|
|||||||
Route::get('/superuser/role', [App\Http\Controllers\Superuser\RoleController::class, 'get'])->name('role');
|
Route::get('/superuser/role', [App\Http\Controllers\Superuser\RoleController::class, 'get'])->name('role');
|
||||||
Route::post('/superuser/role/paginate', [App\Http\Controllers\Superuser\RoleController::class, 'paginate'])->name('role.paginate');
|
Route::post('/superuser/role/paginate', [App\Http\Controllers\Superuser\RoleController::class, 'paginate'])->name('role.paginate');
|
||||||
Route::post('/superuser/user/paginate', [App\Http\Controllers\Superuser\UserController::class, 'paginate'])->name('user.paginate');
|
Route::post('/superuser/user/paginate', [App\Http\Controllers\Superuser\UserController::class, 'paginate'])->name('user.paginate');
|
||||||
|
Route::post('/superuser/activity/login', [App\Http\Controllers\ActivityController::class, 'logins'])->name('activity.login');
|
||||||
Route::get('/superuser/menu', [App\Http\Controllers\Superuser\MenuController::class, 'get'])->name('menu');
|
Route::get('/superuser/menu', [App\Http\Controllers\Superuser\MenuController::class, 'get'])->name('menu');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -45,5 +45,6 @@ Route::middleware(['auth:sanctum', config('jetstream.auth_session'), 'verified']
|
|||||||
'index', 'store', 'update', 'destroy',
|
'index', 'store', 'update', 'destroy',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
Route::get('/activity/login', [App\Http\Controllers\ActivityController::class, 'login'])->name('activity.login');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user