commit c03e44d604199046653815a04ea4a5918b564632 Author: snipertutu <109645285+snipertutu@users.noreply.github.com> Date: Thu Jun 20 08:50:56 2024 +0700 up projek diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8f0de65 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] +indent_size = 2 + +[docker-compose.yml] +indent_size = 4 diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..ea0665b --- /dev/null +++ b/.env.example @@ -0,0 +1,59 @@ +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_APP_NAME="${APP_NAME}" +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}" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fcb21d3 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +* text=auto eol=lf + +*.blade.php diff=html +*.css diff=css +*.html diff=html +*.md diff=markdown +*.php diff=php + +/.github export-ignore +CHANGELOG.md export-ignore +.styleci.yml export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7fe978f --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +/.phpunit.cache +/node_modules +/public/build +/public/hot +/public/storage +/storage/*.key +/vendor +.env +.env.backup +.env.production +.phpunit.result.cache +Homestead.json +Homestead.yaml +auth.json +npm-debug.log +yarn-error.log +/.fleet +/.idea +/.vscode diff --git a/README.md b/README.md new file mode 100644 index 0000000..1824fc1 --- /dev/null +++ b/README.md @@ -0,0 +1,66 @@ +
+ + + +## About Laravel + +Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as: + +- [Simple, fast routing engine](https://laravel.com/docs/routing). +- [Powerful dependency injection container](https://laravel.com/docs/container). +- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage. +- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent). +- Database agnostic [schema migrations](https://laravel.com/docs/migrations). +- [Robust background job processing](https://laravel.com/docs/queues). +- [Real-time event broadcasting](https://laravel.com/docs/broadcasting). + +Laravel is accessible, powerful, and provides tools required for large, robust applications. + +## Learning Laravel + +Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework. + +You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch. + +If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library. + +## Laravel Sponsors + +We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the [Laravel Partners program](https://partners.laravel.com). + +### Premium Partners + +- **[Vehikl](https://vehikl.com/)** +- **[Tighten Co.](https://tighten.co)** +- **[WebReinvent](https://webreinvent.com/)** +- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)** +- **[64 Robots](https://64robots.com)** +- **[Curotec](https://www.curotec.com/services/technologies/laravel/)** +- **[Cyber-Duck](https://cyber-duck.co.uk)** +- **[DevSquad](https://devsquad.com/hire-laravel-developers)** +- **[Jump24](https://jump24.co.uk)** +- **[Redberry](https://redberry.international/laravel/)** +- **[Active Logic](https://activelogic.com)** +- **[byte5](https://byte5.de)** +- **[OP.GG](https://op.gg)** + +## Contributing + +Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions). + +## Code of Conduct + +In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct). + +## Security Vulnerabilities + +If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed. + +## License + +The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT). diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php new file mode 100644 index 0000000..e6b9960 --- /dev/null +++ b/app/Console/Kernel.php @@ -0,0 +1,27 @@ +command('inspire')->hourly(); + } + + /** + * Register the commands for the application. + */ + protected function commands(): void + { + $this->load(__DIR__.'/Commands'); + + require base_path('routes/console.php'); + } +} diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php new file mode 100644 index 0000000..56af264 --- /dev/null +++ b/app/Exceptions/Handler.php @@ -0,0 +1,30 @@ + + */ + protected $dontFlash = [ + 'current_password', + 'password', + 'password_confirmation', + ]; + + /** + * Register the exception handling callbacks for the application. + */ + public function register(): void + { + $this->reportable(function (Throwable $e) { + // + }); + } +} diff --git a/app/Http/Auth/AuthenticatesUsers.php b/app/Http/Auth/AuthenticatesUsers.php new file mode 100644 index 0000000..ebf3c38 --- /dev/null +++ b/app/Http/Auth/AuthenticatesUsers.php @@ -0,0 +1,52 @@ +validate([ + 'nim' => 'required|string', + 'password' => 'required|string', + ]); + + $credentials = $request->only('nim', 'password'); + + if (Auth::attempt($credentials)) { + // Authentication passed... + $user = Auth::user(); + if ($user->role === 'admin') { + return redirect()->route('dashboard'); + } elseif ($user->role === 'mahasiswa') { + return redirect()->route('pages.tables.Project-mhs'); + } + } + + // Jika autentikasi gagal, redirect kembali ke halaman login dengan pesan error + throw ValidationException::withMessages([ + 'nim' => [trans('auth.failed')], + ]); + } + + public function logout() + { + Auth::logout(); + + $request->session()->invalidate(); + + $request->session()->regenerateToken(); + + return view('login'); + } +} diff --git a/app/Http/Controllers/AdminCarouselController.php b/app/Http/Controllers/AdminCarouselController.php new file mode 100644 index 0000000..557d99c --- /dev/null +++ b/app/Http/Controllers/AdminCarouselController.php @@ -0,0 +1,45 @@ +validate([ + 'title' => 'required', + 'image_url' => 'required|image|mimes:jpeg,png,jpg|max:2048', // maksimum 2MB + ]); + + $imagePath = $request->file('image_url')->store('images/carousel_images', 'public'); + + CarouselImage::create([ + 'title' => $request->title, + 'image_url' => $imagePath, + ]); + + Session::flash('success', 'Banner berhasil ditambahkan.'); + return redirect()->route('homepage.index'); + } + + public function destroy($id) + { + $banner = CarouselImage::findOrFail($id); + Storage::disk('public')->delete($banner->image_url); + $banner->delete(); + + Session::flash('success', 'Banner berhasil dihapus.'); + return redirect()->route('homepage.index'); + } +} diff --git a/app/Http/Controllers/AdminDashboardController.php b/app/Http/Controllers/AdminDashboardController.php new file mode 100644 index 0000000..f922fc0 --- /dev/null +++ b/app/Http/Controllers/AdminDashboardController.php @@ -0,0 +1,26 @@ +get(); + $totalProjects = ProjectMahasiswa::count(); + $totalProjectsThisYear = ProjectMahasiswa::whereYear('created_at', now()->year)->count(); + $totalUsers = User::count(); + + return view('dashboard', compact('projects', 'mahasiswa', 'totalProjects', 'totalProjectsThisYear', 'totalUsers')); + } +} diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php new file mode 100644 index 0000000..1ab8e67 --- /dev/null +++ b/app/Http/Controllers/AuthController.php @@ -0,0 +1,161 @@ +year)->count(); + $totalUsers = User::count(); + + return compact('totalProjects', 'totalProjectsThisYear', 'totalUsers'); + } + + public function showLoginForm() + { + return view('pages.auth.login'); + } + + public function login(Request $request) +{ + $credentials = $request->validate([ + 'nim' => ['required', 'string', 'max:255'], + 'password' => ['required'], + ]); + + if (Auth::attempt($credentials)) { + $request->session()->regenerate(); + + // Mendapatkan pengguna yang sedang login + $user = Auth::user(); + + // Redirect ke halaman sesuai dengan peran (role) pengguna + if ($user->role === 'admin') { + $statistics = $this->getStatistics(); + return redirect()->intended('/adm')->with(['user' => $user, 'statistics' => $statistics]); + } elseif ($user->role === 'mahasiswa') { + return redirect()->intended('/mhs')->with('user', $user); + } + } + + return back()->withErrors(['nim' => 'Invalid credentials']); +} + + + public function logout(Request $request) + { + Auth::logout(); + + $request->session()->invalidate(); + + $request->session()->regenerateToken(); + + return redirect('/login'); + } + + + public function showRegistrationForm() + { + return view('pages.auth.register'); + } + + public function register(Request $request) + { + // Temukan pengguna berdasarkan NIM + $user = User::where('nim', $request->nim)->first(); + + // Jika pengguna dengan NIM tersebut sudah ada + if ($user) { + // Validasi input + $validator = Validator::make($request->all(), [ + 'email' => ['required', 'string', 'email', 'max:255'], + 'password' => ['required', 'string', 'min:8', 'confirmed'], + ]); + + // Jika validasi gagal + if ($validator->fails()) { + return redirect()->back()->withErrors($validator)->withInput(); + } + + // Jika validasi berhasil, gunakan akun yang sudah ada dengan NIM tersebut + $user->update([ + 'email' => $request->email, + 'password' => Hash::make($request->password), + ]); + + // Melakukan login setelah registrasi + Auth::login($user); + + return redirect('/mhs'); + } else { + // Jika pengguna dengan NIM tersebut belum ada + return redirect()->back()->withErrors(['nim' => 'NIM tidak terdaftar. Mohon periksa kembali.'])->withInput(); + } + } + + + public function updateProfile(Request $request) + { + // Validasi data yang dikirimkan + $request->validate([ + 'email' => 'nullable|string|max:255', + 'phone_number' => 'nullable|string|max:20', + 'akun_github' => 'nullable|string|max:20', + 'akun_linkedin' => 'nullable|string|max:20', + 'address' => 'nullable|string|max:255', + 'profile_picture' => 'nullable|image|mimes:jpeg,png,jpg|max:2048', // Sesuaikan dengan aturan validasi yang diperlukan + ], [ + 'profile_picture.max' => 'Gambar profil tidak boleh lebih besar dari 2 megabita.', + ]); + + // Ambil user yang sedang login + $user = Auth::user(); + + // Update data pada user + $user->email = $request->email; + $user->phone_number = $request->phone_number; + $user->akun_github= $request->akun_github; + $user->akun_linkedin= $request->akun_linkedin; + $user->address = $request->address; + + // Cek apakah ada file foto yang dikirimkan + if ($request->hasFile('profile_picture')) { + // Cek ukuran file gambar + $fileSize = $request->file('profile_picture')->getSize(); // Dapatkan ukuran file dalam byte + $maxFileSize = 2048 * 1024; // 2048 KB, konversi ke byte + + // Jika ukuran file melebihi batas maksimum + if ($fileSize > $maxFileSize) { + return redirect()->back()->withErrors(['error' => 'Ukuran file gambar terlalu besar.'])->withInput(); + } + + // Hapus gambar profil lama jika ada + if ($user->profile_picture) { + Storage::disk('public')->delete($user->profile_picture); + } + + // Simpan foto baru + $imagePath = $request->file('profile_picture')->store('images/profile_pictures', 'public'); + $user->profile_picture = $imagePath; + } + + // Simpan perubahan pada user + $user->save(); + + // Redirect ke halaman profil dengan pesan sukses + return redirect()->back()->with('success', 'Profil berhasil diperbarui.'); + } + +} diff --git a/app/Http/Controllers/CarouselController.php b/app/Http/Controllers/CarouselController.php new file mode 100644 index 0000000..f64b9e8 --- /dev/null +++ b/app/Http/Controllers/CarouselController.php @@ -0,0 +1,15 @@ +validate(['email' => 'required|email']); + + $status = Password::sendResetLink( + $request->only('email') + ); + + return $status === Password::RESET_LINK_SENT + ? back()->with('status', __($status)) + : back()->withErrors(['email' => __($status)]); + } +} diff --git a/app/Http/Controllers/IndexController.php b/app/Http/Controllers/IndexController.php new file mode 100644 index 0000000..bc46eee --- /dev/null +++ b/app/Http/Controllers/IndexController.php @@ -0,0 +1,49 @@ +validate([ + 'tahun' => 'required', + 'kategori' => 'required' + ]); + + // Tangkap nilai pencarian dari permintaan HTTP + $tahun = $validatedData['tahun']; + $kategori = $validatedData['kategori']; + + // Tambahkan kondisi pencarian berdasarkan tahun jika ada + if ($tahun) { + $projects->where('angkatan', $tahun); + } + + // Tambahkan kondisi pencarian berdasarkan kategori jika ada + if ($kategori) { + $projects->where('kategori', $kategori); + } + + // Dapatkan hasil pencarian proyek + $projects = $projects->get(); + + // Dapatkan data banner + $banners = CarouselImage::all(); + + // Jika permintaan adalah AJAX, kembalikan tampilan parsial + if ($request->ajax()) { + return view('partials.project-list', compact('projects')); + } + + // Jika bukan permintaan AJAX, kembalikan tampilan penuh + return view('index', compact('projects', 'banners')); + } + +} diff --git a/app/Http/Controllers/MahasiswaDashboardController.php b/app/Http/Controllers/MahasiswaDashboardController.php new file mode 100644 index 0000000..29a6c9d --- /dev/null +++ b/app/Http/Controllers/MahasiswaDashboardController.php @@ -0,0 +1,14 @@ +hidden = !$project->hidden; + $project->save(); + + // Redirect kembali ke halaman index atau lakukan respons JSON sesuai kebutuhan + return redirect()->route('project.index')->with('success', 'Visibility toggled successfully.'); + } + + public function searchMahasiswa(Request $request) + { + $searchTerm = $request->input('q'); // Mendapatkan kata kunci pencarian dari permintaan + + // Lakukan pencarian berdasarkan NIM atau nama untuk pengguna dengan peran mahasiswa + $users = User::where(function ($query) use ($searchTerm) { + $query->where('nim', 'like', "%{$searchTerm}%") + ->orWhere('name', 'like', "%{$searchTerm}%"); + }) + ->where('role', 'mahasiswa') // Filter berdasarkan peran 'mahasiswa' + ->get(); + + // Format hasil pencarian menjadi format yang diharapkan oleh Select2 + $formattedUsers = []; + foreach ($users as $user) { + $formattedUsers[] = ['id' => $user->id, 'text' => $user->nim . ' - ' . $user->name]; + } + + return response()->json($formattedUsers); + } + + public function getMembersProject($projectId) + { + // Dapatkan anggota dari proyek tertentu yang memiliki peran mahasiswa + $members = ProjectDetail::where('project_mahasiswa_id', $projectId) + ->with('users') // Menggunakan 'users' karena itulah nama relasinya + ->whereHas('users', function ($query) { + $query->where('role', 'mahasiswa'); + }) + ->get() + ->map(function ($detail) { + return [ + 'id' => $detail->users->id, // Menggunakan 'users' untuk mendapatkan data anggota + 'name' => $detail->users->name, // Menggunakan 'users' untuk mendapatkan data anggota + ]; + }); + + + // Kirim data anggota sebagai respons JSON + return response()->json(['data' => $members]); + } + + public function editProject($id) + { + $project = ProjectMahasiswa::find($id); + + if (!$project) { + return redirect()->route('project.index')->with('error', 'Proyek tidak ditemukan.'); + } + + // Lanjutkan untuk menampilkan modal edit dengan informasi proyek + return view('pages.tables.project', compact('project')); // Perbaikan: Kirim data proyek ke view + } + + public function updateAnggotaProject(Request $request, $id) + { + $project = ProjectMahasiswa::find($id); + + // Update project details (members) + if ($request->has('anggota')) { + // Ambil anggota yang dipilih dari form + $selectedMembers = $request->anggota; + + // Hapus anggota yang tidak dipilih dari database + $project->detail()->whereNotIn('anggota', $selectedMembers)->delete(); + + // Tambahkan anggota yang dipilih jika belum ada dalam database + foreach ($selectedMembers as $member) { + $existingMember = $project->detail()->where('anggota', $member)->first(); + if (!$existingMember) { + $project->detail()->create([ + 'anggota' => $member, + ]); + } + } + } + + return redirect()->route('project.index')->with('success', 'Proyek berhasil diperbarui.'); + } + + + + public function delete($id) + { + try { + $project = ProjectMahasiswa::findOrFail($id); + $project->delete(); + + return response()->json(['message' => 'Proyek berhasil dihapus']); + } catch (\Exception $e) { + return response()->json(['message' => 'Gagal menghapus proyek'], 500); + } + } + +} diff --git a/app/Http/Controllers/ProjectDetailController.php b/app/Http/Controllers/ProjectDetailController.php new file mode 100644 index 0000000..be8da31 --- /dev/null +++ b/app/Http/Controllers/ProjectDetailController.php @@ -0,0 +1,21 @@ +findOrFail($id); + + // Mengirimkan data proyek ke tampilan + return view('project-details', compact('project')); + } +} diff --git a/app/Http/Controllers/ProjectMahasiswaController.php b/app/Http/Controllers/ProjectMahasiswaController.php new file mode 100644 index 0000000..5983579 --- /dev/null +++ b/app/Http/Controllers/ProjectMahasiswaController.php @@ -0,0 +1,267 @@ +pluck('project_mahasiswa_id'); + + // Memuat proyek yang ditambahkan pengguna sebagai anggota atau proyek yang ditambahkan oleh pengguna itu sendiri + $projects = ProjectMahasiswa::with('Detail.users') + ->where('user_id', $userId) + ->orWhereIn('id', $projectIds) + ->get(); + return view('pages.tables.project-mhs', compact('projects')); + } + + public function print() + { + $userId = Auth::id(); + // Mendapatkan ID proyek yang ditambahkan pengguna sebagai anggota + $projectIds = ProjectDetail::where('anggota', $userId)->pluck('project_mahasiswa_id'); + + // Memuat proyek yang ditambahkan pengguna sebagai anggota atau proyek yang ditambahkan oleh pengguna itu sendiri + $projects = ProjectMahasiswa::with('Detail.users') + ->where('user_id', $userId) + ->orWhereIn('id', $projectIds) + ->get(); + return view('projectprint', compact('projects')); + + } + + public function store(Request $request) + { + // Validasi input + $request->validate([ + 'nama_aplikasi' => 'required|string', + 'semester' => 'required|string', + 'angkatan' => 'required|string', + 'golongan' => 'required|string', + 'kategori' => 'required|string', + 'link_github' => 'nullable|string', + 'link_website' => 'nullable|string', + 'link_youtube' => 'required|string', + 'gambar_1' => 'image|extensions:jpeg,png,jpg|max:2048', + 'gambar_2' => 'image|extensions:jpeg,png,jpg|max:2048', + 'gambar_3' => 'image|extensions:jpeg,png,jpg|max:2048', + 'gambar_4' => 'image|extensions:jpeg,png,jpg|max:2048', + 'anggota' => 'nullable|array', // Menambahkan validasi untuk anggota + ]); + + // Lakukan operasi penyimpanan data jika validasi berhasil + $userId = Auth::id(); + $userNim = Auth::user()->nim; + $project = new ProjectMahasiswa(); + $project->user_id = $userId; + $project->nama_aplikasi = $request->nama_aplikasi; + $project->semester = $request->semester; + $project->kategori = $request->kategori; + $project->angkatan = $request->angkatan; + $project->golongan = $request->golongan; + + // Cek kategori, jika "Tugas Akhir", abaikan nilai "ketua_kelompok" + if ($request->kategori != 'Tugas Akhir') { + $project->ketua_kelompok = $userNim; + } + + $project->link_github = $request->link_github; + $project->link_website = $request->link_website; + $project->link_youtube = $request->link_youtube; + $project->narasi = $request->narasi; + + // Upload gambar-gambar jika ada + $gambarPaths = []; + foreach (['gambar_1', 'gambar_2', 'gambar_3', 'gambar_4'] as $field) { + if ($request->hasFile($field)) { + $gambarPath = $request->file($field)->store('images/project_picture', 'public'); + $gambarPaths[$field] = $gambarPath; + } + } + + $project->gambar_1 = $gambarPaths['gambar_1'] ?? null; + $project->gambar_2 = $gambarPaths['gambar_2'] ?? null; + $project->gambar_3 = $gambarPaths['gambar_3'] ?? null; + $project->gambar_4 = $gambarPaths['gambar_4'] ?? null; + + // Simpan proyek + if ($project->save()) { + if ($request->has('anggota')) { + foreach ($request->anggota as $anggota) { + // Periksa apakah anggota telah terdaftar dalam proyek lain dengan semester yang sama + $existingProjects = ProjectDetail::where('anggota', $anggota) + ->whereHas('projectMahasiswa', function ($query) use ($project) { + $query->where('semester', $project->semester); + }) + ->exists(); + + // Jika anggota telah terdaftar dalam proyek dengan semester yang sama, abaikan anggota tersebut + if ($existingProjects) { + continue; + } + + // Tambahkan anggota ke proyek saat ini + ProjectDetail::create([ + 'project_mahasiswa_id' => $project->id, + 'anggota' => $anggota + ]); + } + } + + return redirect()->route('project-mhs')->with('success', 'Data proyek berhasil ditambahkan.'); + } else { + // Penanganan kesalahan jika penyimpanan proyek gagal + return redirect()->back()->with('error', 'Gagal menyimpan data proyek. Silakan coba lagi.'); + } + } + + + public function search(Request $request) + { + $searchTerm = $request->input('q'); // Mendapatkan kata kunci pencarian dari permintaan + + // Lakukan pencarian berdasarkan NIM atau nama untuk pengguna dengan peran mahasiswa + $users = User::where(function ($query) use ($searchTerm) { + $query->where('nim', 'like', "%{$searchTerm}%") + ->orWhere('name', 'like', "%{$searchTerm}%"); + }) + ->where('role', 'mahasiswa') // Filter berdasarkan peran 'mahasiswa' + ->get(); + + // Format hasil pencarian menjadi format yang diharapkan oleh Select2 + $formattedUsers = []; + foreach ($users as $user) { + $formattedUsers[] = ['id' => $user->id, 'text' => $user->nim . ' - ' . $user->name]; + } + + return response()->json($formattedUsers); + } + + public function getMembers($projectId) + { + // Dapatkan anggota dari proyek tertentu yang memiliki peran mahasiswa + $members = ProjectDetail::where('project_mahasiswa_id', $projectId) + ->with('users') // Menggunakan 'users' karena itulah nama relasinya + ->whereHas('users', function ($query) { + $query->where('role', 'mahasiswa'); + }) + ->get() + ->map(function ($detail) { + return [ + 'id' => $detail->users->id, // Menggunakan 'users' untuk mendapatkan data anggota + 'name' => $detail->users->name, // Menggunakan 'users' untuk mendapatkan data anggota + ]; + }); + + + // Kirim data anggota sebagai respons JSON + return response()->json(['data' => $members]); + } + + + public function edit($id) + { + $project = ProjectMahasiswa::find($id); + + if (!$project) { + return redirect()->route('project-mhs')->with('error', 'Proyek tidak ditemukan.'); + } + + // Periksa izin pengguna untuk mengedit proyek + if ($project->user_id !== Auth::id() && !ProjectDetail::where('project_mahasiswa_id', $id)->where('anggota', Auth::id())->exists()) { + return redirect()->route('project-mhs')->with('error', 'Anda tidak memiliki izin untuk mengedit proyek ini.'); + } + + // Lanjutkan untuk menampilkan modal edit dengan informasi proyek + return view('pages.tables.project-mhs', compact('project')); // Perbaikan: Kirim data proyek ke view + } + + public function update(Request $request, $id) + { + $project = ProjectMahasiswa::find($id); + + // Periksa apakah pengguna yang sedang melakukan permintaan adalah pemilik proyek atau anggota proyek + if (!$project || ($project->user_id !== Auth::id() && !ProjectDetail::where('project_mahasiswa_id', $id)->where('anggota', Auth::id())->exists())) { + return redirect()->route('project-mhs')->with('error', 'Proyek tidak ditemukan atau Anda tidak memiliki izin untuk mengedit proyek ini.'); + } + + $request->validate([ + 'nama_aplikasi' => 'required|string', + 'golongan' => 'required|string', + 'link_github' => 'required|string', + 'link_website' => 'required|string', + 'link_youtube' => 'required|string', + 'narasi' => 'required|string', + 'gambar_1' => 'nullable|image|mimes:jpeg,png,jpg|max:2048', + 'gambar_2' => 'nullable|image|mimes:jpeg,png,jpg|max:2048', + 'gambar_3' => 'nullable|image|mimes:jpeg,png,jpg|max:2048', + 'gambar_4' => 'nullable|image|mimes:jpeg,png,jpg|max:2048', + ]); + + // Update data proyek + $project->nama_aplikasi = $request->nama_aplikasi; + $project->golongan = $request->golongan; + $project->link_github = $request->link_github; + $project->link_website = $request->link_website; + $project->link_youtube = $request->link_youtube; + $project->narasi = $request->narasi; + + // Upload ulang gambar-gambar jika ada yang diunggah + foreach (['gambar_1', 'gambar_2', 'gambar_3', 'gambar_4'] as $field) { + if ($request->hasFile($field)) { + // Hapus file lama jika ada + if ($project->{$field}) { + Storage::disk('public')->delete($project->{$field}); + } + // Upload file baru + $gambarPath = $request->file($field)->store('images/project_picture', 'public'); + $project->{$field} = $gambarPath; + } + } + + // Simpan perubahan pada proyek + $project->save(); + + // Update project details (members) + if ($request->has('anggota')) { + // Dapatkan anggota yang sudah ada + $existingMembers = $project->detail->pluck('anggota')->toArray(); + + // Loop melalui anggota yang ingin ditambahkan + foreach ($request->anggota as $member) { + // Periksa apakah anggota telah terdaftar dalam proyek lain dengan semester yang sama + $existingProjects = ProjectDetail::where('anggota', $member) + ->whereHas('projectMahasiswa', function ($query) use ($project) { + $query->where('semester', $project->semester); + }) + ->exists(); + + // Jika anggota telah terdaftar dalam proyek dengan semester yang sama, abaikan anggota tersebut + if ($existingProjects) { + continue; + } + + // Jika anggota belum ada dalam daftar anggota yang sudah ada, tambahkan anggota baru + if (!in_array($member, $existingMembers)) { + $projectDetail = new ProjectDetail(); + $projectDetail->project_mahasiswa_id = $project->id; + $projectDetail->anggota = $member; + $projectDetail->save(); + } + } + } + + return redirect()->route('project-mhs')->with('success', 'Proyek berhasil diperbarui.'); + } + +} diff --git a/app/Http/Controllers/ResetPasswordController.php b/app/Http/Controllers/ResetPasswordController.php new file mode 100644 index 0000000..2cc96a5 --- /dev/null +++ b/app/Http/Controllers/ResetPasswordController.php @@ -0,0 +1,56 @@ +with( + ['token' => $token, 'email' => $request->email] + ); + } + + public function reset(Request $request) + { + $request->validate([ + 'token' => 'required', + 'email' => 'required|email', + 'password' => 'required|confirmed|min:8', + ]); + + // Pastikan email ada di salah satu dari dua tabel + $emailExists = User::where('email', $request->email)->exists() || + PasswordResetToken::where('email', $request->email)->exists(); + + if (!$emailExists) { + return back()->withErrors(['email' => 'Invalid email or not found']); + } + + $status = Password::reset( + $request->only('email', 'password', 'password_confirmation', 'token'), + function ($user, $password) { + $user->forceFill([ + 'password' => Hash::make($password), + 'remember_token' => Str::random(60), + ])->save(); + } + ); + + if ($status == Password::PASSWORD_RESET) { + // Hapus token reset password dari tabel password_reset_token + PasswordResetToken::where('email', $request->email)->delete(); + + return redirect()->route('login')->with('status', __($status)); + } else { + return back()->withErrors(['email' => __($status)]); + } + } +} diff --git a/app/Http/Controllers/UploadDataController.php b/app/Http/Controllers/UploadDataController.php new file mode 100644 index 0000000..c44ea3a --- /dev/null +++ b/app/Http/Controllers/UploadDataController.php @@ -0,0 +1,83 @@ +validate([ + 'file' => 'required|extensions:csv', + ]); + + $file = $request->file('file'); + // $path = $file->store('file', 'public'); + $extension = $file->getClientOriginalExtension(); + + if ($extension == 'csv') { + $csvData = array_map(function($row) { + return str_getcsv($row, ';'); + }, file($file)); + array_shift($csvData); + + foreach ($csvData as $row) { + User::updateOrCreate( + ['nim' => $row[0]], + ['name' => $row[1], 'angkatan' => $row[3]] + ); + } + } + + return redirect()->back()->with('success', 'Data berhasil diimpor.'); + } + + public function upload(Request $request) + { + Log::info('Upload method accessed'); + + $request->validate([ + 'file' => 'required|mimes:csv,xls,xlsx', + ]); + + try { + $file = $request->file('file'); + Log::info('File validated and received'); + + // Simpan file ke dalam folder penyimpanan tertentu + $path = $file->store('file', 'public'); + Log::info('File stored successfully at ' . $path); + + $extension = $file->getClientOriginalExtension(); + Log::info('File extension: ' . $extension); + + if ($extension == 'csv') { + $csvData = array_map('str_getcsv', file($file)); + Log::info('CSV data processed'); + + foreach ($csvData as $row) { + User::updateOrCreate( + ['nim' => $row[0]], + ['name' => $row[1], 'angkatan' => $row[2]] + ); + Log::info('Data updated or created for NIM: ' . $row[0]); + } + } else { + Excel::import(new UserImport, storage_path('app/public/' . $path)); + Log::info('Excel data imported'); + } + + Log::info('Data imported successfully'); + return redirect()->back()->with('success', 'Data berhasil diimpor.'); + } catch (\Exception $e) { + Log::error('Error: ' . $e->getMessage()); + return redirect()->back()->with('error', 'Terjadi kesalahan. Silakan coba lagi.'); + } + } +} diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php new file mode 100644 index 0000000..6aa5168 --- /dev/null +++ b/app/Http/Controllers/UserController.php @@ -0,0 +1,149 @@ +ajax()) { + $data = User::where('role', 'mahasiswa')->get(); + return DataTables::of($data) + ->addColumn('action', function($row){ + $button = ''; + $button .= ' '; + return $button; + }) + ->rawColumns(['action']) + ->make(true); + } + + return view('pages.tables.Mahasiswa'); + } + + + /** + * Show the form for creating a new resource. + */ + public function create() + { + // + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request) + { + // Validasi data yang dikirim oleh pengguna + $request->validate([ + 'nim' => 'required', + 'name' => 'required', + 'angkatan' => 'required', + ]); + + try { + // Simpan data mahasiswa ke dalam database + User::create([ + 'nim' => $request->nim, + 'name' => $request->name, + 'angkatan' => $request->angkatan, + ]); + + // Berikan respons sukses jika penyimpanan berhasil + return response()->json(['success' => 'Data mahasiswa berhasil ditambahkan.']); + } catch (\Exception $e) { + // Tangani kesalahan jika terjadi + \Log::error($e->getMessage()); + return response()->json(['error' => 'Terjadi kesalahan. Silakan coba lagi.'], 500); + } + } + + /** + * Display the specified resource. + */ + public function show(string $id) + { + // + } + + /** + * Show the form for editing the specified resource. + */ + public function edit($id) + { + $user = User::find($id); + return response()->json($user); + } + + + + public function update(Request $request, $id) + { + $request->validate([ + 'nim' => 'sometimes|required', + 'name' => 'sometimes|required', + 'angkatan' => 'sometimes|required|numeric', + ]); + + $user = User::find($id); + if ($user) { + // Memperbarui bidang-bidang yang ada dalam permintaan + if ($request->has('edit_nim')) { + $user->nim = $request->edit_nim; + } + if ($request->has('edit_name')) { + $user->name = $request->edit_name; + } + if ($request->has('edit_angkatan')) { + $user->angkatan = $request->edit_angkatan; + } + + // Menyimpan perubahan + $user->save(); + + return response()->json(['message' => 'Data mahasiswa berhasil diperbarui.']); + } else { + return response()->json(['error' => 'Data mahasiswa tidak ditemukan.'], 404); + } + } + + + + + /** + * Remove the specified resource from storage. + */ + public function destroy(Request $request) + { + // Validasi request + $request->validate([ + 'id' => 'required|exists:users,id', + ]); + + try { + // Ambil ID pengguna dari permintaan + $userId = $request->input('id'); + + // Hapus pengguna dari database + User::destroy($userId); + + // Berhasil menghapus, kembalikan respons berhasil + return response()->json(['success' => 'Pengguna berhasil dihapus.']); + } catch (\Exception $e) { + // Tangani kesalahan + // Misalnya, log pesan kesalahan + \Log::error($e->getMessage()); + // Kembalikan respons dengan pesan kesalahan yang sesuai + return response()->json(['error' => 'Terjadi kesalahan saat menghapus pengguna.'], 500); + } + } +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php new file mode 100644 index 0000000..b9dc521 --- /dev/null +++ b/app/Http/Kernel.php @@ -0,0 +1,69 @@ + + */ + protected $middleware = [ + // \App\Http\Middleware\TrustHosts::class, + \App\Http\Middleware\TrustProxies::class, + \Illuminate\Http\Middleware\HandleCors::class, + \App\Http\Middleware\PreventRequestsDuringMaintenance::class, + \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, + \App\Http\Middleware\TrimStrings::class, + \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, + ]; + + /** + * The application's route middleware groups. + * + * @var array
+
+ npm install @mdi/font
+
+ <span class="mdi mdi-name"></span>
+
+ + Click the icon, hex codepoint, or name below to copy the value to your clipboard. ++ +
+ Deprecated icons will be removed in a future major release. +
+ + +The helper CSS classes are listed below.
+ +mdi-18px
+ mdi-24px
+ mdi-36px
+ mdi-48px
+ mdi-rotate-45
+ mdi-rotate-90
+ mdi-rotate-135
+ mdi-rotate-180
+ mdi-rotate-225
+ mdi-rotate-270
+ mdi-rotate-315
+ mdi-flip-h
+ mdi-flip-v
+ Note: We do not include the ability to use mdi-flip-*
and
+ mdi-rotate-*
at the same time.
mdi-spin
+ mdi-spin
+ mdi-light
+ mdi-light mdi-inactive
+ mdi-dark
+ mdi-dark mdi-inactive
+