Browse Source

login y dashboard

main
sergiomarquez778 1 month ago
parent
commit
74e280b4e8
  1. 58
      .env.example
  2. 39
      app/Http/Controllers/Auth/ConfirmPasswordController.php
  3. 22
      app/Http/Controllers/Auth/ForgotPasswordController.php
  4. 40
      app/Http/Controllers/Auth/LoginController.php
  5. 72
      app/Http/Controllers/Auth/RegisterController.php
  6. 29
      app/Http/Controllers/Auth/ResetPasswordController.php
  7. 41
      app/Http/Controllers/Auth/VerificationController.php
  8. 28
      app/Http/Controllers/HomeController.php
  9. 71
      app/Http/Controllers/usuariosController.php
  10. 3
      composer.json
  11. 65
      composer.lock
  12. 32
      database/migrations/2014_10_12_100000_create_password_resets_table.php
  13. 1438
      package-lock.json
  14. 3
      package.json
  15. 277
      public/css/style.css
  16. 0
      resources/css/app.css
  17. 4
      resources/js/bootstrap.js
  18. 7
      resources/sass/_variables.scss
  19. 8
      resources/sass/app.scss
  20. 106
      resources/views/auth/login.blade.php
  21. 49
      resources/views/auth/passwords/confirm.blade.php
  22. 47
      resources/views/auth/passwords/email.blade.php
  23. 65
      resources/views/auth/passwords/reset.blade.php
  24. 77
      resources/views/auth/register.blade.php
  25. 28
      resources/views/auth/verify.blade.php
  26. 99
      resources/views/dashboard.blade.php
  27. 23
      resources/views/home.blade.php
  28. 80
      resources/views/layouts/app.blade.php
  29. 108
      resources/views/layouts/dashboard.blade.php
  30. 11
      routes/web.php
  31. 5
      vite.config.js

58
.env.example

@ -1,58 +0,0 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailpit
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_HOST=
PUSHER_PORT=443
PUSHER_SCHEME=https
PUSHER_APP_CLUSTER=mt1
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_HOST="${PUSHER_HOST}"
VITE_PUSHER_PORT="${PUSHER_PORT}"
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

39
app/Http/Controllers/Auth/ConfirmPasswordController.php

@ -0,0 +1,39 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ConfirmsPasswords;
class ConfirmPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Confirm Password Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password confirmations and
| uses a simple trait to include the behavior. You're free to explore
| this trait and override any functions that require customization.
|
*/
use ConfirmsPasswords;
/**
* Where to redirect users when the intended url fails.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
}

22
app/Http/Controllers/Auth/ForgotPasswordController.php

@ -0,0 +1,22 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
class ForgotPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset emails and
| includes a trait which assists in sending these notifications from
| your application to your users. Feel free to explore this trait.
|
*/
use SendsPasswordResetEmails;
}

40
app/Http/Controllers/Auth/LoginController.php

@ -0,0 +1,40 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
$this->middleware('auth')->only('logout');
}
}

72
app/Http/Controllers/Auth/RegisterController.php

@ -0,0 +1,72 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\Models\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
}

29
app/Http/Controllers/Auth/ResetPasswordController.php

@ -0,0 +1,29 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Where to redirect users after resetting their password.
*
* @var string
*/
protected $redirectTo = '/home';
}

41
app/Http/Controllers/Auth/VerificationController.php

@ -0,0 +1,41 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\VerifiesEmails;
class VerificationController extends Controller
{
/*
|--------------------------------------------------------------------------
| Email Verification Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling email verification for any
| user that recently registered with the application. Emails may also
| be re-sent if the user didn't receive the original email message.
|
*/
use VerifiesEmails;
/**
* Where to redirect users after verification.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify', 'resend');
}
}

28
app/Http/Controllers/HomeController.php

@ -0,0 +1,28 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* @return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
return view('dashboard');
}
}

71
app/Http/Controllers/usuariosController.php

@ -0,0 +1,71 @@
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class usuariosController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
$user=User::all();
return view('usuarios',['user'=>$user]);
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
return view('usuariosCrearEditar');
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
$user = new User($request->all());
$user->save();
return redirect()->route('usuarios');
}
/**
* Display the specified resource.
*/
public function show(string $id)
{
//
}
/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
//
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, string $id)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(string $id)
{
//
}
}

3
composer.json

@ -9,7 +9,8 @@
"guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^10.0",
"laravel/sanctum": "^3.2",
"laravel/tinker": "^2.8"
"laravel/tinker": "^2.8",
"laravel/ui": "^4.6"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",

65
composer.lock

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "bfe12996eeecb6fdc8713a9fd9d431f8",
"content-hash": "8fac62fa000557439a1027c0c1519c98",
"packages": [
{
"name": "brick/math",
@ -1512,6 +1512,69 @@
},
"time": "2025-01-27T14:24:01+00:00"
},
{
"name": "laravel/ui",
"version": "v4.6.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/ui.git",
"reference": "7d6ffa38d79f19c9b3e70a751a9af845e8f41d88"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/ui/zipball/7d6ffa38d79f19c9b3e70a751a9af845e8f41d88",
"reference": "7d6ffa38d79f19c9b3e70a751a9af845e8f41d88",
"shasum": ""
},
"require": {
"illuminate/console": "^9.21|^10.0|^11.0|^12.0",
"illuminate/filesystem": "^9.21|^10.0|^11.0|^12.0",
"illuminate/support": "^9.21|^10.0|^11.0|^12.0",
"illuminate/validation": "^9.21|^10.0|^11.0|^12.0",
"php": "^8.0",
"symfony/console": "^6.0|^7.0"
},
"require-dev": {
"orchestra/testbench": "^7.35|^8.15|^9.0|^10.0",
"phpunit/phpunit": "^9.3|^10.4|^11.5"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Laravel\\Ui\\UiServiceProvider"
]
},
"branch-alias": {
"dev-master": "4.x-dev"
}
},
"autoload": {
"psr-4": {
"Laravel\\Ui\\": "src/",
"Illuminate\\Foundation\\Auth\\": "auth-backend/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "Laravel UI utilities and presets.",
"keywords": [
"laravel",
"ui"
],
"support": {
"source": "https://github.com/laravel/ui/tree/v4.6.1"
},
"time": "2025-01-28T15:15:29+00:00"
},
{
"name": "league/commonmark",
"version": "2.6.1",

32
database/migrations/2014_10_12_100000_create_password_resets_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.
*
* @return void
*/
public function up()
{
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('password_resets');
}
};

1438
package-lock.json

File diff suppressed because it is too large

3
package.json

@ -5,8 +5,11 @@
"build": "vite build"
},
"devDependencies": {
"@popperjs/core": "^2.11.6",
"axios": "^1.1.2",
"bootstrap": "^5.2.3",
"laravel-vite-plugin": "^0.7.2",
"sass": "^1.56.1",
"vite": "^4.0.0"
}
}

277
public/css/style.css

@ -0,0 +1,277 @@
/********** Template CSS **********/
:root {
--primary: #009CFF;
--light: #F3F6F9;
--dark: #191C24;
}
.back-to-top {
position: fixed;
display: none;
right: 45px;
bottom: 45px;
z-index: 99;
}
/*** Spinner ***/
#spinner {
opacity: 0;
visibility: hidden;
transition: opacity .5s ease-out, visibility 0s linear .5s;
z-index: 99999;
}
#spinner.show {
transition: opacity .5s ease-out, visibility 0s linear 0s;
visibility: visible;
opacity: 1;
}
/*** Button ***/
.btn {
transition: .5s;
}
.btn.btn-primary {
color: #FFFFFF;
}
.btn-square {
width: 38px;
height: 38px;
}
.btn-sm-square {
width: 32px;
height: 32px;
}
.btn-lg-square {
width: 48px;
height: 48px;
}
.btn-square,
.btn-sm-square,
.btn-lg-square {
padding: 0;
display: inline-flex;
align-items: center;
justify-content: center;
font-weight: normal;
border-radius: 50px;
}
/*** Layout ***/
.sidebar {
position: fixed;
top: 0;
left: 0;
bottom: 0;
width: 250px;
height: 100vh;
overflow-y: auto;
background: var(--light);
transition: 0.5s;
z-index: 999;
}
.content {
margin-left: 250px;
min-height: 100vh;
background: #FFFFFF;
transition: 0.5s;
}
@media (min-width: 992px) {
.sidebar {
margin-left: 0;
}
.sidebar.open {
margin-left: -250px;
}
.content {
width: calc(100% - 250px);
}
.content.open {
width: 100%;
margin-left: 0;
}
}
@media (max-width: 991.98px) {
.sidebar {
margin-left: -250px;
}
.sidebar.open {
margin-left: 0;
}
.content {
width: 100%;
margin-left: 0;
}
}
/*** Navbar ***/
.sidebar .navbar .navbar-nav .nav-link {
padding: 7px 20px;
color: var(--dark);
font-weight: 500;
border-left: 3px solid var(--light);
border-radius: 0 30px 30px 0;
outline: none;
}
.sidebar .navbar .navbar-nav .nav-link:hover,
.sidebar .navbar .navbar-nav .nav-link.active {
color: var(--primary);
background: #FFFFFF;
border-color: var(--primary);
}
.sidebar .navbar .navbar-nav .nav-link i {
width: 40px;
height: 40px;
display: inline-flex;
align-items: center;
justify-content: center;
background: #FFFFFF;
border-radius: 40px;
}
.sidebar .navbar .navbar-nav .nav-link:hover i,
.sidebar .navbar .navbar-nav .nav-link.active i {
background: var(--light);
}
.sidebar .navbar .dropdown-toggle::after {
position: absolute;
top: 15px;
right: 15px;
border: none;
content: "\f107";
font-family: "Font Awesome 5 Free";
font-weight: 900;
transition: .5s;
}
.sidebar .navbar .dropdown-toggle[aria-expanded=true]::after {
transform: rotate(-180deg);
}
.sidebar .navbar .dropdown-item {
padding-left: 25px;
border-radius: 0 30px 30px 0;
}
.content .navbar .navbar-nav .nav-link {
margin-left: 25px;
padding: 12px 0;
color: var(--dark);
outline: none;
}
.content .navbar .navbar-nav .nav-link:hover,
.content .navbar .navbar-nav .nav-link.active {
color: var(--primary);
}
.content .navbar .sidebar-toggler,
.content .navbar .navbar-nav .nav-link i {
width: 40px;
height: 40px;
display: inline-flex;
align-items: center;
justify-content: center;
background: #FFFFFF;
border-radius: 40px;
}
.content .navbar .dropdown-toggle::after {
margin-left: 6px;
vertical-align: middle;
border: none;
content: "\f107";
font-family: "Font Awesome 5 Free";
font-weight: 900;
transition: .5s;
}
.content .navbar .dropdown-toggle[aria-expanded=true]::after {
transform: rotate(-180deg);
}
@media (max-width: 575.98px) {
.content .navbar .navbar-nav .nav-link {
margin-left: 15px;
}
}
/*** Date Picker ***/
.bootstrap-datetimepicker-widget.bottom {
top: auto !important;
}
.bootstrap-datetimepicker-widget .table * {
border-bottom-width: 0px;
}
.bootstrap-datetimepicker-widget .table th {
font-weight: 500;
}
.bootstrap-datetimepicker-widget.dropdown-menu {
padding: 10px;
border-radius: 2px;
}
.bootstrap-datetimepicker-widget table td.active,
.bootstrap-datetimepicker-widget table td.active:hover {
background: var(--primary);
}
.bootstrap-datetimepicker-widget table td.today::before {
border-bottom-color: var(--primary);
}
/*** Testimonial ***/
.progress .progress-bar {
width: 0px;
transition: 2s;
}
/*** Testimonial ***/
.testimonial-carousel .owl-dots {
margin-top: 24px;
display: flex;
align-items: flex-end;
justify-content: center;
}
.testimonial-carousel .owl-dot {
position: relative;
display: inline-block;
margin: 0 5px;
width: 15px;
height: 15px;
border: 5px solid var(--primary);
border-radius: 15px;
transition: .5s;
}
.testimonial-carousel .owl-dot.active {
background: var(--dark);
border-color: var(--primary);
}

0
resources/css/app.css

4
resources/js/bootstrap.js

@ -1,3 +1,5 @@
import 'bootstrap';
/**
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
@ -24,7 +26,7 @@ window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
// broadcaster: 'pusher',
// key: import.meta.env.VITE_PUSHER_APP_KEY,
// cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER ?? 'mt1',
// wsHost: import.meta.env.VITE_PUSHER_HOST ? import.meta.env.VITE_PUSHER_HOST : `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
// wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
// wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
// wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
// forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',

7
resources/sass/_variables.scss

@ -0,0 +1,7 @@
// Body
$body-bg: #f8fafc;
// Typography
$font-family-sans-serif: 'Nunito', sans-serif;
$font-size-base: 0.9rem;
$line-height-base: 1.6;

8
resources/sass/app.scss

@ -0,0 +1,8 @@
// Fonts
@import url('https://fonts.bunny.net/css?family=Nunito');
// Variables
@import 'variables';
// Bootstrap
@import 'bootstrap/scss/bootstrap';

106
resources/views/auth/login.blade.php

@ -0,0 +1,106 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login - PrestamosTecmm</title>
<!-- Tailwind CSS desde CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
</head>
<body class="bg-gradient-to-br from-blue-600 to-blue-800 min-h-screen flex items-center justify-center p-4">
<div class="max-w-md w-full bg-white rounded-lg shadow-xl overflow-hidden">
<div class="p-6">
<div class="text-center mb-8">
<h2 class="text-3xl font-bold text-gray-800">PrestamosTecmm</h2>
<p class="text-gray-600 mt-2">Inicia sesión en tu cuenta</p>
</div>
@if ($errors->any())
<div class="mb-4 bg-red-50 border-l-4 border-red-500 p-4">
<div class="text-red-700">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
</div>
@endif
<form method="POST" action="{{ route('login') }}" class="space-y-6">
@csrf
<div>
<label for="email" class="block text-sm font-medium text-gray-700">
Correo Electrónico
</label>
<div class="mt-1 relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-envelope text-gray-400"></i>
</div>
<input id="email" name="email" type="email" required
class="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500"
value="{{ old('email') }}"
placeholder="tu@email.com">
</div>
</div>
<div>
<label for="password" class="block text-sm font-medium text-gray-700">
Contraseña
</label>
<div class="mt-1 relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-lock text-gray-400"></i>
</div>
<input id="password" name="password" type="password" required
class="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500"
placeholder="••••••••">
</div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center">
<input id="remember_me" name="remember" type="checkbox"
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded">
<label for="remember_me" class="ml-2 block text-sm text-gray-700">
Recordarme
</label>
</div>
@if (Route::has('password.request'))
<a href="{{ route('password.request') }}" class="text-sm text-blue-600 hover:text-blue-500">
¿Olvidaste tu contraseña?
</a>
@endif
</div>
<div>
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
Iniciar Sesión
</button>
</div>
</form>
@if (Route::has('register'))
<div class="mt-6 text-center">
<p class="text-sm text-gray-600">
¿No tienes una cuenta?
<a href="{{ route('register') }}" class="font-medium text-blue-600 hover:text-blue-500">
Regístrate aquí
</a>
</p>
</div>
@endif
</div>
</div>
<!-- Decoración de fondo -->
<div class="absolute top-0 left-0 w-full h-full pointer-events-none overflow-hidden">
<div class="absolute -top-1/2 -left-1/4 w-96 h-96 bg-blue-400 rounded-full opacity-10 transform rotate-45"></div>
<div class="absolute -bottom-1/2 -right-1/4 w-96 h-96 bg-blue-400 rounded-full opacity-10 transform -rotate-45"></div>
</div>
</body>
</html>

49
resources/views/auth/passwords/confirm.blade.php

@ -0,0 +1,49 @@
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Confirm Password') }}</div>
<div class="card-body">
{{ __('Please confirm your password before continuing.') }}
<form method="POST" action="{{ route('password.confirm') }}">
@csrf
<div class="row mb-3">
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Confirm Password') }}
</button>
@if (Route::has('password.request'))
<a class="btn btn-link" href="{{ route('password.request') }}">
{{ __('Forgot Your Password?') }}
</a>
@endif
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection

47
resources/views/auth/passwords/email.blade.php

@ -0,0 +1,47 @@
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Reset Password') }}</div>
<div class="card-body">
@if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
@endif
<form method="POST" action="{{ route('password.email') }}">
@csrf
<div class="row mb-3">
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Send Password Reset Link') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection

65
resources/views/auth/passwords/reset.blade.php

@ -0,0 +1,65 @@
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Reset Password') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('password.update') }}">
@csrf
<input type="hidden" name="token" value="{{ $token }}">
<div class="row mb-3">
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ $email ?? old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="password-confirm" class="col-md-4 col-form-label text-md-end">{{ __('Confirm Password') }}</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
</div>
</div>
<div class="row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Reset Password') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection

77
resources/views/auth/register.blade.php

@ -0,0 +1,77 @@
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Register') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('register') }}">
@csrf
<div class="row mb-3">
<label for="name" class="col-md-4 col-form-label text-md-end">{{ __('Name') }}</label>
<div class="col-md-6">
<input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
@error('name')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="password-confirm" class="col-md-4 col-form-label text-md-end">{{ __('Confirm Password') }}</label>
<div class="col-md-6">
<input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
</div>
</div>
<div class="row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Register') }}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection

28
resources/views/auth/verify.blade.php

@ -0,0 +1,28 @@
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Verify Your Email Address') }}</div>
<div class="card-body">
@if (session('resent'))
<div class="alert alert-success" role="alert">
{{ __('A fresh verification link has been sent to your email address.') }}
</div>
@endif
{{ __('Before proceeding, please check your email for a verification link.') }}
{{ __('If you did not receive the email') }},
<form class="d-inline" method="POST" action="{{ route('verification.resend') }}">
@csrf
<button type="submit" class="btn btn-link p-0 m-0 align-baseline">{{ __('click here to request another') }}</button>.
</form>
</div>
</div>
</div>
</div>
</div>
@endsection

99
resources/views/dashboard.blade.php

@ -0,0 +1,99 @@
@extends('layouts.dashboard')
@section('content')
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
<!-- Tarjeta de Préstamos Activos -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-gray-700">Préstamos Activos</h3>
<span class="text-blue-600 bg-blue-100 rounded-full p-2">
<i class="fas fa-book-reader"></i>
</span>
</div>
<p class="text-3xl font-bold text-gray-900">25</p>
<p class="text-sm text-gray-500 mt-2">↑ 12% desde el mes pasado</p>
</div>
<!-- Tarjeta de Usuarios Registrados -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-gray-700">Usuarios Registrados</h3>
<span class="text-green-600 bg-green-100 rounded-full p-2">
<i class="fas fa-users"></i>
</span>
</div>
<p class="text-3xl font-bold text-gray-900">150</p>
<p class="text-sm text-gray-500 mt-2">↑ 5% desde el mes pasado</p>
</div>
<!-- Tarjeta de Préstamos Vencidos -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-gray-700">Préstamos Vencidos</h3>
<span class="text-red-600 bg-red-100 rounded-full p-2">
<i class="fas fa-exclamation-circle"></i>
</span>
</div>
<p class="text-3xl font-bold text-gray-900">3</p>
<p class="text-sm text-gray-500 mt-2">↓ 2% desde el mes pasado</p>
</div>
<!-- Tarjeta de Préstamos del Mes -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-gray-700">Préstamos del Mes</h3>
<span class="text-purple-600 bg-purple-100 rounded-full p-2">
<i class="fas fa-chart-line"></i>
</span>
</div>
<p class="text-3xl font-bold text-gray-900">42</p>
<p class="text-sm text-gray-500 mt-2">↑ 8% desde el mes pasado</p>
</div>
</div>
<!-- Sección de Actividad Reciente -->
<div class="mt-8 bg-white rounded-lg shadow">
<div class="p-6">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Actividad Reciente</h2>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Usuario</th>
<th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Acción</th>
<th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Fecha</th>
<th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Estado</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<tr>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="flex-shrink-0 h-10 w-10">
<img class="h-10 w-10 rounded-full" src="https://ui-avatars.com/api/?name=Juan+Pérez" alt="">
</div>
<div class="ml-4">
<div class="text-sm font-medium text-gray-900">Juan Pérez</div>
<div class="text-sm text-gray-500">juan@example.com</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900">Solicitó préstamo</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900">Hace 2 horas</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
Aprobado
</span>
</td>
</tr>
<!-- Más filas de actividad aquí -->
</tbody>
</table>
</div>
</div>
</div>
@endsection

23
resources/views/home.blade.php

@ -0,0 +1,23 @@
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Dashboard') }}</div>
<div class="card-body">
@if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
@endif
{{ __('You are logged in!') }}
</div>
</div>
</div>
</div>
</div>
@endsection

80
resources/views/layouts/app.blade.php

@ -0,0 +1,80 @@
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">
<!-- Scripts -->
@vite(['resources/sass/app.scss', 'resources/js/app.js'])
</head>
<body>
<div id="app">
<nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
<div class="container">
<a class="navbar-brand" href="{{ url('/') }}">
{{ config('app.name', 'Laravel') }}
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<!-- Left Side Of Navbar -->
<ul class="navbar-nav me-auto">
</ul>
<!-- Right Side Of Navbar -->
<ul class="navbar-nav ms-auto">
<!-- Authentication Links -->
@guest
@if (Route::has('login'))
<li class="nav-item">
<a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
</li>
@endif
@if (Route::has('register'))
<li class="nav-item">
<a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
</li>
@endif
@else
<li class="nav-item dropdown">
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
{{ Auth::user()->name }}
</a>
<div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="{{ route('logout') }}"
onclick="event.preventDefault();
document.getElementById('logout-form').submit();">
{{ __('Logout') }}
</a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
@csrf
</form>
</div>
</li>
@endguest
</ul>
</div>
</div>
</nav>
<main class="py-4">
@yield('content')
</main>
</div>
</body>
</html>

108
resources/views/layouts/dashboard.blade.php

@ -0,0 +1,108 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard - PrestamosTecmm</title>
<!-- Tailwind CSS desde CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Alpine.js -->
<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
</head>
<body class="bg-gray-100">
<div class="min-h-screen flex">
<!-- Sidebar -->
<aside class="bg-[#1E40AF] text-white w-64 min-h-screen px-4 py-6 hidden md:block">
<div class="flex items-center justify-center mb-8">
<span class="text-2xl font-bold">PrestamosTecmm</span>
</div>
<nav>
<ul class="space-y-2">
<li>
<a href="/dashboard" class="flex items-center space-x-2 px-4 py-2 rounded hover:bg-blue-700">
<i class="fas fa-home"></i>
<span>Inicio</span>
</a>
</li>
<li>
<a href="/prestamos" class="flex items-center space-x-2 px-4 py-2 rounded hover:bg-blue-700">
<i class="fas fa-book"></i>
<span>Préstamos</span>
</a>
</li>
<li>
<a href="/usuarios" class="flex items-center space-x-2 px-4 py-2 rounded hover:bg-blue-700">
<i class="fas fa-users"></i>
<span>Usuarios</span>
</a>
</li>
<li>
<a href="/configuracion" class="flex items-center space-x-2 px-4 py-2 rounded hover:bg-blue-700">
<i class="fas fa-cog"></i>
<span>Configuración</span>
</a>
</li>
</ul>
</nav>
</aside>
<div class="flex-1 flex flex-col">
<!-- Navbar -->
<header class="bg-white shadow">
<div class="flex items-center justify-between px-6 py-4">
<button class="md:hidden text-gray-500 hover:text-gray-700">
<i class="fas fa-bars text-xl"></i>
</button>
<div class="flex items-center space-x-4">
<div class="relative" x-data="{ open: false }">
<button @click="open = !open" class="flex items-center space-x-2 text-gray-700 hover:text-gray-900">
<img src="https://ui-avatars.com/api/?name={{ Auth::user()->name }}" alt="Profile" class="w-8 h-8 rounded-full">
<span>{{ Auth::user()->name }}</span>
<i class="fas fa-chevron-down"></i>
</button>
<!-- Menú desplegable -->
<div x-show="open"
@click.away="open = false"
class="absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg py-1">
<form method="POST" action="{{ route('logout') }}">
@csrf
<button type="submit" class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
<i class="fas fa-sign-out-alt mr-2"></i> Cerrar Sesión
</button>
</form>
</div>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<main class="flex-1 p-6">
@yield('content')
</main>
<!-- Footer -->
<footer class="bg-white shadow mt-auto">
<div class="max-w-7xl mx-auto py-4 px-6">
<div class="flex justify-between items-center">
<p class="text-gray-600">&copy; 2024 PrestamosTecmm. Todos los derechos reservados.</p>
<div class="flex space-x-4">
<a href="#" class="text-gray-600 hover:text-gray-900">
<i class="fab fa-facebook"></i>
</a>
<a href="#" class="text-gray-600 hover:text-gray-900">
<i class="fab fa-twitter"></i>
</a>
<a href="#" class="text-gray-600 hover:text-gray-900">
<i class="fab fa-instagram"></i>
</a>
</div>
</div>
</div>
</footer>
</div>
</div>
</body>
</html>

11
routes/web.php

@ -1,6 +1,7 @@
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\usuariosController;
/*
|--------------------------------------------------------------------------
@ -16,3 +17,13 @@ use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('welcome');
});
Auth::routes(['register'=>false,'reset'=>false]);
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::get('/usuarios', [usuariosController::class,'index'])->name('usuarios');
Route::get('/usuarios/nuevo', [usuariosController::class,'create'])->name('usuarios.create');
Route::post('/usuarios/store', [usuariosController::class,'store'])->name('usuarios.store');

5
vite.config.js

@ -4,7 +4,10 @@ import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
input: [
'resources/css/app.css',
'resources/js/app.js',
],
refresh: true,
}),
],

Loading…
Cancel
Save