first commit
This commit is contained in:
commit
43cc02b39e
|
@ -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
|
|
@ -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=ternakq_animal_husbandry_education
|
||||
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}"
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,66 @@
|
|||
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
|
||||
</p>
|
||||
|
||||
## 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 thousands of 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).
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*/
|
||||
protected function schedule(Schedule $schedule): void
|
||||
{
|
||||
// $schedule->command('inspire')->hourly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
*/
|
||||
protected function commands(): void
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* The list of the inputs that are never flashed to the session on validation exceptions.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Article;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class AdminArticleAccController extends Controller
|
||||
{
|
||||
|
||||
public function indexAdminArticle(Request $request)
|
||||
{
|
||||
try {
|
||||
$articlePage = $request->get('article_page', 1);
|
||||
$articles = Article::latest()->paginate(10, ['*'], 'article_page', $articlePage);
|
||||
return view('admin.article-management', compact('articles'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat data artikel: ' . $e->getMessage());
|
||||
return redirect()->route('admin.article-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memuat data artikel.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function editArticle($id)
|
||||
{
|
||||
try {
|
||||
$article = Article::with(['subArticles' => function ($query) {
|
||||
$query->orderBy('order_number', 'asc');
|
||||
}])->findOrFail($id);
|
||||
return view('admin.article-management-edit', compact('article'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat artikel untuk edit: ' . $e->getMessage());
|
||||
return redirect()->route('admin.article-management-edit')
|
||||
->with('status', 'error')
|
||||
->with('message', 'Terjadi kesalahan saat memuat artikel.');
|
||||
}
|
||||
}
|
||||
|
||||
public function updateArticle(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'catatan' => 'nullable|string',
|
||||
'status' => 'required|in:Tertunda,Disetujui,Ditolak',
|
||||
]);
|
||||
$article = Article::findOrFail($id);
|
||||
$article->update($validated);
|
||||
return redirect()->route('admin.article-management')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Status artikel berhasil diperbarui!',
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memperbarui artikel: ' . $e->getMessage());
|
||||
return redirect()->route('admin.article-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memperbarui artikel.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteArticle($id)
|
||||
{
|
||||
try {
|
||||
$article = Article::findOrFail($id);
|
||||
|
||||
$article->tags()->detach();
|
||||
|
||||
if ($article->image && Storage::disk('public')->exists($article->image)) {
|
||||
Storage::disk('public')->delete($article->image);
|
||||
}
|
||||
|
||||
$article->delete();
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Artikel berhasil dihapus.']);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menghapus artikel: ' . $e->getMessage());
|
||||
return response()->json(['success' => false, 'message' => 'Gagal menghapus artikel: ' . $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\CardArticle;
|
||||
use App\Models\Article;
|
||||
use App\Models\Tag;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class AdminArticleController extends Controller
|
||||
{
|
||||
public function indexAdminArtikel(Request $request)
|
||||
{
|
||||
try {
|
||||
$articlePage = $request->get('article_page', 1);
|
||||
|
||||
$articles = Article::with('cardArticle')
|
||||
->where('user_id', Auth::id())
|
||||
->latest()
|
||||
->paginate(4, ['*'], 'article_page', $articlePage);
|
||||
|
||||
$cardArticles = CardArticle::where('user_id', Auth::id())->get();
|
||||
$tags = Tag::all();
|
||||
|
||||
$articles->appends(['article_page' => $articlePage]);
|
||||
|
||||
$totalArticles = Article::where('user_id', Auth::id())->count();
|
||||
$todayArticles = Article::where('user_id', Auth::id())
|
||||
->whereDate('created_at', now())
|
||||
->count();
|
||||
|
||||
return view('admin.add-article-detail', compact('articles', 'cardArticles', 'tags', 'totalArticles', 'todayArticles'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat data artikel: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('admin.add-article-detail')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memuat data artikel.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function storeAdminArtikel(Request $request)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'card_id' => 'required|exists:card_articles,id',
|
||||
'title' => 'required|string|max:255',
|
||||
'description' => 'required|string',
|
||||
'status' => 'required|string|in:Tertunda,Disetujui,Ditolak',
|
||||
'tags' => 'required|array|min:1|max:3',
|
||||
'tags.*' => 'exists:tags,id',
|
||||
'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
|
||||
], [
|
||||
'card_id.required' => 'Artikel grup harus dipilih',
|
||||
'card_id.exists' => 'Artikel grup yang dipilih tidak valid',
|
||||
'title.required' => 'Judul artikel harus diisi',
|
||||
'title.max' => 'Judul artikel maksimal 255 karakter',
|
||||
'description.required' => 'Deskripsi artikel harus diisi',
|
||||
'tags.required' => 'Minimal satu tag harus dipilih',
|
||||
'tags.array' => 'Format tag tidak valid',
|
||||
'tags.min' => 'Minimal satu tag harus dipilih',
|
||||
'tags.max' => 'Maksimal tiga tag yang dapat dipilih',
|
||||
'tags.*.exists' => 'Tag yang dipilih tidak valid',
|
||||
'image.required' => 'Gambar artikel harus diunggah',
|
||||
'image.image' => 'File harus berupa gambar',
|
||||
'image.mimes' => 'Format gambar harus jpeg, png, jpg, atau gif',
|
||||
'image.max' => 'Ukuran gambar maksimal 2MB',
|
||||
]);
|
||||
|
||||
$imagePath = null;
|
||||
if ($request->hasFile('image')) {
|
||||
$imagePath = $request->file('image')->store('articles', 'public');
|
||||
}
|
||||
|
||||
$article = Article::create([
|
||||
'card_id' => $validated['card_id'],
|
||||
'title' => $validated['title'],
|
||||
'description' => $validated['description'],
|
||||
'status' => $validated['status'],
|
||||
'image' => $imagePath,
|
||||
'user_id' => Auth::id(),
|
||||
]);
|
||||
|
||||
if (!empty($validated['tags'])) {
|
||||
$article->tags()->attach($validated['tags']);
|
||||
}
|
||||
|
||||
return redirect()->route('admin.add-article-detail')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Artikel berhasil dibuat!',
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()
|
||||
->withErrors($e->validator)
|
||||
->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menyimpan artikel: ' . $e->getMessage());
|
||||
|
||||
return redirect()->back()->withInput()->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menyimpan artikel: ' . $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateAdminArtikel(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'card_id' => 'required|exists:card_articles,id',
|
||||
'title' => 'required|string|max:255',
|
||||
'description' => 'required|string',
|
||||
'status' => 'required|string|in:Tertunda,Disetujui,Ditolak',
|
||||
'tags' => 'required|array|min:1|max:3',
|
||||
'tags.*' => 'exists:tags,id',
|
||||
'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
|
||||
], [
|
||||
'card_id.required' => 'Artikel grup harus dipilih',
|
||||
'card_id.exists' => 'Artikel grup yang dipilih tidak valid',
|
||||
'title.required' => 'Judul artikel harus diisi',
|
||||
'title.max' => 'Judul artikel maksimal 255 karakter',
|
||||
'description.required' => 'Deskripsi artikel harus diisi',
|
||||
'tags.required' => 'Minimal satu tag harus dipilih',
|
||||
'tags.array' => 'Format tag tidak valid',
|
||||
'tags.min' => 'Minimal satu tag harus dipilih',
|
||||
'tags.max' => 'Maksimal tiga tag yang dapat dipilih',
|
||||
'tags.*.exists' => 'Tag yang dipilih tidak valid',
|
||||
'image.image' => 'File harus berupa gambar',
|
||||
'image.mimes' => 'Format gambar harus jpeg, png, jpg, atau gif',
|
||||
'image.max' => 'Ukuran gambar maksimal 2MB',
|
||||
]);
|
||||
|
||||
$article = Article::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$imagePath = $article->image;
|
||||
if ($request->hasFile('image')) {
|
||||
if ($article->image && Storage::disk('public')->exists($article->image)) {
|
||||
Storage::disk('public')->delete($article->image);
|
||||
}
|
||||
$imagePath = $request->file('image')->store('articles', 'public');
|
||||
}
|
||||
|
||||
$article->update([
|
||||
'card_id' => $validated['card_id'],
|
||||
'title' => $validated['title'],
|
||||
'description' => $validated['description'],
|
||||
'status' => $validated['status'],
|
||||
'image' => $imagePath,
|
||||
]);
|
||||
|
||||
if (!empty($validated['tags'])) {
|
||||
$article->tags()->sync($validated['tags']);
|
||||
} else {
|
||||
$article->tags()->detach();
|
||||
}
|
||||
|
||||
return redirect()->route('admin.add-article-detail')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Artikel berhasil diperbarui!',
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()
|
||||
->withErrors($e->validator)
|
||||
->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memperbarui artikel: ' . $e->getMessage());
|
||||
return redirect()->back()->withInput()->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memperbarui artikel: ' . $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteAdminArtikel($id)
|
||||
{
|
||||
try {
|
||||
$article = Article::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$article->tags()->detach();
|
||||
if ($article->image) {
|
||||
Storage::disk('public')->delete($article->image);
|
||||
}
|
||||
$article->delete();
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Artikel berhasil dihapus.']);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menghapus artikel: ' . $e->getMessage());
|
||||
|
||||
return response()->json(['success' => false, 'message' => 'Gagal menghapus artikel.'], 500);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\CardArticle;
|
||||
use App\Models\Article;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class AdminCardArticleController extends Controller
|
||||
{
|
||||
public function indexAdminArtikel(Request $request)
|
||||
{
|
||||
try {
|
||||
$artikelPage = $request->get('artikel_page', 1);
|
||||
$articles = CardArticle::where('user_id', Auth::id())
|
||||
->withCount('articles')
|
||||
->latest()
|
||||
->paginate(5, ['*'], 'artikel_page', $artikelPage);
|
||||
|
||||
$approvedCount = Article::where('status', 'Disetujui')
|
||||
->where('user_id', Auth::id())
|
||||
->count();
|
||||
|
||||
return view('admin.add-card-article', compact('articles', 'approvedCount'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat data artikel: ' . $e->getMessage());
|
||||
return redirect()->route('admin.add-article')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memuat data artikel.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function storeAdminArtikel(Request $request)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'description' => 'required|string',
|
||||
'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
|
||||
], [
|
||||
'title.required' => 'Judul grup artikel harus diisi.',
|
||||
'title.max' => 'Judul grup artikel maksimal 255 karakter.',
|
||||
'description.required' => 'Deskripsi grup artikel harus diisi.',
|
||||
'image.required' => 'Gambar grup artikel harus diunggah.',
|
||||
'image.image' => 'File harus berupa gambar.',
|
||||
'image.mimes' => 'Format gambar harus jpeg, png, jpg, atau gif.',
|
||||
'image.max' => 'Ukuran gambar maksimal 2MB.'
|
||||
]);
|
||||
|
||||
$imagePath = null;
|
||||
if ($request->hasFile('image')) {
|
||||
$imagePath = $request->file('image')->store('card_articles', 'public');
|
||||
}
|
||||
|
||||
$cardArticle = CardArticle::create([
|
||||
'title' => $validated['title'],
|
||||
'description' => $validated['description'],
|
||||
'image' => $imagePath,
|
||||
'user_id' => Auth::id(),
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.add-article')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Artikel grup berhasil ditambahkan!',
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()
|
||||
->withErrors($e->validator)
|
||||
->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menyimpan artikel: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('admin.add-article')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menyimpan artikel.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateAdminArtikel(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'description' => 'required|string',
|
||||
'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
|
||||
], [
|
||||
'title.required' => 'Judul grup artikel harus diisi.',
|
||||
'title.max' => 'Judul grup artikel maksimal 255 karakter.',
|
||||
'description.required' => 'Deskripsi grup artikel harus diisi.',
|
||||
'image.image' => 'File harus berupa gambar.',
|
||||
'image.mimes' => 'Format gambar harus jpeg, png, jpg, atau gif.',
|
||||
'image.max' => 'Ukuran gambar maksimal 2MB.'
|
||||
]);
|
||||
|
||||
$card = CardArticle::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$imagePath = $card->image;
|
||||
|
||||
if ($request->hasFile('image')) {
|
||||
if ($imagePath && Storage::disk('public')->exists($imagePath)) {
|
||||
Storage::disk('public')->delete($imagePath);
|
||||
Log::info('Gambar lama berhasil dihapus: ' . $imagePath);
|
||||
}
|
||||
|
||||
$newImagePath = $request->file('image')->store('card_articles', 'public');
|
||||
Log::info('Gambar baru berhasil disimpan: ' . $newImagePath);
|
||||
$imagePath = $newImagePath;
|
||||
}
|
||||
|
||||
$card->update([
|
||||
'title' => $validated['title'],
|
||||
'description' => $validated['description'],
|
||||
'image' => $imagePath,
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.add-article')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Artikel grup berhasil diperbarui!',
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()
|
||||
->withErrors($e->validator)
|
||||
->withInput();
|
||||
} catch (ModelNotFoundException $e) {
|
||||
return redirect()->route('admin.add-article')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Artikel grup tidak ditemukan.',
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memperbarui artikel grup: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('admin.add-article')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memperbarui artikel grup.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteAdminArtikel($id)
|
||||
{
|
||||
try {
|
||||
$cardArticle = CardArticle::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
if ($cardArticle->image) {
|
||||
Storage::disk('public')->delete($cardArticle->image);
|
||||
}
|
||||
$cardArticle->delete();
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Grup artikel berhasil dihapus.']);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menghapus artikel: ' . $e->getMessage());
|
||||
return response()->json(['success' => false, 'message' => 'Gagal menghapus artikel.'], 500);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,261 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\SubArticle;
|
||||
use App\Models\Article;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class AdminSubArticleController extends Controller
|
||||
{
|
||||
|
||||
public function indexAdminArtikel(Request $request)
|
||||
{
|
||||
try {
|
||||
$subArticle = null;
|
||||
$articles = Article::where('user_id', Auth::id())->get();
|
||||
$selectedArticle = null;
|
||||
$subArticles = collect();
|
||||
|
||||
$articleId = $request->query('article_id');
|
||||
if ($articleId) {
|
||||
$selectedArticle = Article::with(['subArticles' => function ($query) {
|
||||
$query->orderBy('order_number', 'asc')
|
||||
->orderBy('id', 'desc');
|
||||
}])->where('user_id', Auth::id())->find($articleId);
|
||||
|
||||
if ($selectedArticle) {
|
||||
$subArticles = $selectedArticle->subArticles;
|
||||
}
|
||||
}
|
||||
|
||||
$editId = $request->query('edit_id');
|
||||
if ($editId) {
|
||||
$subArticle = SubArticle::where('id', $editId)
|
||||
->whereHas('article', function ($query) {
|
||||
$query->where('user_id', Auth::id());
|
||||
})
|
||||
->first();
|
||||
}
|
||||
|
||||
return view('admin.add-article-sub', compact('subArticles', 'articles', 'selectedArticle', 'subArticle'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat sub-artikel: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('admin.add-article-sub')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memuat data sub-artikel.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function storeMultipleSubArticles(Request $request)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'article_id' => 'required|exists:articles,id',
|
||||
'sub_articles' => 'required|array|min:1',
|
||||
'sub_articles.*.title' => 'required|string|max:255',
|
||||
'sub_articles.*.content' => 'required|string',
|
||||
'sub_articles.*.order_number' => 'required|integer|min:1',
|
||||
'sub_articles.*.image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
|
||||
'sub_articles.*.remove_image' => 'nullable|in:0,1',
|
||||
], [
|
||||
'article_id.required' => 'Artikel induk harus dipilih.',
|
||||
'article_id.exists' => 'Artikel induk tidak ditemukan.',
|
||||
'sub_articles.required' => 'Minimal satu sub artikel harus diisi.',
|
||||
'sub_articles.min' => 'Minimal satu sub artikel harus diisi.',
|
||||
'sub_articles.*.title.required' => 'Judul sub artikel harus diisi.',
|
||||
'sub_articles.*.title.max' => 'Judul sub artikel maksimal 255 karakter.',
|
||||
'sub_articles.*.content.required' => 'Konten sub artikel harus diisi.',
|
||||
'sub_articles.*.order_number.required' => 'Urutan sub artikel harus diisi.',
|
||||
'sub_articles.*.order_number.integer' => 'Urutan sub artikel harus berupa angka.',
|
||||
'sub_articles.*.order_number.min' => 'Urutan sub artikel minimal 1.',
|
||||
'sub_articles.*.image.image' => 'File harus berupa gambar.',
|
||||
'sub_articles.*.image.mimes' => 'Format gambar harus jpeg, png, jpg, atau gif.',
|
||||
'sub_articles.*.image.max' => 'Ukuran gambar maksimal 2MB.',
|
||||
]);
|
||||
|
||||
$article = Article::where('id', $validated['article_id'])
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$subArticlesData = [];
|
||||
foreach ($validated['sub_articles'] as $subArticle) {
|
||||
$imagePath = null;
|
||||
|
||||
if (isset($subArticle['image']) && $subArticle['image'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$imagePath = $subArticle['image']->store('sub_articles', 'public');
|
||||
}
|
||||
|
||||
$subArticlesData[] = [
|
||||
'article_id' => $validated['article_id'],
|
||||
'title' => $subArticle['title'],
|
||||
'content' => $subArticle['content'],
|
||||
'order_number' => $subArticle['order_number'],
|
||||
'image' => $imagePath,
|
||||
'user_id' => Auth::id(),
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
];
|
||||
}
|
||||
|
||||
SubArticle::insert($subArticlesData);
|
||||
|
||||
return redirect()->route('admin.add-article-sub', ['article_id' => $validated['article_id']])->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Semua sub-artikel berhasil disimpan!',
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()->withErrors($e->validator)->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menyimpan sub-artikel: ' . $e->getMessage());
|
||||
return redirect()->route('admin.add-article-sub')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menyimpan sub-artikel: ' . $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateAdminArtikel(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$subArticle = SubArticle::where('id', $id)
|
||||
->whereHas('article', function ($query) {
|
||||
$query->where('user_id', Auth::id());
|
||||
})
|
||||
->firstOrFail();
|
||||
|
||||
$validated = $request->validate([
|
||||
'article_id' => 'required|exists:articles,id',
|
||||
'sub_articles' => 'required|array',
|
||||
'sub_articles.*.title' => 'required|string|max:255',
|
||||
'sub_articles.*.content' => 'required|string',
|
||||
'sub_articles.*.order_number' => 'required|integer|min:1',
|
||||
'sub_articles.*.image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
|
||||
'sub_articles.*.remove_image' => 'nullable|in:0,1',
|
||||
], [
|
||||
'article_id.required' => 'Artikel induk harus dipilih.',
|
||||
'article_id.exists' => 'Artikel induk tidak ditemukan.',
|
||||
'sub_articles.required' => 'Data sub artikel harus diisi.',
|
||||
'sub_articles.*.title.required' => 'Judul sub artikel harus diisi.',
|
||||
'sub_articles.*.title.max' => 'Judul sub artikel maksimal 255 karakter.',
|
||||
'sub_articles.*.content.required' => 'Konten sub artikel harus diisi.',
|
||||
'sub_articles.*.order_number.required' => 'Urutan sub artikel harus diisi.',
|
||||
'sub_articles.*.order_number.integer' => 'Urutan sub artikel harus berupa angka.',
|
||||
'sub_articles.*.order_number.min' => 'Urutan sub artikel minimal 1.',
|
||||
'sub_articles.*.image.image' => 'File harus berupa gambar.',
|
||||
'sub_articles.*.image.mimes' => 'Format gambar harus jpeg, png, jpg, atau gif.',
|
||||
'sub_articles.*.image.max' => 'Ukuran gambar maksimal 2MB.',
|
||||
]);
|
||||
|
||||
$removeImage = $request->input('sub_articles.0.remove_image', '0');
|
||||
$imagePath = $subArticle->image;
|
||||
|
||||
if ($removeImage === '1') {
|
||||
if ($imagePath && Storage::disk('public')->exists($imagePath)) {
|
||||
Storage::disk('public')->delete($imagePath);
|
||||
}
|
||||
$imagePath = null;
|
||||
}
|
||||
elseif ($request->hasFile('sub_articles.0.image')) {
|
||||
if ($imagePath && Storage::disk('public')->exists($imagePath)) {
|
||||
Storage::disk('public')->delete($imagePath);
|
||||
}
|
||||
$imagePath = $request->file('sub_articles.0.image')->store('sub_articles', 'public');
|
||||
}
|
||||
|
||||
$subArticle->update([
|
||||
'article_id' => $validated['article_id'],
|
||||
'title' => $validated['sub_articles'][0]['title'],
|
||||
'content' => $validated['sub_articles'][0]['content'],
|
||||
'order_number' => $validated['sub_articles'][0]['order_number'],
|
||||
'image' => $imagePath,
|
||||
]);
|
||||
|
||||
return redirect()->route('admin.add-article-sub', ['article_id' => $validated['article_id']])->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Sub-artikel berhasil diperbarui!',
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()->withErrors($e->validator)->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memperbarui sub-artikel: ' . $e->getMessage());
|
||||
return redirect()->route('admin.add-article-sub')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memperbarui sub-artikel: ' . $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function editAdminArtikel($id)
|
||||
{
|
||||
try {
|
||||
$subArticle = SubArticle::where('id', $id)
|
||||
->whereHas('article', function ($query) {
|
||||
$query->where('user_id', Auth::id());
|
||||
})
|
||||
->firstOrFail();
|
||||
|
||||
$selectedArticle = $subArticle->article;
|
||||
|
||||
$articles = Article::where('user_id', Auth::id())->get();
|
||||
|
||||
return view('admin.add-article-sub', compact('subArticle', 'selectedArticle', 'articles'));
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->route('admin.add-article-sub')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Sub-artikel tidak ditemukan atau tidak dapat diakses.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteAdminArtikel($id)
|
||||
{
|
||||
try {
|
||||
$subArticle = SubArticle::where('id', $id)
|
||||
->whereHas('article', function ($query) {
|
||||
$query->where('user_id', Auth::id());
|
||||
})
|
||||
->firstOrFail();
|
||||
|
||||
$articleId = $subArticle->article_id;
|
||||
|
||||
if ($subArticle->image) {
|
||||
Storage::disk('public')->delete($subArticle->image);
|
||||
}
|
||||
|
||||
$subArticle->delete();
|
||||
|
||||
if (request()->ajax() || request()->wantsJson()) {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Sub-artikel berhasil dihapus!'
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect()->route('admin.add-article-sub', ['article_id' => $articleId])->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Sub-artikel berhasil dihapus!',
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menghapus sub-artikel: ' . $e->getMessage());
|
||||
|
||||
if (request()->ajax() || request()->wantsJson()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Terjadi kesalahan saat menghapus sub-artikel: ' . $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
|
||||
return redirect()->route('admin.add-article-sub')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menghapus sub-artikel.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Article;
|
||||
use App\Models\CardArticle;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ArticleController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$cardArticles = CardArticle::whereHas('articles', function($q) {
|
||||
$q->where('status', 'Disetujui');
|
||||
})
|
||||
->with(['articles' => function($q) {
|
||||
$q->where('status', 'Disetujui')->with('subArticles');
|
||||
}])
|
||||
->withCount(['articles' => function($q) {
|
||||
$q->where('status', 'Disetujui');
|
||||
}])
|
||||
->latest()
|
||||
->take(8)
|
||||
->get();
|
||||
|
||||
$readingSpeed = 200;
|
||||
|
||||
foreach ($cardArticles as $card) {
|
||||
$totalReadingTime = 0;
|
||||
foreach ($card->articles as $article) {
|
||||
$text = $article->title . ' ' . $article->description;
|
||||
if ($article->subArticles && $article->subArticles->isNotEmpty()) {
|
||||
$subText = $article->subArticles
|
||||
->map(function ($sub) {
|
||||
return $sub->title . ' ' . $sub->content;
|
||||
})
|
||||
->implode(' ');
|
||||
$text .= ' ' . $subText;
|
||||
}
|
||||
$wordCount = str_word_count(strip_tags($text));
|
||||
$articleReadingTime = ceil($wordCount / $readingSpeed);
|
||||
$totalReadingTime += $articleReadingTime;
|
||||
}
|
||||
$card->readingTime = $totalReadingTime;
|
||||
}
|
||||
|
||||
$totalArticles = Article::where('status', 'Disetujui')->count();
|
||||
$totalUsers = User::count();
|
||||
|
||||
return view('home', compact('cardArticles', 'totalArticles', 'totalUsers'));
|
||||
}
|
||||
|
||||
public function showAllCards(Request $request)
|
||||
{
|
||||
$search = $request->get('search');
|
||||
$cardArticlesQuery = CardArticle::whereHas('articles', function ($q) {
|
||||
$q->where('status', 'Disetujui');
|
||||
})
|
||||
->withCount(['articles' => function ($q) {
|
||||
$q->where('status', 'Disetujui');
|
||||
}])
|
||||
->latest();
|
||||
|
||||
if ($search) {
|
||||
$cardArticlesQuery->where('title', 'like', '%' . $search . '%');
|
||||
}
|
||||
|
||||
$cardArticles = $cardArticlesQuery->paginate(8);
|
||||
|
||||
$readingSpeed = 200;
|
||||
|
||||
foreach ($cardArticles as $card) {
|
||||
$totalReadingTime = 0;
|
||||
foreach ($card->articles as $article) {
|
||||
$text = $article->title . ' ' . $article->description;
|
||||
|
||||
if ($article->subArticles && $article->subArticles->isNotEmpty()) {
|
||||
$subText = $article->subArticles
|
||||
->map(function ($sub) {
|
||||
return $sub->title . ' ' . $sub->content;
|
||||
})
|
||||
->implode(' ');
|
||||
|
||||
$text .= ' ' . $subText;
|
||||
}
|
||||
|
||||
$wordCount = str_word_count(strip_tags($text));
|
||||
$articleReadingTime = ceil($wordCount / $readingSpeed);
|
||||
$totalReadingTime += $articleReadingTime;
|
||||
}
|
||||
|
||||
$card->readingTime = $totalReadingTime;
|
||||
}
|
||||
|
||||
return view('livewire.pages.home.all-cards', compact('cardArticles'));
|
||||
}
|
||||
|
||||
public function showArticles(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$card = CardArticle::whereHas('articles', function($query) {
|
||||
$query->where('status', 'Disetujui');
|
||||
})->findOrFail($id);
|
||||
|
||||
$articlesQuery = $card->articles()
|
||||
->with('subArticles')
|
||||
->where('status', 'Disetujui');
|
||||
|
||||
if ($request->has('search')) {
|
||||
$search = $request->get('search');
|
||||
$articlesQuery->where('title', 'like', '%' . $search . '%');
|
||||
}
|
||||
|
||||
$articles = $articlesQuery->latest()->paginate(8);
|
||||
$readingSpeed = 200;
|
||||
|
||||
foreach ($articles as $article) {
|
||||
$text = $article->title . ' ' . $article->description;
|
||||
|
||||
if ($article->subArticles && $article->subArticles->isNotEmpty()) {
|
||||
$subText = $article->subArticles->map(function ($sub) {
|
||||
return $sub->title . ' ' . $sub->content;
|
||||
})->implode(' ');
|
||||
|
||||
$text .= ' ' . $subText;
|
||||
}
|
||||
|
||||
$wordCount = str_word_count(strip_tags($text));
|
||||
$article->readingTime = ceil($wordCount / $readingSpeed);
|
||||
}
|
||||
|
||||
$totalReadingTime = $articles->sum('readingTime');
|
||||
$card->readingTime = $totalReadingTime;
|
||||
|
||||
return view('livewire.pages.home.articles', compact('card', 'articles'));
|
||||
} catch (\Exception $e) {
|
||||
return redirect('/')->with('error', 'Card artikel tidak ditemukan atau tidak memiliki artikel yang disetujui.');
|
||||
}
|
||||
}
|
||||
|
||||
public function showArticleDetail($id)
|
||||
{
|
||||
$article = Article::with(['subArticles' => function ($query) {
|
||||
$query->orderBy('order_number', 'asc');
|
||||
}])->findOrFail($id);
|
||||
|
||||
return view('livewire.pages.home.article-detail', compact('article'));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class AuthenticatedSessionController extends Controller
|
||||
{
|
||||
/**
|
||||
* Protect the controller with the 'auth' middleware.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth')->except('store');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle login and redirect based on role.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'email' => ['required', 'email'],
|
||||
'password' => ['required'],
|
||||
]);
|
||||
|
||||
if (Auth::attempt($request->only('email', 'password'), $request->boolean('remember'))) {
|
||||
$request->session()->regenerate();
|
||||
|
||||
return redirect()->intended(RouteServiceProvider::HOME);
|
||||
}
|
||||
|
||||
return back()->withErrors([
|
||||
'email' => 'Kredensial yang diberikan salah.',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout the authenticated user and invalidate their session.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Request $request)
|
||||
{
|
||||
Auth::logout();
|
||||
|
||||
$request->session()->invalidate();
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Auth\Events\Verified;
|
||||
use Illuminate\Foundation\Auth\EmailVerificationRequest;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
|
||||
class VerifyEmailController extends Controller
|
||||
{
|
||||
|
||||
public function __invoke(EmailVerificationRequest $request): RedirectResponse
|
||||
{
|
||||
if ($request->user()->hasVerifiedEmail()) {
|
||||
return redirect()->intended(RouteServiceProvider::HOME.'?verified=1');
|
||||
}
|
||||
|
||||
if ($request->user()->markEmailAsVerified()) {
|
||||
event(new Verified($request->user()));
|
||||
}
|
||||
|
||||
return redirect()->intended(RouteServiceProvider::HOME.'?verified=1');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, ValidatesRequests;
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Models\KandangAyam;
|
||||
use Carbon\Carbon;
|
||||
use DB;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$userId = Auth::id();
|
||||
$totalKandangAyams = KandangAyam::where('status_kandang', 'Aktif')
|
||||
->where('user_id', $userId)
|
||||
->count();
|
||||
|
||||
$totalCapacity = KandangAyam::where('status_kandang', 'Aktif')
|
||||
->where('user_id', $userId)
|
||||
->sum('kapasitas');
|
||||
|
||||
$totalDeathsThisMonth = DB::table('harian_ayam')
|
||||
->whereMonth('tanggal_input', Carbon::now()->month)
|
||||
->whereYear('tanggal_input', Carbon::now()->year)
|
||||
->whereIn('id_populasi', function ($query) use ($userId) {
|
||||
$query->select('id')->from('populasi_ayam')->where('user_id', $userId);
|
||||
})
|
||||
->sum('jumlah_ayam_mati');
|
||||
|
||||
$currentMonthDeaths = DB::table('harian_ayam')
|
||||
->whereYear('tanggal_input', Carbon::now()->year)
|
||||
->whereMonth('tanggal_input', Carbon::now()->month)
|
||||
->whereIn('id_populasi', function ($query) use ($userId) {
|
||||
$query->select('id')->from('populasi_ayam')->where('user_id', $userId);
|
||||
})
|
||||
->sum('jumlah_ayam_mati');
|
||||
|
||||
$previousMonthDeaths = DB::table('harian_ayam')
|
||||
->whereYear('tanggal_input', Carbon::now()->year)
|
||||
->whereMonth('tanggal_input', Carbon::now()->subMonth()->month)
|
||||
->whereIn('id_populasi', function ($query) use ($userId) {
|
||||
$query->select('id')->from('populasi_ayam')->where('user_id', $userId);
|
||||
})
|
||||
->sum('jumlah_ayam_mati');
|
||||
|
||||
$percentageChange = 0;
|
||||
if ($previousMonthDeaths > 0) {
|
||||
$percentageChange = (($currentMonthDeaths - $previousMonthDeaths) / $previousMonthDeaths) * 100;
|
||||
}
|
||||
|
||||
$populasiSub = DB::table('populasi_ayam')
|
||||
->whereIn('status_ayam', ['Proses', 'Siap Panen'])
|
||||
->where('user_id', $userId)
|
||||
->select('kandang_id', DB::raw('SUM(jumlah_ayam_masuk) as total_ayam'))
|
||||
->groupBy('kandang_id');
|
||||
|
||||
$harianSub = DB::table('harian_ayam')
|
||||
->join('populasi_ayam', 'harian_ayam.id_populasi', '=', 'populasi_ayam.id')
|
||||
->whereIn('populasi_ayam.status_ayam', ['Proses', 'Siap Panen'])
|
||||
->where('populasi_ayam.user_id', $userId)
|
||||
->select('populasi_ayam.kandang_id',
|
||||
DB::raw('SUM(jumlah_ayam_sakit) as total_sick'),
|
||||
DB::raw('SUM(jumlah_ayam_mati) as total_dead'))
|
||||
->groupBy('populasi_ayam.kandang_id');
|
||||
$KandangAyams = DB::table('kandang_ayam')
|
||||
->where('user_id', $userId)
|
||||
->leftJoinSub($populasiSub, 'populasi', function ($join) {
|
||||
$join->on('kandang_ayam.id', '=', 'populasi.kandang_id');
|
||||
})
|
||||
->leftJoinSub($harianSub, 'harian', function ($join) {
|
||||
$join->on('kandang_ayam.id', '=', 'harian.kandang_id');
|
||||
})
|
||||
->select(
|
||||
'kandang_ayam.*',
|
||||
DB::raw('COALESCE(populasi.total_ayam, 0) as total_ayam'),
|
||||
DB::raw('COALESCE(harian.total_sick, 0) as total_sick'),
|
||||
DB::raw('COALESCE(harian.total_dead, 0) as total_dead')
|
||||
)
|
||||
->having('total_ayam', '>', 0)
|
||||
->paginate(5);
|
||||
|
||||
$pendapatanBulanIni = DB::table('pendapatan')
|
||||
->whereMonth('tanggal_transaksi', Carbon::now()->month)
|
||||
->whereYear('tanggal_transaksi', Carbon::now()->year)
|
||||
->where('user_id', $userId)
|
||||
->sum('total_pendapatan');
|
||||
|
||||
$pengeluaranBulanIni = DB::table('pengeluaran')
|
||||
->whereMonth('tanggal_pembelian', Carbon::now()->month)
|
||||
->whereYear('tanggal_pembelian', Carbon::now()->year)
|
||||
->where('user_id', $userId)
|
||||
->sum('total_biaya');
|
||||
|
||||
return view('dashboard', compact(
|
||||
'totalKandangAyams',
|
||||
'totalCapacity',
|
||||
'totalDeathsThisMonth',
|
||||
'percentageChange',
|
||||
'KandangAyams',
|
||||
'pendapatanBulanIni',
|
||||
'pengeluaranBulanIni',
|
||||
));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\KandangAyam;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class KandangAyamController extends Controller
|
||||
{
|
||||
public function indexKandangManagement(Request $request)
|
||||
{
|
||||
try {
|
||||
$kandangPage = $request->get('kandang_page', 1);
|
||||
$kandang = KandangAyam::where('user_id', Auth::id())
|
||||
->latest()
|
||||
->paginate(4, ['*'], 'kandang_page', $kandangPage);
|
||||
return view('cage-management', compact('kandang'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat data kandang: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('cage-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memuat data kandang.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function storeKandang(Request $request)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'nama_kandang' => 'required|string|max:255',
|
||||
'kapasitas' => 'required|integer|min:1',
|
||||
'status_kandang' => 'required|in:Aktif,Tidak Aktif',
|
||||
], [
|
||||
'nama_kandang.required' => 'Nama kandang harus diisi.',
|
||||
'nama_kandang.max' => 'Nama kandang maksimal 255 karakter.',
|
||||
'kapasitas.required' => 'Kapasitas kandang harus diisi.',
|
||||
'kapasitas.integer' => 'Kapasitas harus berupa angka.',
|
||||
'kapasitas.min' => 'Kapasitas kandang minimal 1.',
|
||||
'status_kandang.required' => 'Status kandang harus dipilih.',
|
||||
'status_kandang.in' => 'Status kandang tidak valid.',
|
||||
]);
|
||||
|
||||
try {
|
||||
$validated['user_id'] = Auth::id();
|
||||
KandangAyam::create($validated);
|
||||
return redirect()->route('cage-management')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Kandang berhasil ditambahkan.',
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menyimpan kandang: ' . $e->getMessage());
|
||||
return redirect()->route('cage-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menyimpan data kandang.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateKandang(Request $request, $id)
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'nama_kandang' => 'required|string|max:255',
|
||||
'kapasitas' => 'required|integer|min:1',
|
||||
'status_kandang' => 'required|in:Aktif,Tidak Aktif',
|
||||
], [
|
||||
'nama_kandang.required' => 'Nama kandang harus diisi.',
|
||||
'nama_kandang.max' => 'Nama kandang maksimal 255 karakter.',
|
||||
'kapasitas.required' => 'Kapasitas kandang harus diisi.',
|
||||
'kapasitas.integer' => 'Kapasitas harus berupa angka.',
|
||||
'kapasitas.min' => 'Kapasitas kandang minimal 1.',
|
||||
'status_kandang.required' => 'Status kandang harus dipilih.',
|
||||
'status_kandang.in' => 'Status kandang tidak valid.',
|
||||
]);
|
||||
|
||||
try {
|
||||
$kandang = KandangAyam::where('id', $id)->where('user_id', Auth::id())->firstOrFail();
|
||||
|
||||
if ($kandang->status_kandang === 'Aktif' && $validated['status_kandang'] === 'Tidak Aktif') {
|
||||
$activePopulations = $kandang->populasiAyam()
|
||||
->whereIn('status_ayam', ['Proses', 'Siap Panen'])
|
||||
->count();
|
||||
|
||||
if ($activePopulations > 0) {
|
||||
return redirect()->back()->with([
|
||||
'status' => 'warning',
|
||||
'message' => "Kandang ini memiliki $activePopulations populasi ayam aktif. Pastikan semua populasi sudah dipanen sebelum menonaktifkan kandang.",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$kandang->update($validated);
|
||||
return redirect()->route('cage-management')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Kandang berhasil diperbarui.',
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menyimpan kandang: ' . $e->getMessage());
|
||||
return redirect()->route('cage-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menyimpan data kandang.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function destroyKandang($id)
|
||||
{
|
||||
try {
|
||||
$kandang = KandangAyam::where('id', $id)->where('user_id', Auth::id())->firstOrFail();
|
||||
$kandang->delete();
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Kandang berhasil dihapus.']);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menghapus kandang: ' . $e->getMessage());
|
||||
|
||||
return response()->json(['success' => false, 'message' => 'Gagal menghapus kandang.'], 500);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Pendapatan;
|
||||
use App\Models\Pengeluaran;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Carbon\Carbon;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class KeuanganController extends Controller
|
||||
{
|
||||
|
||||
public function indexKeuangan(Request $request)
|
||||
{
|
||||
try {
|
||||
$bulan = $request->get('bulan', Carbon::now()->format('m'));
|
||||
$tahun = $request->get('tahun', Carbon::now()->format('Y'));
|
||||
if ($tahun == Carbon::now()->format('Y') && $bulan > Carbon::now()->format('m')) {
|
||||
$bulan = Carbon::now()->format('m');
|
||||
}
|
||||
if ($tahun > Carbon::now()->format('Y')) {
|
||||
$tahun = Carbon::now()->format('Y');
|
||||
}
|
||||
$namaBulan = Carbon::create()->month($bulan)->translatedFormat('F');
|
||||
$pendapatan = Pendapatan::where('user_id', Auth::id())
|
||||
->whereYear('tanggal_transaksi', $tahun)
|
||||
->whereMonth('tanggal_transaksi', $bulan)
|
||||
->orderBy('tanggal_transaksi', 'asc')
|
||||
->get()
|
||||
->map(function ($item) {
|
||||
return [
|
||||
'tanggal' => $item->tanggal_transaksi,
|
||||
'keterangan' => $item->kategori,
|
||||
'jumlah' => $item->jumlah * $item->harga_per_satuan,
|
||||
'tipe' => 'pendapatan',
|
||||
];
|
||||
});
|
||||
|
||||
$pengeluaran = Pengeluaran::where('user_id', Auth::id())
|
||||
->whereYear('tanggal_pembelian', $tahun)
|
||||
->whereMonth('tanggal_pembelian', $bulan)
|
||||
->orderBy('tanggal_pembelian', 'asc')
|
||||
->get()
|
||||
->map(function ($item) {
|
||||
return [
|
||||
'tanggal' => $item->tanggal_pembelian,
|
||||
'keterangan' => $item->category . ' - ' . $item->description,
|
||||
'jumlah' => $item->jumlah * $item->harga_per_satuan,
|
||||
'tipe' => 'pengeluaran',
|
||||
];
|
||||
});
|
||||
|
||||
$transaksi = collect($pendapatan)->merge($pengeluaran)->sortBy('tanggal');
|
||||
|
||||
$totalPendapatan = $pendapatan->sum('jumlah');
|
||||
$totalPengeluaran = $pengeluaran->sum('jumlah');
|
||||
$labaBersih = $totalPendapatan - $totalPengeluaran;
|
||||
|
||||
$totalPendapatanHarian = $transaksi->filter(fn($trx) => $trx['tipe'] === 'pendapatan')->sum('jumlah');
|
||||
$totalPengeluaranHarian = $transaksi->filter(fn($trx) => $trx['tipe'] === 'pengeluaran')->sum('jumlah');
|
||||
$totalSaldoHarian = $totalPendapatanHarian - $totalPengeluaranHarian;
|
||||
|
||||
return view('finance-management', compact(
|
||||
'transaksi',
|
||||
'totalPendapatan',
|
||||
'totalPengeluaran',
|
||||
'labaBersih',
|
||||
'bulan',
|
||||
'tahun',
|
||||
'namaBulan',
|
||||
'totalPendapatanHarian',
|
||||
'totalPengeluaranHarian',
|
||||
'totalSaldoHarian'
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat laporan keuangan: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('finance-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memuat laporan keuangan.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function exportPDF(Request $request)
|
||||
{
|
||||
$bulan = $request->get('bulan', Carbon::now()->format('m'));
|
||||
$tahun = $request->get('tahun', Carbon::now()->format('Y'));
|
||||
$namaBulan = Carbon::create()->month($bulan)->translatedFormat('F');
|
||||
$userId = Auth::id(); // Simpan user ID dalam variabel agar konsisten
|
||||
|
||||
$pendapatan = Pendapatan::where('user_id', $userId)
|
||||
->whereYear('tanggal_transaksi', $tahun)
|
||||
->whereMonth('tanggal_transaksi', $bulan)
|
||||
->orderBy('tanggal_transaksi', 'asc')
|
||||
->get()
|
||||
->map(fn($item) => [
|
||||
'tanggal' => $item->tanggal_transaksi,
|
||||
'keterangan' => $item->kategori,
|
||||
'jumlah' => $item->jumlah * $item->harga_per_satuan,
|
||||
'tipe' => 'pendapatan',
|
||||
]);
|
||||
|
||||
$pengeluaran = Pengeluaran::where('user_id', $userId) // Tambahkan filter user_id di sini
|
||||
->whereYear('tanggal_pembelian', $tahun)
|
||||
->whereMonth('tanggal_pembelian', $bulan)
|
||||
->orderBy('tanggal_pembelian', 'asc')
|
||||
->get()
|
||||
->map(fn($item) => [
|
||||
'tanggal' => $item->tanggal_pembelian,
|
||||
'keterangan' => $item->category . ' - ' . $item->description,
|
||||
'jumlah' => $item->jumlah * $item->harga_per_satuan,
|
||||
'tipe' => 'pengeluaran',
|
||||
]);
|
||||
|
||||
$transaksi = collect($pendapatan)->merge($pengeluaran)->sortBy('tanggal');
|
||||
$totalPendapatan = $pendapatan->sum('jumlah');
|
||||
$totalPengeluaran = $pengeluaran->sum('jumlah');
|
||||
$totalSaldo = $totalPendapatan - $totalPengeluaran;
|
||||
|
||||
// Tambahkan nama user ke dalam view untuk ditampilkan dalam PDF
|
||||
$user = Auth::user();
|
||||
|
||||
$pdf = Pdf::loadView('cetak.laporan-keuangan', compact(
|
||||
'transaksi', 'totalPendapatan', 'totalPengeluaran', 'totalSaldo', 'namaBulan', 'tahun', 'user'
|
||||
));
|
||||
|
||||
return $pdf->download("Laporan-Keuangan-{$user->name}-{$namaBulan}-{$tahun}.pdf");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Pakan;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class PakanController extends Controller
|
||||
{
|
||||
public function indexPakan(Request $request)
|
||||
{
|
||||
try {
|
||||
$pakanPage = $request->get('pakan_page', 1);
|
||||
$pakan = Pakan::where('user_id', Auth::id())
|
||||
->latest()
|
||||
->paginate(5, ['*'], 'pakan_page', $pakanPage);
|
||||
|
||||
return view('food-management', compact('pakan'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat data pakan: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('food-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memuat data pakan.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function storePakan(Request $request)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'nama_pakan' => 'required|string|max:255',
|
||||
'jenis_pakan' => 'required|string|max:255',
|
||||
'berat' => 'required|numeric|min:1',
|
||||
'tanggal_masuk' => 'required|date',
|
||||
'harga_per_kg' => 'required|numeric|min:1000'
|
||||
], [
|
||||
'nama_pakan.required' => 'Nama pakan harus diisi.',
|
||||
'nama_pakan.max' => 'Nama pakan maksimal 255 karakter.',
|
||||
'jenis_pakan.required' => 'Jenis pakan harus diisi.',
|
||||
'jenis_pakan.max' => 'Jenis pakan maksimal 255 karakter.',
|
||||
'berat.required' => 'Berat pakan harus diisi.',
|
||||
'berat.numeric' => 'Berat pakan harus berupa angka.',
|
||||
'berat.min' => 'Berat pakan minimal 1 kg.',
|
||||
'tanggal_masuk.required' => 'Tanggal masuk harus diisi.',
|
||||
'tanggal_masuk.date' => 'Format tanggal masuk tidak valid.',
|
||||
'harga_per_kg.required' => 'Harga per kg harus diisi.',
|
||||
'harga_per_kg.numeric' => 'Harga per kg harus berupa angka.',
|
||||
'harga_per_kg.min' => 'Harga per kg minimal Rp 1.000.'
|
||||
]);
|
||||
|
||||
$validated['user_id'] = Auth::id();
|
||||
Pakan::create($validated);
|
||||
|
||||
return redirect()->route('food-management')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Pakan berhasil ditambahkan.'
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()->withErrors($e->validator)->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menambah pakan: ' . $e->getMessage());
|
||||
return redirect()->route('food-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menambahkan pakan.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function updatePakan(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'nama_pakan' => 'required|string|max:255',
|
||||
'jenis_pakan' => 'required|string|max:255',
|
||||
'berat' => 'required|numeric|min:1',
|
||||
'tanggal_masuk' => 'required|date',
|
||||
'harga_per_kg' => 'required|numeric|min:1000'
|
||||
], [
|
||||
'nama_pakan.required' => 'Nama pakan harus diisi.',
|
||||
'nama_pakan.max' => 'Nama pakan maksimal 255 karakter.',
|
||||
'jenis_pakan.required' => 'Jenis pakan harus diisi.',
|
||||
'jenis_pakan.max' => 'Jenis pakan maksimal 255 karakter.',
|
||||
'berat.required' => 'Berat pakan harus diisi.',
|
||||
'berat.numeric' => 'Berat pakan harus berupa angka.',
|
||||
'berat.min' => 'Berat pakan minimal 1 kg.',
|
||||
'tanggal_masuk.required' => 'Tanggal masuk harus diisi.',
|
||||
'tanggal_masuk.date' => 'Format tanggal masuk tidak valid.',
|
||||
'harga_per_kg.required' => 'Harga per kg harus diisi.',
|
||||
'harga_per_kg.numeric' => 'Harga per kg harus berupa angka.',
|
||||
'harga_per_kg.min' => 'Harga per kg minimal Rp 1.000.'
|
||||
]);
|
||||
|
||||
$pakan = Pakan::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$pakan->update($validated);
|
||||
|
||||
return redirect()->route('food-management')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Pakan berhasil diperbarui.'
|
||||
]);
|
||||
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()->withErrors($e->validator)->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memperbarui pakan: ' . $e->getMessage());
|
||||
return redirect()->route('food-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memperbarui pakan.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function destroyPakan($id)
|
||||
{
|
||||
try {
|
||||
$pakan = Pakan::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
$pakan->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Pakan berhasil dihapus.'
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menghapus pakan: ' . $e->getMessage());
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Terjadi kesalahan saat menghapus pakan.'
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Pendapatan;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class PendapatanController extends Controller
|
||||
{
|
||||
|
||||
public function indexPendapatan(Request $request)
|
||||
{
|
||||
try {
|
||||
$pendapatanPage = $request->get('pendapatan_page', 1);
|
||||
|
||||
$pendapatan = Pendapatan::where('user_id', Auth::id())
|
||||
->orderBy('tanggal_transaksi', 'desc')
|
||||
->paginate(10, ['*'], 'pendapatan_page', $pendapatanPage);
|
||||
|
||||
return view('finance-management-income', compact('pendapatan'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat data pendapatan: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('finance-management-income')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memuat data pendapatan.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function storePendapatan(Request $request)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'kategori' => 'required|in:Penjualan Ayam,Penjualan Kotoran,Pendapatan Kemitraan',
|
||||
'jumlah' => 'required|numeric|min:1',
|
||||
'satuan' => 'required|in:ekor,kg,karung',
|
||||
'harga_per_satuan' => 'required|numeric|min:1000',
|
||||
'tanggal_transaksi' => 'required|date',
|
||||
'nama_pembeli' => 'nullable|string|max:255',
|
||||
'nama_perusahaan' => 'nullable|string|max:255',
|
||||
], [
|
||||
'kategori.required' => 'Kategori harus dipilih.',
|
||||
'kategori.in' => 'Kategori tidak valid.',
|
||||
'jumlah.required' => 'Jumlah harus diisi.',
|
||||
'jumlah.numeric' => 'Jumlah harus berupa angka.',
|
||||
'jumlah.min' => 'Jumlah minimal 1.',
|
||||
'satuan.required' => 'Satuan harus dipilih.',
|
||||
'satuan.in' => 'Satuan tidak valid.',
|
||||
'harga_per_satuan.required' => 'Harga per satuan harus diisi.',
|
||||
'harga_per_satuan.numeric' => 'Harga per satuan harus berupa angka.',
|
||||
'harga_per_satuan.min' => 'Harga per satuan minimal Rp 1.000.',
|
||||
'tanggal_transaksi.required' => 'Tanggal transaksi harus diisi.',
|
||||
'tanggal_transaksi.date' => 'Format tanggal transaksi tidak valid.',
|
||||
'nama_pembeli.max' => 'Nama pembeli maksimal 255 karakter.',
|
||||
'nama_perusahaan.max' => 'Nama perusahaan maksimal 255 karakter.'
|
||||
]);
|
||||
|
||||
$validated['user_id'] = Auth::id();
|
||||
|
||||
Pendapatan::create($validated);
|
||||
|
||||
return redirect()->route('finance-management-income')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Pendapatan berhasil ditambahkan.',
|
||||
]);
|
||||
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()
|
||||
->withErrors($e->validator)
|
||||
->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menyimpan pendapatan: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('finance-management-income')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menyimpan pendapatan.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function updatePendapatan(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'kategori' => 'required|in:Penjualan Ayam,Penjualan Kotoran,Pendapatan Kemitraan',
|
||||
'jumlah' => 'required|numeric|min:1',
|
||||
'satuan' => 'required|in:ekor,kg,karung',
|
||||
'harga_per_satuan' => 'required|numeric|min:1000',
|
||||
'tanggal_transaksi' => 'required|date',
|
||||
'nama_pembeli' => 'nullable|string|max:255',
|
||||
'nama_perusahaan' => 'nullable|string|max:255',
|
||||
], [
|
||||
'kategori.required' => 'Kategori harus dipilih.',
|
||||
'kategori.in' => 'Kategori tidak valid.',
|
||||
'jumlah.required' => 'Jumlah harus diisi.',
|
||||
'jumlah.numeric' => 'Jumlah harus berupa angka.',
|
||||
'jumlah.min' => 'Jumlah minimal 1.',
|
||||
'satuan.required' => 'Satuan harus dipilih.',
|
||||
'satuan.in' => 'Satuan tidak valid.',
|
||||
'harga_per_satuan.required' => 'Harga per satuan harus diisi.',
|
||||
'harga_per_satuan.numeric' => 'Harga per satuan harus berupa angka.',
|
||||
'harga_per_satuan.min' => 'Harga per satuan minimal Rp 1.000.',
|
||||
'tanggal_transaksi.required' => 'Tanggal transaksi harus diisi.',
|
||||
'tanggal_transaksi.date' => 'Format tanggal transaksi tidak valid.',
|
||||
'nama_pembeli.max' => 'Nama pembeli maksimal 255 karakter.',
|
||||
'nama_perusahaan.max' => 'Nama perusahaan maksimal 255 karakter.'
|
||||
]);
|
||||
|
||||
$pendapatan = Pendapatan::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$pendapatan->update($validated);
|
||||
|
||||
return redirect()->route('finance-management-income')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Pendapatan berhasil diperbarui.',
|
||||
]);
|
||||
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()
|
||||
->withErrors($e->validator)
|
||||
->withInput();
|
||||
} catch (ModelNotFoundException $e) {
|
||||
return redirect()->route('finance-management-income')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Data pendapatan tidak ditemukan.',
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memperbarui pendapatan: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('finance-management-income')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memperbarui pendapatan.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function destroyPendapatan(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$pendapatan = Pendapatan::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$pendapatan->delete();
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Pendapatan berhasil dihapus.']);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menghapus pendapatan: ' . $e->getMessage());
|
||||
|
||||
return response()->json(['success' => false, 'message' => 'Gagal menghapus pendapatan.'], 500);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Pengeluaran;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class PengeluaranController extends Controller
|
||||
{
|
||||
public function indexPengeluaran(Request $request)
|
||||
{
|
||||
try {
|
||||
$pengeluaranPage = $request->get('pengeluaran_page', 1);
|
||||
$pengeluaran = Pengeluaran::where('user_id', Auth::id())
|
||||
->orderBy('tanggal_pembelian', 'desc')
|
||||
->paginate(10, ['*'], 'pengeluaran_page', $pengeluaranPage);
|
||||
|
||||
return view('finance-management-outcome', compact('pengeluaran'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat data pengeluaran: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('finance-management-outcome')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memuat data pengeluaran.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function storePengeluaran(Request $request)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'category' => 'required|in:Pembelian Ayam,Pakan Ayam,Vitamin',
|
||||
'description' => 'nullable|string|max:255',
|
||||
'jumlah' => 'required|numeric|min:1',
|
||||
'satuan' => 'required|in:ekor,kg,karung,unit',
|
||||
'harga_per_satuan' => 'required|numeric|min:1',
|
||||
'tanggal_pembelian' => 'required|date',
|
||||
'supplier' => 'nullable|string|max:255',
|
||||
], [
|
||||
'category.required' => 'Kategori harus dipilih.',
|
||||
'category.in' => 'Kategori tidak valid.',
|
||||
'description.max' => 'Deskripsi pengeluaran maksimal 255 karakter.',
|
||||
'jumlah.required' => 'Jumlah harus diisi.',
|
||||
'jumlah.numeric' => 'Jumlah harus berupa angka.',
|
||||
'jumlah.min' => 'Jumlah minimal 1.',
|
||||
'satuan.required' => 'Satuan harus dipilih.',
|
||||
'satuan.in' => 'Satuan tidak valid.',
|
||||
'harga_per_satuan.required' => 'Harga per satuan harus diisi.',
|
||||
'harga_per_satuan.numeric' => 'Harga per satuan harus berupa angka.',
|
||||
'harga_per_satuan.min' => 'Harga per satuan minimal Rp 1.',
|
||||
'tanggal_pembelian.required' => 'Tanggal pembelian harus diisi.',
|
||||
'tanggal_pembelian.date' => 'Format tanggal pembelian tidak valid.',
|
||||
'supplier.max' => 'Nama supplier maksimal 255 karakter.',
|
||||
]);
|
||||
|
||||
$validated['user_id'] = Auth::id();
|
||||
$validated['total_biaya'] = $request->jumlah * $request->harga_per_satuan;
|
||||
|
||||
Pengeluaran::create($validated);
|
||||
|
||||
return redirect()->route('finance-management-outcome')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Pengeluaran berhasil ditambahkan.',
|
||||
]);
|
||||
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()
|
||||
->withErrors($e->validator)
|
||||
->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menyimpan pengeluaran: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('finance-management-outcome')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menyimpan pengeluaran.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function updatePengeluaran(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'category' => 'required|in:Pembelian Ayam,Pakan Ayam,Vitamin',
|
||||
'description' => 'nullable|string|max:255',
|
||||
'jumlah' => 'required|numeric|min:1',
|
||||
'satuan' => 'required|in:ekor,kg,karung,unit',
|
||||
'harga_per_satuan' => 'required|numeric|min:1',
|
||||
'tanggal_pembelian' => 'required|date',
|
||||
'supplier' => 'nullable|string|max:255',
|
||||
], [
|
||||
'category.required' => 'Kategori harus dipilih.',
|
||||
'category.in' => 'Kategori tidak valid.',
|
||||
'description.required' => 'Deskripsi pengeluaran harus diisi.',
|
||||
'description.max' => 'Deskripsi pengeluaran maksimal 255 karakter.',
|
||||
'jumlah.required' => 'Jumlah harus diisi.',
|
||||
'jumlah.numeric' => 'Jumlah harus berupa angka.',
|
||||
'jumlah.min' => 'Jumlah minimal 1.',
|
||||
'satuan.required' => 'Satuan harus dipilih.',
|
||||
'satuan.in' => 'Satuan tidak valid.',
|
||||
'harga_per_satuan.required' => 'Harga per satuan harus diisi.',
|
||||
'harga_per_satuan.numeric' => 'Harga per satuan harus berupa angka.',
|
||||
'harga_per_satuan.min' => 'Harga per satuan minimal Rp 1.',
|
||||
'tanggal_pembelian.required' => 'Tanggal pembelian harus diisi.',
|
||||
'tanggal_pembelian.date' => 'Format tanggal pembelian tidak valid.',
|
||||
'supplier.max' => 'Nama supplier maksimal 255 karakter.',
|
||||
]);
|
||||
|
||||
$pengeluaran = Pengeluaran::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$validated['total_biaya'] = $request->jumlah * $request->harga_per_satuan;
|
||||
$pengeluaran->update($validated);
|
||||
|
||||
return redirect()->route('finance-management-outcome')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Pengeluaran berhasil diperbarui.',
|
||||
]);
|
||||
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()
|
||||
->withErrors($e->validator)
|
||||
->withInput();
|
||||
} catch (ModelNotFoundException $e) {
|
||||
return redirect()->route('finance-management-outcome')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Data pengeluaran tidak ditemukan.',
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memperbarui pengeluaran: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('finance-management-outcome')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memperbarui pengeluaran.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function destroyPengeluaran(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$pengeluaran = Pengeluaran::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$pengeluaran->delete();
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Pengeluaran berhasil dihapus.']);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menghapus pengeluaran: ' . $e->getMessage());
|
||||
|
||||
return response()->json(['success' => false, 'message' => 'Gagal menghapus pengeluaran.'], 500);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Pakan;
|
||||
use App\Models\PenggunaanPakan;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class PenggunaanPakanController extends Controller
|
||||
{
|
||||
public function storePenggunaanPakan(Request $request)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'nama_pakan' => 'required|string|max:255',
|
||||
'tanggal_pakai' => 'required|date',
|
||||
'jumlah_pakai' => 'required|numeric|min:1',
|
||||
], [
|
||||
'nama_pakan.required' => 'Nama pakan harus dipilih.',
|
||||
'nama_pakan.max' => 'Nama pakan maksimal 255 karakter.',
|
||||
'tanggal_pakai.required' => 'Tanggal pakai harus diisi.',
|
||||
'tanggal_pakai.date' => 'Format tanggal pakai tidak valid.',
|
||||
'jumlah_pakai.required' => 'Jumlah pakai harus diisi.',
|
||||
'jumlah_pakai.numeric' => 'Jumlah pakai harus berupa angka.',
|
||||
'jumlah_pakai.min' => 'Minimal jumlah pakai adalah 1 kg.'
|
||||
]);
|
||||
|
||||
$pakan = Pakan::where('nama_pakan', $request->nama_pakan)->first();
|
||||
|
||||
if (!$pakan) {
|
||||
return redirect()->back()
|
||||
->withInput()
|
||||
->withErrors(['nama_pakan' => 'Pakan tidak ditemukan.']);
|
||||
}
|
||||
|
||||
if ($pakan->berat < $request->jumlah_pakai) {
|
||||
return redirect()->back()
|
||||
->withInput()
|
||||
->withErrors(['jumlah_pakai' => "Stok pakan tidak mencukupi. Tersedia: {$pakan->berat} kg"]);
|
||||
}
|
||||
|
||||
PenggunaanPakan::create([
|
||||
'pakan_id' => $pakan->id,
|
||||
'tanggal_pakai' => $request->tanggal_pakai,
|
||||
'jumlah_pakai' => $request->jumlah_pakai
|
||||
]);
|
||||
|
||||
$pakan->update([
|
||||
'berat' => $pakan->berat - $request->jumlah_pakai
|
||||
]);
|
||||
|
||||
return redirect()->route('food-management')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Penggunaan pakan berhasil disimpan.'
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()
|
||||
->withErrors($e->validator)
|
||||
->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menyimpan penggunaan pakan: ' . $e->getMessage());
|
||||
return redirect()->route('food-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menyimpan penggunaan pakan.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,518 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\PopulasiAyam;
|
||||
use App\Models\HarianAyam;
|
||||
use App\Models\KandangAyam;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class PopulasiHarianController extends Controller
|
||||
{
|
||||
public function indexChickenManagement(Request $request)
|
||||
{
|
||||
try {
|
||||
$populasiPage = $request->get('populasi_page', 1);
|
||||
$harianPage = $request->get('harian_page', 1);
|
||||
$populasi = PopulasiAyam::with('kandang')
|
||||
->where('user_id', Auth::id())
|
||||
->latest()
|
||||
->paginate(5, ['*'], 'populasi_page', $populasiPage);
|
||||
$harian = HarianAyam::whereHas('populasiAyam', function($query) {
|
||||
$query->where('user_id', Auth::id());
|
||||
})
|
||||
->latest()
|
||||
->paginate(5, ['*'], 'harian_page', $harianPage);
|
||||
|
||||
$batches = PopulasiAyam::where('user_id', Auth::id())->get();
|
||||
$kandang = KandangAyam::where('status_kandang', 'Aktif')
|
||||
->where('user_id', Auth::id())
|
||||
->get();
|
||||
$userId = Auth::id();
|
||||
$monthlyData = DB::table('harian_ayam')
|
||||
->join('populasi_ayam', 'harian_ayam.id_populasi', '=', 'populasi_ayam.id')
|
||||
->whereIn('populasi_ayam.status_ayam', ['Proses', 'Siap Panen'])
|
||||
->where('populasi_ayam.user_id', $userId)
|
||||
->select(
|
||||
DB::raw('MONTH(harian_ayam.tanggal_input) as month'),
|
||||
DB::raw('SUM(harian_ayam.jumlah_ayam_sakit) as sick'),
|
||||
DB::raw('SUM(harian_ayam.jumlah_ayam_mati) as dead')
|
||||
)
|
||||
->whereYear('harian_ayam.tanggal_input', Carbon::now()->year)
|
||||
->groupBy(DB::raw('MONTH(harian_ayam.tanggal_input)'))
|
||||
->orderBy('month')
|
||||
->get();
|
||||
|
||||
$todayData = DB::table('harian_ayam')
|
||||
->join('populasi_ayam', 'harian_ayam.id_populasi', '=', 'populasi_ayam.id')
|
||||
->whereIn('populasi_ayam.status_ayam', ['Proses', 'Siap Panen'])
|
||||
->where('populasi_ayam.user_id', $userId)
|
||||
->whereDate('harian_ayam.tanggal_input', Carbon::today())
|
||||
->select(
|
||||
DB::raw('SUM(harian_ayam.jumlah_ayam_sakit) as sick'),
|
||||
DB::raw('SUM(harian_ayam.jumlah_ayam_mati) as dead')
|
||||
)
|
||||
->first();
|
||||
|
||||
return view('chicken-management', compact('populasi', 'harian', 'batches', 'kandang', 'monthlyData', 'todayData'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat data: ' . $e->getMessage());
|
||||
return redirect()->back()->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memuat data.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function storePopulasi(Request $request)
|
||||
{
|
||||
try {
|
||||
$request->validate([
|
||||
'kandang_id' => 'required|exists:kandang_ayam,id',
|
||||
'batchCodeSuffix' => 'required|alpha_num|size:3|unique:populasi_ayam,kode_batch',
|
||||
'batchName' => 'required|string|max:255',
|
||||
'docDate' => 'required|date',
|
||||
'chickenQuantity' => 'required|integer|min:1',
|
||||
], [
|
||||
'kandang_id.required' => 'Kandang harus dipilih.',
|
||||
'kandang_id.exists' => 'Kandang yang dipilih tidak valid.',
|
||||
'batchCodeSuffix.required' => 'Kode populasi harus diisi.',
|
||||
'batchCodeSuffix.alpha_num' => 'Kode populasi hanya boleh berisi huruf dan angka.',
|
||||
'batchCodeSuffix.size' => 'Kode populasi harus terdiri dari 3 karakter.',
|
||||
'batchCodeSuffix.unique' => 'Kode populasi ini sudah digunakan, silakan gunakan kode lain.',
|
||||
'batchName.required' => 'Nama populasi harus diisi.',
|
||||
'batchName.max' => 'Nama populasi maksimal 255 karakter.',
|
||||
'docDate.required' => 'Tanggal DOC harus diisi.',
|
||||
'docDate.date' => 'Format tanggal DOC tidak valid.',
|
||||
'docDate.before_or_equal' => 'Tanggal DOC tidak boleh lebih dari hari ini.',
|
||||
'chickenQuantity.required' => 'Jumlah ayam masuk harus diisi.',
|
||||
'chickenQuantity.integer' => 'Jumlah ayam masuk harus berupa angka.',
|
||||
'chickenQuantity.min' => 'Jumlah ayam masuk minimal 1 ekor.',
|
||||
]);
|
||||
|
||||
$kandang = KandangAyam::where('id', $request->kandang_id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$totalAyamDiKandang = PopulasiAyam::where('kandang_id', $kandang->id)
|
||||
->where('user_id', Auth::id())
|
||||
->sum('jumlah_ayam_masuk');
|
||||
|
||||
if ($totalAyamDiKandang + $request->chickenQuantity > $kandang->kapasitas) {
|
||||
$sisaKapasitas = $kandang->kapasitas - $totalAyamDiKandang;
|
||||
|
||||
return redirect()->back()->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Jumlah ayam yang ingin ditambahkan melebihi kapasitas kandang. Kapasitas tersisa: ' .
|
||||
$sisaKapasitas . ' ekor, sedangkan Anda mencoba menambahkan ' .
|
||||
$request->chickenQuantity . ' ekor.'
|
||||
]);
|
||||
}
|
||||
$batchCode = 'POPULASI-' . strtoupper($request->batchCodeSuffix);
|
||||
|
||||
PopulasiAyam::create([
|
||||
'kode_batch' => $batchCode,
|
||||
'nama_batch' => $request->batchName,
|
||||
'tanggal_doc' => $request->docDate,
|
||||
'jumlah_ayam_masuk' => $request->chickenQuantity,
|
||||
'status_ayam' => 'Proses',
|
||||
'kandang_id' => $kandang->id,
|
||||
'user_id' => Auth::id(),
|
||||
]);
|
||||
|
||||
return redirect()->route('chicken-management')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Data populasi Ayam berhasil disimpan.'
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
$errors = $e->validator->errors()->all();
|
||||
return redirect()->back()->with('status', 'error')->with('message', $errors[0]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menyimpan data populasi ayam: ' . $e->getMessage());
|
||||
return redirect()->route('chicken-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menyimpan data populasi ayam.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function storeHarian(Request $request)
|
||||
{
|
||||
try {
|
||||
$request->validate([
|
||||
'dailyBatchName' => 'required|exists:populasi_ayam,id',
|
||||
'dailyDate' => 'required|date',
|
||||
'sickChicken' => 'required|integer|min:0',
|
||||
'deadChicken' => 'required|integer|min:0',
|
||||
], [
|
||||
'dailyBatchName.required' => 'Populasi ayam harus dipilih.',
|
||||
'dailyBatchName.exists' => 'Populasi ayam yang dipilih tidak valid.',
|
||||
'dailyDate.required' => 'Tanggal input harus diisi.',
|
||||
'dailyDate.date' => 'Format tanggal tidak valid.',
|
||||
'sickChicken.required' => 'Jumlah ayam sakit harus diisi.',
|
||||
'sickChicken.integer' => 'Jumlah ayam sakit harus berupa angka.',
|
||||
'sickChicken.min' => 'Jumlah ayam sakit tidak boleh negatif.',
|
||||
'deadChicken.required' => 'Jumlah ayam mati harus diisi.',
|
||||
'deadChicken.integer' => 'Jumlah ayam mati harus berupa angka.',
|
||||
'deadChicken.min' => 'Jumlah ayam mati tidak boleh negatif.',
|
||||
]);
|
||||
|
||||
$populasi = PopulasiAyam::where('id', $request->dailyBatchName)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$totalMatiSebelumnya = HarianAyam::where('id_populasi', $populasi->id)->sum('jumlah_ayam_mati');
|
||||
$totalSakitSebelumnya = HarianAyam::where('id_populasi', $populasi->id)->sum('jumlah_ayam_sakit');
|
||||
|
||||
$newSick = (int)$request->sickChicken;
|
||||
$newDead = (int)$request->deadChicken;
|
||||
|
||||
$totalMatiBaru = $totalMatiSebelumnya + $newDead;
|
||||
$totalSakitBaru = $totalSakitSebelumnya + $newSick;
|
||||
$totalKeseluruhan = $totalMatiBaru + $totalSakitBaru;
|
||||
|
||||
Log::info('Validation harian ayam:', [
|
||||
'populasi_id' => $populasi->id,
|
||||
'jumlah_ayam_masuk' => $populasi->jumlah_ayam_masuk,
|
||||
'total_mati_sebelumnya' => $totalMatiSebelumnya,
|
||||
'total_sakit_sebelumnya' => $totalSakitSebelumnya,
|
||||
'new_sick' => $newSick,
|
||||
'new_dead' => $newDead,
|
||||
'total_mati_baru' => $totalMatiBaru,
|
||||
'total_sakit_baru' => $totalSakitBaru,
|
||||
'total_keseluruhan' => $totalKeseluruhan
|
||||
]);
|
||||
|
||||
if ($totalKeseluruhan > $populasi->jumlah_ayam_masuk) {
|
||||
$availableCount = $populasi->jumlah_ayam_masuk - $totalMatiSebelumnya - $totalSakitSebelumnya;
|
||||
|
||||
return redirect()->back()->with([
|
||||
'status' => 'error',
|
||||
'message' => "Jumlah ayam sakit dan mati melebihi jumlah ayam tersedia. Jumlah tersedia: {$availableCount} ekor, sedangkan Anda mencoba menambahkan {$newSick} sakit dan {$newDead} mati (total: " . ($newSick + $newDead) . " ekor)."
|
||||
]);
|
||||
}
|
||||
|
||||
HarianAyam::create([
|
||||
'id_populasi' => $populasi->id,
|
||||
'nama_batch' => $populasi->nama_batch,
|
||||
'tanggal_input' => $request->dailyDate,
|
||||
'jumlah_ayam_sakit' => $newSick,
|
||||
'jumlah_ayam_mati' => $newDead,
|
||||
'user_id' => Auth::id(),
|
||||
]);
|
||||
|
||||
if ($totalMatiBaru == $populasi->jumlah_ayam_masuk) {
|
||||
$populasi->update(['status_ayam' => 'Sudah Panen']);
|
||||
}
|
||||
|
||||
return redirect()->route('chicken-management')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Data Harian Ayam berhasil disimpan.'
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menyimpan data harian ayam: ' . $e->getMessage());
|
||||
return redirect()->route('chicken-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menyimpan data harian ayam: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function destroyPopulasi($id)
|
||||
{
|
||||
try {
|
||||
$populasi = PopulasiAyam::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
$populasi->delete();
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Data berhasil dihapus.']);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menghapus data populasi: ' . $e->getMessage());
|
||||
return response()->json(['success' => false, 'message' => 'Gagal menghapus data.'], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function destroyHarian($id)
|
||||
{
|
||||
try {
|
||||
$harian = HarianAyam::where('id', $id)
|
||||
->whereHas('populasiAyam', function($query) {
|
||||
$query->where('user_id', Auth::id());
|
||||
})
|
||||
->firstOrFail();
|
||||
$harian->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Data Harian Ayam berhasil dihapus.'
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menghapus data harian ayam: ' . $e->getMessage());
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Terjadi kesalahan saat menghapus data harian ayam.'
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function updatePopulasi(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$populasi = PopulasiAyam::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$validated = $request->validate([
|
||||
'kandang_id' => 'required|exists:kandang_ayam,id',
|
||||
'batchCodeSuffix' => 'required|alpha_num|size:3|unique:populasi_ayam,kode_batch,'.$id.',id',
|
||||
'nama_batch' => 'required|string|max:255',
|
||||
'tanggal_doc' => 'required|date',
|
||||
'jumlah_ayam_masuk' => 'required|integer|min:1',
|
||||
'status_ayam' => 'required|in:Proses,Siap Panen,Sudah Panen',
|
||||
], [
|
||||
'kandang_id.required' => 'Kandang harus dipilih.',
|
||||
'kandang_id.exists' => 'Kandang yang dipilih tidak valid.',
|
||||
'batchCodeSuffix.required' => 'Kode populasi harus diisi.',
|
||||
'batchCodeSuffix.alpha_num' => 'Kode populasi hanya boleh berisi huruf dan angka.',
|
||||
'batchCodeSuffix.size' => 'Kode populasi harus terdiri dari 3 karakter.',
|
||||
'batchCodeSuffix.unique' => 'Kode populasi ini sudah digunakan, silakan gunakan kode lain.',
|
||||
'nama_batch.required' => 'Nama populasi harus diisi.',
|
||||
'nama_batch.max' => 'Nama populasi maksimal 255 karakter.',
|
||||
'tanggal_doc.required' => 'Tanggal DOC harus diisi.',
|
||||
'tanggal_doc.date' => 'Format tanggal DOC tidak valid.',
|
||||
'jumlah_ayam_masuk.required' => 'Jumlah ayam masuk harus diisi.',
|
||||
'jumlah_ayam_masuk.integer' => 'Jumlah ayam masuk harus berupa angka.',
|
||||
'jumlah_ayam_masuk.min' => 'Jumlah ayam masuk minimal 1 ekor.',
|
||||
'status_ayam.required' => 'Status ayam harus dipilih.',
|
||||
'status_ayam.in' => 'Status ayam tidak valid.',
|
||||
]);
|
||||
|
||||
$kandang = KandangAyam::where('id', $validated['kandang_id'])
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$changingCage = $populasi->kandang_id != $validated['kandang_id'];
|
||||
$totalAyamDiKandangBaru = PopulasiAyam::where('kandang_id', $validated['kandang_id'])
|
||||
->where('user_id', Auth::id())
|
||||
->where('id', '!=', $id)
|
||||
->sum('jumlah_ayam_masuk');
|
||||
|
||||
Log::info('Perhitungan kapasitas kandang:', [
|
||||
'kandang_id' => $validated['kandang_id'],
|
||||
'kapasitas_kandang' => $kandang->kapasitas,
|
||||
'total_populasi_lain' => $totalAyamDiKandangBaru,
|
||||
'populasi_yang_diedit_id' => $id,
|
||||
'jumlah_ayam_masuk_lama' => $populasi->jumlah_ayam_masuk,
|
||||
'jumlah_ayam_masuk_baru' => $validated['jumlah_ayam_masuk'],
|
||||
'sisa_kapasitas' => $kandang->kapasitas - $totalAyamDiKandangBaru
|
||||
]);
|
||||
|
||||
if ($totalAyamDiKandangBaru + $validated['jumlah_ayam_masuk'] > $kandang->kapasitas) {
|
||||
$sisaKapasitas = $kandang->kapasitas - $totalAyamDiKandangBaru;
|
||||
|
||||
return redirect()->back()->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Jumlah ayam yang ingin ditambahkan melebihi kapasitas kandang. Kapasitas tersisa: ' .
|
||||
$sisaKapasitas . ' ekor dari ' . $kandang->kapasitas . ' total kapasitas, sedangkan Anda mencoba menambahkan ' .
|
||||
$validated['jumlah_ayam_masuk'] . ' ekor.'
|
||||
]);
|
||||
}
|
||||
|
||||
$batchCode = 'POPULASI-' . strtoupper($validated['batchCodeSuffix']);
|
||||
|
||||
$populasi->update([
|
||||
'kode_batch' => $batchCode,
|
||||
'nama_batch' => $validated['nama_batch'],
|
||||
'tanggal_doc' => $validated['tanggal_doc'],
|
||||
'jumlah_ayam_masuk' => $validated['jumlah_ayam_masuk'],
|
||||
'status_ayam' => $validated['status_ayam'],
|
||||
'kandang_id' => $validated['kandang_id'],
|
||||
]);
|
||||
|
||||
return redirect()->route('chicken-management')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Data populasi Ayam berhasil diperbarui.'
|
||||
]);
|
||||
|
||||
} catch (ValidationException $e) {
|
||||
$errors = $e->validator->errors()->all();
|
||||
return redirect()->back()->with('status', 'error')->with('message', $errors[0]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memperbarui data populasi ayam: ' . $e->getMessage());
|
||||
return redirect()->route('chicken-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memperbarui data populasi ayam: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateHarian(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'dailyBatchName' => 'required|exists:populasi_ayam,id',
|
||||
'tanggal_input' => 'required|date',
|
||||
'jumlah_ayam_sakit' => 'required|integer|min:0',
|
||||
'jumlah_ayam_mati' => 'required|integer|min:0',
|
||||
], [
|
||||
'dailyBatchName.required' => 'Populasi ayam harus dipilih.',
|
||||
'dailyBatchName.exists' => 'Populasi ayam yang dipilih tidak valid.',
|
||||
'tanggal_input.required' => 'Tanggal input harus diisi.',
|
||||
'tanggal_input.date' => 'Format tanggal tidak valid.',
|
||||
'jumlah_ayam_sakit.required' => 'Jumlah ayam sakit harus diisi.',
|
||||
'jumlah_ayam_sakit.integer' => 'Jumlah ayam sakit harus berupa angka.',
|
||||
'jumlah_ayam_sakit.min' => 'Jumlah ayam sakit tidak boleh negatif.',
|
||||
'jumlah_ayam_mati.required' => 'Jumlah ayam mati harus diisi.',
|
||||
'jumlah_ayam_mati.integer' => 'Jumlah ayam mati harus berupa angka.',
|
||||
'jumlah_ayam_mati.min' => 'Jumlah ayam mati tidak boleh negatif.',
|
||||
]);
|
||||
|
||||
$harian = HarianAyam::where('id', $id)
|
||||
->whereHas('populasiAyam', function($query) {
|
||||
$query->where('user_id', Auth::id());
|
||||
})
|
||||
->firstOrFail();
|
||||
|
||||
$populasi = PopulasiAyam::where('id', $validated['dailyBatchName'])
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$totalMatiDariRecordLain = HarianAyam::where('id_populasi', $populasi->id)
|
||||
->where('id', '!=', $id)
|
||||
->sum('jumlah_ayam_mati');
|
||||
|
||||
$totalSakitDariRecordLain = HarianAyam::where('id_populasi', $populasi->id)
|
||||
->where('id', '!=', $id)
|
||||
->sum('jumlah_ayam_sakit');
|
||||
|
||||
$newSick = (int)$validated['jumlah_ayam_sakit'];
|
||||
$newDead = (int)$validated['jumlah_ayam_mati'];
|
||||
|
||||
$totalTerpantau = $totalMatiDariRecordLain + $totalSakitDariRecordLain + $newSick + $newDead;
|
||||
|
||||
Log::info('Update harian ayam calculation:', [
|
||||
'record_id' => $id,
|
||||
'populasi_id' => $populasi->id,
|
||||
'total_population' => $populasi->jumlah_ayam_masuk,
|
||||
'total_mati_record_lain' => $totalMatiDariRecordLain,
|
||||
'total_sakit_record_lain' => $totalSakitDariRecordLain,
|
||||
'new_sick' => $newSick,
|
||||
'new_dead' => $newDead,
|
||||
'total_terpantau' => $totalTerpantau
|
||||
]);
|
||||
|
||||
if ($totalTerpantau > $populasi->jumlah_ayam_masuk) {
|
||||
$availableCount = $populasi->jumlah_ayam_masuk - $totalMatiDariRecordLain - $totalSakitDariRecordLain;
|
||||
|
||||
return redirect()->back()->with([
|
||||
'status' => 'error',
|
||||
'message' => "Jumlah ayam sakit dan mati melebihi jumlah ayam tersedia. Jumlah tersedia: {$availableCount} ekor, sedangkan Anda mencoba mencatat {$newSick} sakit dan {$newDead} mati (total: " . ($newSick + $newDead) . " ekor)."
|
||||
]);
|
||||
}
|
||||
|
||||
$harian->update([
|
||||
'id_populasi' => $validated['dailyBatchName'],
|
||||
'nama_batch' => $populasi->nama_batch,
|
||||
'tanggal_input' => $validated['tanggal_input'],
|
||||
'jumlah_ayam_sakit' => $newSick,
|
||||
'jumlah_ayam_mati' => $newDead,
|
||||
]);
|
||||
|
||||
$totalMatiSetelahUpdate = HarianAyam::where('id_populasi', $populasi->id)->sum('jumlah_ayam_mati');
|
||||
if ($totalMatiSetelahUpdate == $populasi->jumlah_ayam_masuk) {
|
||||
$populasi->update(['status_ayam' => 'Sudah Panen']);
|
||||
}
|
||||
|
||||
return redirect()->route('chicken-management')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Data harian Ayam berhasil diperbarui.'
|
||||
]);
|
||||
|
||||
} catch (ValidationException $e) {
|
||||
$errors = $e->validator->errors()->all();
|
||||
return redirect()->back()->with('status', 'error')->with('message', $errors[0]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memperbarui data harian ayam: ' . $e->getMessage());
|
||||
return redirect()->route('chicken-management')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memperbarui data harian ayam: ' . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function cetak($id)
|
||||
{
|
||||
try {
|
||||
$populasi = PopulasiAyam::with('harianAyam')->findOrFail($id);
|
||||
$pdf = Pdf::loadView('cetak.laporan-populasi', compact('populasi'));
|
||||
return $pdf->download("Laporan_Manajemen_Ayam_{$populasi->kode_batch}.pdf");
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->back()->with('error', 'Gagal mencetak laporan.');
|
||||
}
|
||||
}
|
||||
|
||||
public function getAvailableChickenCount($batchId, $recordId = null)
|
||||
{
|
||||
try {
|
||||
$populasi = PopulasiAyam::where('id', $batchId)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$harianQuery = HarianAyam::where('id_populasi', $batchId);
|
||||
if ($recordId) {
|
||||
$harianQuery->where('id', '!=', $recordId);
|
||||
}
|
||||
|
||||
$totalSick = $harianQuery->sum('jumlah_ayam_sakit');
|
||||
$totalDead = $harianQuery->sum('jumlah_ayam_mati');
|
||||
|
||||
$availableCount = $populasi->jumlah_ayam_masuk - $totalSick - $totalDead;
|
||||
$availableCount = max(0, $availableCount);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'available_count' => $availableCount,
|
||||
'total_population' => $populasi->jumlah_ayam_masuk,
|
||||
'recorded_sick' => $totalSick,
|
||||
'recorded_dead' => $totalDead
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error retrieving chicken count: ' . $e->getMessage());
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Error retrieving data: ' . $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function getHarianRecord($id)
|
||||
{
|
||||
try {
|
||||
$harian = HarianAyam::where('id', $id)
|
||||
->whereHas('populasiAyam', function($query) {
|
||||
$query->where('user_id', Auth::id());
|
||||
})
|
||||
->firstOrFail();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $harian
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error retrieving harian record: ' . $e->getMessage());
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Error retrieving record data: ' . $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\CardArticle;
|
||||
use App\Models\Article;
|
||||
use App\Models\Tag;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class UserArticleController extends Controller
|
||||
{
|
||||
public function indexUserArtikel(Request $request)
|
||||
{
|
||||
try {
|
||||
$articlePage = $request->get('article_page', 1);
|
||||
$articles = Article::with('cardArticle')
|
||||
->where('user_id', Auth::id())
|
||||
->latest()
|
||||
->paginate(4, ['*'], 'article_page', $articlePage);
|
||||
$cardArticles = CardArticle::where('user_id', Auth::id())->get();
|
||||
$tags = Tag::all();
|
||||
$articles->appends(['article_page' => $articlePage]);
|
||||
$totalArticles = Article::where('user_id', Auth::id())->count();
|
||||
$todayArticles = Article::where('user_id', Auth::id())
|
||||
->whereDate('created_at', now())
|
||||
->count();
|
||||
return view('add-article-detail', compact(
|
||||
'articles',
|
||||
'cardArticles',
|
||||
'tags',
|
||||
'totalArticles',
|
||||
'todayArticles'
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat data artikel: ' . $e->getMessage());
|
||||
return redirect()->route('add-article-detail')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memuat data artikel.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function storeUserArtikel(Request $request)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'card_id' => 'required|exists:card_articles,id',
|
||||
'title' => 'required|string|max:255',
|
||||
'description' => 'required|string',
|
||||
'status' => 'required|string|in:Tertunda,Disetujui,Ditolak',
|
||||
'tags' => 'required|array|min:1|max:3',
|
||||
'tags.*' => 'exists:tags,id',
|
||||
'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
|
||||
], [
|
||||
'card_id.required' => 'Artikel grup harus dipilih',
|
||||
'card_id.exists' => 'Artikel grup yang dipilih tidak valid',
|
||||
'title.required' => 'Judul artikel harus diisi',
|
||||
'title.max' => 'Judul artikel maksimal 255 karakter',
|
||||
'description.required' => 'Deskripsi artikel harus diisi',
|
||||
'tags.required' => 'Minimal satu tag harus dipilih',
|
||||
'tags.array' => 'Format tag tidak valid',
|
||||
'tags.min' => 'Minimal satu tag harus dipilih',
|
||||
'tags.max' => 'Maksimal tiga tag yang dapat dipilih',
|
||||
'tags.*.exists' => 'Tag yang dipilih tidak valid',
|
||||
'image.required' => 'Gambar artikel harus diunggah',
|
||||
'image.image' => 'File harus berupa gambar',
|
||||
'image.mimes' => 'Format gambar harus jpeg, png, jpg, atau gif',
|
||||
'image.max' => 'Ukuran gambar maksimal 2MB',
|
||||
]);
|
||||
|
||||
$imagePath = null;
|
||||
if ($request->hasFile('image')) {
|
||||
$imagePath = $request->file('image')->store('articles', 'public');
|
||||
}
|
||||
|
||||
$article = Article::create([
|
||||
'card_id' => $validated['card_id'],
|
||||
'title' => $validated['title'],
|
||||
'description' => $validated['description'],
|
||||
'status' => $validated['status'],
|
||||
'image' => $imagePath,
|
||||
'user_id' => Auth::id(),
|
||||
]);
|
||||
|
||||
if (!empty($validated['tags'])) {
|
||||
$article->tags()->attach($validated['tags']);
|
||||
}
|
||||
|
||||
return redirect()->route('add-article-detail')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Artikel berhasil dibuat!',
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()
|
||||
->withErrors($e->validator)
|
||||
->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menyimpan artikel: ' . $e->getMessage());
|
||||
|
||||
return redirect()->back()->withInput()->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menyimpan artikel: ' . $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateUserArtikel(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'card_id' => 'required|exists:card_articles,id',
|
||||
'title' => 'required|string|max:255',
|
||||
'description' => 'required|string',
|
||||
'status' => 'required|string|in:Tertunda,Disetujui,Ditolak',
|
||||
'tags' => 'required|array|min:1|max:3',
|
||||
'tags.*' => 'exists:tags,id',
|
||||
'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
|
||||
], [
|
||||
'card_id.required' => 'Artikel grup harus dipilih',
|
||||
'card_id.exists' => 'Artikel grup yang dipilih tidak valid',
|
||||
'title.required' => 'Judul artikel harus diisi',
|
||||
'title.max' => 'Judul artikel maksimal 255 karakter',
|
||||
'description.required' => 'Deskripsi artikel harus diisi',
|
||||
'tags.required' => 'Minimal satu tag harus dipilih',
|
||||
'tags.array' => 'Format tag tidak valid',
|
||||
'tags.min' => 'Minimal satu tag harus dipilih',
|
||||
'tags.max' => 'Maksimal tiga tag yang dapat dipilih',
|
||||
'tags.*.exists' => 'Tag yang dipilih tidak valid',
|
||||
'image.image' => 'File harus berupa gambar',
|
||||
'image.mimes' => 'Format gambar harus jpeg, png, jpg, atau gif',
|
||||
'image.max' => 'Ukuran gambar maksimal 2MB',
|
||||
]);
|
||||
|
||||
$article = Article::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$imagePath = $article->image;
|
||||
if ($request->hasFile('image')) {
|
||||
if ($article->image && Storage::disk('public')->exists($article->image)) {
|
||||
Storage::disk('public')->delete($article->image);
|
||||
}
|
||||
$imagePath = $request->file('image')->store('articles', 'public');
|
||||
}
|
||||
|
||||
$article->update([
|
||||
'card_id' => $validated['card_id'],
|
||||
'title' => $validated['title'],
|
||||
'description' => $validated['description'],
|
||||
'status' => $validated['status'],
|
||||
'image' => $imagePath,
|
||||
]);
|
||||
|
||||
if (!empty($validated['tags'])) {
|
||||
$article->tags()->sync($validated['tags']);
|
||||
} else {
|
||||
$article->tags()->detach();
|
||||
}
|
||||
|
||||
return redirect()->route('add-article-detail')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Artikel berhasil diperbarui!',
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()
|
||||
->withErrors($e->validator)
|
||||
->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memperbarui artikel: ' . $e->getMessage());
|
||||
return redirect()->back()->withInput()->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memperbarui artikel: ' . $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteUserArtikel($id)
|
||||
{
|
||||
try {
|
||||
$article = Article::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$article->tags()->detach();
|
||||
if ($article->image) {
|
||||
Storage::disk('public')->delete($article->image);
|
||||
}
|
||||
$article->delete();
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Artikel berhasil dihapus.']);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menghapus artikel: ' . $e->getMessage());
|
||||
|
||||
return response()->json(['success' => false, 'message' => 'Gagal menghapus artikel.'], 500);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\CardArticle;
|
||||
use App\Models\Article;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class UserCardArticleController extends Controller
|
||||
{
|
||||
public function indexUserArtikel(Request $request)
|
||||
{
|
||||
try {
|
||||
$artikelPage = $request->get('artikel_page', 1);
|
||||
$articles = CardArticle::where('user_id', Auth::id())
|
||||
->withCount('articles')
|
||||
->latest()
|
||||
->paginate(5, ['*'], 'artikel_page', $artikelPage);
|
||||
|
||||
$pendingCount = Article::where('status', 'Tertunda')
|
||||
->where('user_id', Auth::id())
|
||||
->count();
|
||||
$approvedCount = Article::where('status', 'Disetujui')
|
||||
->where('user_id', Auth::id())
|
||||
->count();
|
||||
$rejectedCount = Article::where('status', 'Ditolak')
|
||||
->where('user_id', Auth::id())
|
||||
->count();
|
||||
|
||||
return view('add-card-article', compact('articles', 'pendingCount', 'approvedCount', 'rejectedCount'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat data artikel: ' . $e->getMessage());
|
||||
return redirect()->route('add-article')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memuat data artikel.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function storeUserArtikel(Request $request)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'description' => 'required|string',
|
||||
'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
|
||||
], [
|
||||
'title.required' => 'Judul grup artikel harus diisi.',
|
||||
'title.max' => 'Judul grup artikel maksimal 255 karakter.',
|
||||
'description.required' => 'Deskripsi grup artikel harus diisi.',
|
||||
'image.required' => 'Gambar grup artikel harus diunggah.',
|
||||
'image.image' => 'File harus berupa gambar.',
|
||||
'image.mimes' => 'Format gambar harus jpeg, png, jpg, atau gif.',
|
||||
'image.max' => 'Ukuran gambar maksimal 2MB.'
|
||||
]);
|
||||
|
||||
$imagePath = null;
|
||||
if ($request->hasFile('image')) {
|
||||
$imagePath = $request->file('image')->store('card_articles', 'public');
|
||||
}
|
||||
|
||||
$cardArticle = CardArticle::create([
|
||||
'title' => $validated['title'],
|
||||
'description' => $validated['description'],
|
||||
'image' => $imagePath,
|
||||
'user_id' => Auth::id(),
|
||||
]);
|
||||
|
||||
return redirect()->route('add-article')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Artikel grup berhasil ditambahkan!',
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()
|
||||
->withErrors($e->validator)
|
||||
->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menyimpan artikel: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('add-article')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menyimpan artikel.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateUserArtikel(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'title' => 'required|string|max:255',
|
||||
'description' => 'required|string',
|
||||
'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
|
||||
], [
|
||||
'title.required' => 'Judul grup artikel harus diisi.',
|
||||
'title.max' => 'Judul grup artikel maksimal 255 karakter.',
|
||||
'description.required' => 'Deskripsi grup artikel harus diisi.',
|
||||
'image.image' => 'File harus berupa gambar.',
|
||||
'image.mimes' => 'Format gambar harus jpeg, png, jpg, atau gif.',
|
||||
'image.max' => 'Ukuran gambar maksimal 2MB.'
|
||||
]);
|
||||
|
||||
$card = CardArticle::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$imagePath = $card->image;
|
||||
|
||||
if ($request->hasFile('image')) {
|
||||
if ($imagePath && Storage::disk('public')->exists($imagePath)) {
|
||||
Storage::disk('public')->delete($imagePath);
|
||||
Log::info('Gambar lama berhasil dihapus: ' . $imagePath);
|
||||
}
|
||||
|
||||
$newImagePath = $request->file('image')->store('card_articles', 'public');
|
||||
Log::info('Gambar baru berhasil disimpan: ' . $newImagePath);
|
||||
$imagePath = $newImagePath;
|
||||
}
|
||||
|
||||
$card->update([
|
||||
'title' => $validated['title'],
|
||||
'description' => $validated['description'],
|
||||
'image' => $imagePath,
|
||||
]);
|
||||
|
||||
return redirect()->route('add-article')->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Artikel grup berhasil diperbarui!',
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()
|
||||
->withErrors($e->validator)
|
||||
->withInput();
|
||||
} catch (ModelNotFoundException $e) {
|
||||
return redirect()->route('add-article')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Artikel grup tidak ditemukan.',
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memperbarui artikel grup: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('add-article')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memperbarui artikel grup.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteUserArtikel($id)
|
||||
{
|
||||
try {
|
||||
$cardArticle = CardArticle::where('id', $id)
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
if ($cardArticle->image) {
|
||||
Storage::disk('public')->delete($cardArticle->image);
|
||||
}
|
||||
$cardArticle->delete();
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Grup artikel berhasil dihapus.']);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menghapus artikel: ' . $e->getMessage());
|
||||
return response()->json(['success' => false, 'message' => 'Gagal menghapus artikel.'], 500);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,261 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\SubArticle;
|
||||
use App\Models\Article;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class UserSubArticleController extends Controller
|
||||
{
|
||||
|
||||
public function indexUserArtikel(Request $request)
|
||||
{
|
||||
try {
|
||||
$subArticle = null;
|
||||
$articles = Article::where('user_id', Auth::id())->get();
|
||||
$selectedArticle = null;
|
||||
$subArticles = collect();
|
||||
$articleId = $request->query('article_id');
|
||||
if ($articleId) {
|
||||
$selectedArticle = Article::with(['subArticles' => function ($query) {
|
||||
$query->orderBy('order_number', 'asc')
|
||||
->orderBy('id', 'desc');
|
||||
}])->where('user_id', Auth::id())->find($articleId);
|
||||
|
||||
if ($selectedArticle) {
|
||||
$subArticles = $selectedArticle->subArticles;
|
||||
}
|
||||
}
|
||||
|
||||
$editId = $request->query('edit_id');
|
||||
if ($editId) {
|
||||
$subArticle = SubArticle::where('id', $editId)
|
||||
->whereHas('article', function ($query) {
|
||||
$query->where('user_id', Auth::id());
|
||||
})
|
||||
->first();
|
||||
}
|
||||
|
||||
return view('add-article-sub', compact('subArticles', 'articles', 'selectedArticle', 'subArticle'));
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memuat sub-artikel: ' . $e->getMessage());
|
||||
|
||||
return redirect()->route('add-article-sub')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memuat data sub-artikel.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function storeMultipleSubArticles(Request $request)
|
||||
{
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'article_id' => 'required|exists:articles,id',
|
||||
'sub_articles' => 'required|array|min:1',
|
||||
'sub_articles.*.title' => 'required|string|max:255',
|
||||
'sub_articles.*.content' => 'required|string',
|
||||
'sub_articles.*.order_number' => 'required|integer|min:1',
|
||||
'sub_articles.*.image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
|
||||
'sub_articles.*.remove_image' => 'nullable|in:0,1',
|
||||
], [
|
||||
'article_id.required' => 'Artikel induk harus dipilih.',
|
||||
'article_id.exists' => 'Artikel induk tidak ditemukan.',
|
||||
'sub_articles.required' => 'Minimal satu sub artikel harus diisi.',
|
||||
'sub_articles.min' => 'Minimal satu sub artikel harus diisi.',
|
||||
'sub_articles.*.title.required' => 'Judul sub artikel harus diisi.',
|
||||
'sub_articles.*.title.max' => 'Judul sub artikel maksimal 255 karakter.',
|
||||
'sub_articles.*.content.required' => 'Konten sub artikel harus diisi.',
|
||||
'sub_articles.*.order_number.required' => 'Urutan sub artikel harus diisi.',
|
||||
'sub_articles.*.order_number.integer' => 'Urutan sub artikel harus berupa angka.',
|
||||
'sub_articles.*.order_number.min' => 'Urutan sub artikel minimal 1.',
|
||||
'sub_articles.*.image.image' => 'File harus berupa gambar.',
|
||||
'sub_articles.*.image.mimes' => 'Format gambar harus jpeg, png, jpg, atau gif.',
|
||||
'sub_articles.*.image.max' => 'Ukuran gambar maksimal 2MB.',
|
||||
]);
|
||||
|
||||
$article = Article::where('id', $validated['article_id'])
|
||||
->where('user_id', Auth::id())
|
||||
->firstOrFail();
|
||||
|
||||
$subArticlesData = [];
|
||||
foreach ($validated['sub_articles'] as $subArticle) {
|
||||
$imagePath = null;
|
||||
|
||||
if (isset($subArticle['image']) && $subArticle['image'] instanceof \Illuminate\Http\UploadedFile) {
|
||||
$imagePath = $subArticle['image']->store('sub_articles', 'public');
|
||||
}
|
||||
|
||||
$subArticlesData[] = [
|
||||
'article_id' => $validated['article_id'],
|
||||
'title' => $subArticle['title'],
|
||||
'content' => $subArticle['content'],
|
||||
'order_number' => $subArticle['order_number'],
|
||||
'image' => $imagePath,
|
||||
'user_id' => Auth::id(),
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
];
|
||||
}
|
||||
|
||||
SubArticle::insert($subArticlesData);
|
||||
|
||||
return redirect()->route('add-article-sub', ['article_id' => $validated['article_id']])->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Semua sub-artikel berhasil disimpan!',
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()->withErrors($e->validator)->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menyimpan sub-artikel: ' . $e->getMessage());
|
||||
return redirect()->route('add-article-sub')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menyimpan sub-artikel: ' . $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateUserArtikel(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$subArticle = SubArticle::where('id', $id)
|
||||
->whereHas('article', function ($query) {
|
||||
$query->where('user_id', Auth::id());
|
||||
})
|
||||
->firstOrFail();
|
||||
|
||||
$validated = $request->validate([
|
||||
'article_id' => 'required|exists:articles,id',
|
||||
'sub_articles' => 'required|array',
|
||||
'sub_articles.*.title' => 'required|string|max:255',
|
||||
'sub_articles.*.content' => 'required|string',
|
||||
'sub_articles.*.order_number' => 'required|integer|min:1',
|
||||
'sub_articles.*.image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
|
||||
'sub_articles.*.remove_image' => 'nullable|in:0,1',
|
||||
], [
|
||||
'article_id.required' => 'Artikel induk harus dipilih.',
|
||||
'article_id.exists' => 'Artikel induk tidak ditemukan.',
|
||||
'sub_articles.required' => 'Data sub artikel harus diisi.',
|
||||
'sub_articles.*.title.required' => 'Judul sub artikel harus diisi.',
|
||||
'sub_articles.*.title.max' => 'Judul sub artikel maksimal 255 karakter.',
|
||||
'sub_articles.*.content.required' => 'Konten sub artikel harus diisi.',
|
||||
'sub_articles.*.order_number.required' => 'Urutan sub artikel harus diisi.',
|
||||
'sub_articles.*.order_number.integer' => 'Urutan sub artikel harus berupa angka.',
|
||||
'sub_articles.*.order_number.min' => 'Urutan sub artikel minimal 1.',
|
||||
'sub_articles.*.image.image' => 'File harus berupa gambar.',
|
||||
'sub_articles.*.image.mimes' => 'Format gambar harus jpeg, png, jpg, atau gif.',
|
||||
'sub_articles.*.image.max' => 'Ukuran gambar maksimal 2MB.',
|
||||
]);
|
||||
|
||||
$removeImage = $request->input('sub_articles.0.remove_image', '0');
|
||||
$imagePath = $subArticle->image;
|
||||
|
||||
if ($removeImage === '1') {
|
||||
if ($imagePath && Storage::disk('public')->exists($imagePath)) {
|
||||
Storage::disk('public')->delete($imagePath);
|
||||
}
|
||||
$imagePath = null;
|
||||
}
|
||||
elseif ($request->hasFile('sub_articles.0.image')) {
|
||||
if ($imagePath && Storage::disk('public')->exists($imagePath)) {
|
||||
Storage::disk('public')->delete($imagePath);
|
||||
}
|
||||
$imagePath = $request->file('sub_articles.0.image')->store('sub_articles', 'public');
|
||||
}
|
||||
|
||||
$subArticle->update([
|
||||
'article_id' => $validated['article_id'],
|
||||
'title' => $validated['sub_articles'][0]['title'],
|
||||
'content' => $validated['sub_articles'][0]['content'],
|
||||
'order_number' => $validated['sub_articles'][0]['order_number'],
|
||||
'image' => $imagePath,
|
||||
]);
|
||||
|
||||
return redirect()->route('add-article-sub', ['article_id' => $validated['article_id']])->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Sub-artikel berhasil diperbarui!',
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
return redirect()->back()->withErrors($e->validator)->withInput();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal memperbarui sub-artikel: ' . $e->getMessage());
|
||||
return redirect()->route('add-article-sub')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat memperbarui sub-artikel: ' . $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function editUserArtikel($id)
|
||||
{
|
||||
try {
|
||||
$subArticle = SubArticle::where('id', $id)
|
||||
->whereHas('article', function ($query) {
|
||||
$query->where('user_id', Auth::id());
|
||||
})
|
||||
->firstOrFail();
|
||||
|
||||
$selectedArticle = $subArticle->article;
|
||||
|
||||
$articles = Article::where('user_id', Auth::id())->get();
|
||||
|
||||
return view('add-article-sub', compact('subArticle', 'selectedArticle', 'articles'));
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->route('add-article-sub')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Sub-artikel tidak ditemukan atau tidak dapat diakses.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteUserArtikel($id)
|
||||
{
|
||||
try {
|
||||
$subArticle = SubArticle::where('id', $id)
|
||||
->whereHas('article', function ($query) {
|
||||
$query->where('user_id', Auth::id());
|
||||
})
|
||||
->firstOrFail();
|
||||
|
||||
$articleId = $subArticle->article_id;
|
||||
|
||||
if ($subArticle->image) {
|
||||
Storage::disk('public')->delete($subArticle->image);
|
||||
}
|
||||
|
||||
$subArticle->delete();
|
||||
|
||||
if (request()->ajax() || request()->wantsJson()) {
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Sub-artikel berhasil dihapus!'
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect()->route('add-article-sub', ['article_id' => $articleId])->with([
|
||||
'status' => 'success',
|
||||
'message' => 'Sub-artikel berhasil dihapus!',
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Gagal menghapus sub-artikel: ' . $e->getMessage());
|
||||
|
||||
if (request()->ajax() || request()->wantsJson()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Terjadi kesalahan saat menghapus sub-artikel: ' . $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
|
||||
return redirect()->route('add-article-sub')->with([
|
||||
'status' => 'error',
|
||||
'message' => 'Terjadi kesalahan saat menghapus sub-artikel.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array<int, class-string|string>
|
||||
*/
|
||||
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<string, array<int, class-string|string>>
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's middleware aliases.
|
||||
*
|
||||
* Aliases may be used instead of class names to conveniently assign middleware to routes and groups.
|
||||
*
|
||||
* @var array<string, class-string|string>
|
||||
*/
|
||||
protected $middlewareAliases = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
|
||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'admin' => \App\Http\Middleware\AdminMiddleware::class,
|
||||
'user' => \App\Http\Middleware\UserMiddleware::class,
|
||||
];
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class AdminMiddleware
|
||||
{
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if (Auth::check() && Auth::user()->role === 'admin') {
|
||||
return $next($request);
|
||||
}
|
||||
return redirect()->route('dashboard'); // Redirect user biasa ke dashboard
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*/
|
||||
protected function redirectTo(Request $request): ?string
|
||||
{
|
||||
return $request->expectsJson() ? null : route('login');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
public function handle(Request $request, Closure $next, ...$guards): Response
|
||||
{
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect()->intended(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
||||
class TrustHosts extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the host patterns that should be trusted.
|
||||
*
|
||||
* @return array<int, string|null>
|
||||
*/
|
||||
public function hosts(): array
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array<int, string>|string|null
|
||||
*/
|
||||
protected $proxies;
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class UserMiddleware
|
||||
{
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if (Auth::check() && Auth::user()->role === 'user') {
|
||||
return $next($request);
|
||||
}
|
||||
return redirect()->route('dashboard'); // Redirect jika bukan user
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
|
||||
|
||||
class ValidateSignature extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the query string parameters that should be ignored.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
// 'fbclid',
|
||||
// 'utm_campaign',
|
||||
// 'utm_content',
|
||||
// 'utm_medium',
|
||||
// 'utm_source',
|
||||
// 'utm_term',
|
||||
];
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreArticleRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreArticleTagRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreCardArticleRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreHarianAyamRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreKandangAyamRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StorePakanRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StorePendapatanRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StorePengeluaranRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StorePenggunaanPakanRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StorePopulasiAyamRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreSubArticleRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreTagRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateArticleRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateArticleTagRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateCardArticleRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateHarianAyamRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateKandangAyamRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdatePakanRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdatePendapatanRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdatePengeluaranRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdatePenggunaanPakanRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdatePopulasiAyamRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateSubArticleRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateTagRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Actions;
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class Logout
|
||||
{
|
||||
public function __invoke(): void
|
||||
{
|
||||
Auth::guard('web')->logout();
|
||||
|
||||
Session::invalidate();
|
||||
Session::regenerateToken();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Forms;
|
||||
|
||||
use Illuminate\Auth\Events\Lockout;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Form;
|
||||
|
||||
class LoginForm extends Form
|
||||
{
|
||||
#[Validate('required|email:rfc,dns|string|max:255')]
|
||||
public string $email = '';
|
||||
|
||||
#[Validate('required|string|min:8')]
|
||||
public string $password = '';
|
||||
|
||||
#[Validate('boolean')]
|
||||
public bool $remember = false;
|
||||
|
||||
protected function messages(): array
|
||||
{
|
||||
return [
|
||||
'email.required' => 'Email wajib diisi.',
|
||||
'email.email' => 'Format email tidak valid.',
|
||||
'email.max' => 'Email tidak boleh lebih dari 255 karakter.',
|
||||
'password.required' => 'Kata sandi wajib diisi.',
|
||||
'password.min' => 'Kata sandi minimal terdiri dari 8 karakter.',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function authenticate(): void
|
||||
{
|
||||
$this->validate();
|
||||
$this->ensureIsNotRateLimited();
|
||||
$user = \App\Models\User::where('email', $this->email)->first();
|
||||
if (!$user) {
|
||||
RateLimiter::hit($this->throttleKey());
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'form.email' => 'Email tidak terdaftar.',
|
||||
]);
|
||||
}
|
||||
if (!Auth::attempt($this->only(['email', 'password']), $this->remember)) {
|
||||
RateLimiter::hit($this->throttleKey());
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'form.password' => 'Kata sandi yang Anda masukkan salah.',
|
||||
]);
|
||||
}
|
||||
RateLimiter::clear($this->throttleKey());
|
||||
}
|
||||
|
||||
protected function ensureIsNotRateLimited(): void
|
||||
{
|
||||
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
|
||||
return;
|
||||
}
|
||||
event(new Lockout(request()));
|
||||
$seconds = RateLimiter::availableIn($this->throttleKey());
|
||||
throw ValidationException::withMessages([
|
||||
'form.email' => trans('auth.throttle', [
|
||||
'seconds' => $seconds,
|
||||
'minutes' => ceil($seconds / 60),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
protected function throttleKey(): string
|
||||
{
|
||||
return Str::transliterate(Str::lower($this->email).'|'.request()->ip());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Forum;
|
||||
|
||||
use Livewire\Attributes\On;
|
||||
use Livewire\Component;
|
||||
use App\Models\Comment;
|
||||
use App\Models\Topic;
|
||||
|
||||
class CommentList extends Component
|
||||
{
|
||||
public $topic;
|
||||
public $newComment = '';
|
||||
public $replyingTo = null;
|
||||
public $parentComment = null;
|
||||
|
||||
protected $rules = [
|
||||
'newComment' => 'required|min:3|max:500'
|
||||
];
|
||||
|
||||
protected $messages = [
|
||||
'newComment.required' => 'Komentar tidak boleh kosong',
|
||||
'newComment.min' => 'Komentar minimal 3 karakter',
|
||||
'newComment.max' => 'Komentar maksimsal 500 karakter',
|
||||
];
|
||||
|
||||
#[On('commentAdded')]
|
||||
public function refreshComments()
|
||||
{
|
||||
$this->topic = Topic::with(['comments' => function($query) {
|
||||
$query->with(['user', 'replies.user']);
|
||||
}])->find($this->topic->id);
|
||||
}
|
||||
|
||||
public function mount(Topic $topic)
|
||||
{
|
||||
$this->topic = $topic;
|
||||
}
|
||||
|
||||
public function startReply($commentId)
|
||||
{
|
||||
$this->replyingTo = $commentId;
|
||||
$this->parentComment = Comment::find($commentId);
|
||||
}
|
||||
|
||||
public function cancelReply()
|
||||
{
|
||||
$this->replyingTo = null;
|
||||
$this->parentComment = null;
|
||||
}
|
||||
|
||||
public function addComment()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
$comment = Comment::create([
|
||||
'topic_id' => $this->topic->id,
|
||||
'user_id' => auth()->id(),
|
||||
'content' => $this->newComment,
|
||||
'parent_id' => $this->replyingTo
|
||||
]);
|
||||
|
||||
$this->reset('newComment');
|
||||
$this->cancelReply();
|
||||
|
||||
return redirect(request()->header('Referer'));
|
||||
}
|
||||
|
||||
protected $listeners = [
|
||||
'commentAdded' => '$refresh',
|
||||
'refreshComponent' => '$refresh'
|
||||
];
|
||||
|
||||
public function render()
|
||||
{
|
||||
$comments = $this->topic->comments()
|
||||
->with(['user', 'likes', 'replies.user', 'replies.likes'])
|
||||
->whereNull('parent_id')
|
||||
->latest()
|
||||
->get();
|
||||
|
||||
return view('livewire.forum.comment-list', [
|
||||
'comments' => $comments
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Forum;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Models\Topic;
|
||||
|
||||
class CreateTopic extends Component
|
||||
{
|
||||
public $title;
|
||||
public $content;
|
||||
protected $rules = [
|
||||
'title' => 'required|min:3',
|
||||
'content' => 'required|min:10',
|
||||
];
|
||||
protected $messages = [
|
||||
'title.required' => 'Judul topik tidak boleh kosong',
|
||||
'title.min' => 'Judul topik minimal 3 karakter',
|
||||
'content.required' => 'Isi topik tidak boleh kosong',
|
||||
'content.min' => 'Isi topik minimal 10 karakter'
|
||||
];
|
||||
public function submit()
|
||||
{
|
||||
$validated = $this->validate();
|
||||
$topic = Topic::create([
|
||||
'title' => $this->title,
|
||||
'content' => $this->content,
|
||||
'user_id' => auth()->id(),
|
||||
]);
|
||||
session()->flash('status', 'success');
|
||||
session()->flash('message', 'Topik berhasil dibuat!');
|
||||
return redirect()->route('forum.index');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.forum.create-topic')
|
||||
->extends('layouts.dashboard-layout')
|
||||
->section('content');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
namespace App\Livewire\Forum;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class LikeButton extends Component
|
||||
{
|
||||
public $model;
|
||||
public $likesCount;
|
||||
public $isLiked;
|
||||
|
||||
public function mount($model)
|
||||
{
|
||||
$this->model = $model;
|
||||
$this->updateLikeStatus();
|
||||
}
|
||||
|
||||
protected function updateLikeStatus()
|
||||
{
|
||||
$this->likesCount = $this->model->likes()->count();
|
||||
|
||||
$this->isLiked = auth()->check()
|
||||
? $this->model->likes()->where('user_id', auth()->id())->exists()
|
||||
: false;
|
||||
}
|
||||
|
||||
public function toggleLike()
|
||||
{
|
||||
if (!auth()->check()) {
|
||||
return redirect()->route('login');
|
||||
}
|
||||
|
||||
try {
|
||||
$existingLike = $this->model->likes()
|
||||
->where('user_id', auth()->id())
|
||||
->first();
|
||||
|
||||
if ($existingLike) {
|
||||
$existingLike->delete();
|
||||
} else {
|
||||
$this->model->likes()->create([
|
||||
'user_id' => auth()->id()
|
||||
]);
|
||||
}
|
||||
|
||||
$this->updateLikeStatus();
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Like Toggle Error', [
|
||||
'error' => $e->getMessage(),
|
||||
'model_type' => get_class($this->model),
|
||||
'model_id' => $this->model->id,
|
||||
'user_id' => auth()->id()
|
||||
]);
|
||||
|
||||
session()->flash('error', 'Unable to process like/unlike');
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.forum.like-button');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Forum;
|
||||
|
||||
use App\Models\Topic;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
use Livewire\Attributes\Url;
|
||||
|
||||
class TopicList extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
protected $paginationTheme = 'tailwind';
|
||||
#[Url]
|
||||
public $search = '';
|
||||
protected $listeners = ['topicCreated' => '$refresh'];
|
||||
public function mount()
|
||||
{
|
||||
$this->search = request()->get('search', '');
|
||||
$this->dispatch('listen-for-new-topic');
|
||||
}
|
||||
public function setSearch($value)
|
||||
{
|
||||
$this->search = $value;
|
||||
$this->resetPage();
|
||||
}
|
||||
public function render()
|
||||
{
|
||||
$topics = Topic::with('user')
|
||||
->withCount('comments', 'likes')
|
||||
->when($this->search, function($query) {
|
||||
return $query->where('title', 'like', '%' . $this->search . '%');
|
||||
})
|
||||
->latest()
|
||||
->paginate(10);
|
||||
return view('livewire.forum.topic-list', [
|
||||
'topics' => $topics
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Forum;
|
||||
|
||||
use App\Models\Topic;
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class TopicView extends Component
|
||||
{
|
||||
public $topic;
|
||||
public function mount($topic)
|
||||
{
|
||||
try {
|
||||
$this->topic = is_numeric($topic)
|
||||
? Topic::findOrFail($topic)
|
||||
: $topic;
|
||||
Log::info('Topic loaded', [
|
||||
'topic_id' => $this->topic->id,
|
||||
'topic_title' => $this->topic->title
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Topic loading error', [
|
||||
'error' => $e->getMessage(),
|
||||
'topic' => $topic
|
||||
]);
|
||||
|
||||
session()->flash('error', 'Topic not found');
|
||||
return redirect()->route('forum.index');
|
||||
}
|
||||
}
|
||||
public function render()
|
||||
{
|
||||
$topic = Topic::with(['user', 'comments'])
|
||||
->findOrFail($this->topic->id);
|
||||
return view('livewire.forum.topic-view');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
class Article extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'card_id',
|
||||
'title',
|
||||
'catatan',
|
||||
'description',
|
||||
'image',
|
||||
'status',
|
||||
'user_id',];
|
||||
|
||||
public function cardArticle(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CardArticle::class, 'card_id');
|
||||
}
|
||||
|
||||
public function subArticles(): HasMany
|
||||
{
|
||||
return $this->hasMany(SubArticle::class, 'article_id');
|
||||
}
|
||||
|
||||
public function tags()
|
||||
{
|
||||
return $this->belongsToMany(Tag::class, 'article_tags');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ArticleTag extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany; // Tambahkan namespace ini!
|
||||
|
||||
class CardArticle extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
protected $table = 'card_articles';
|
||||
protected $fillable = [
|
||||
'title',
|
||||
'description',
|
||||
'image',
|
||||
'user_id',
|
||||
];
|
||||
public function articles(): HasMany
|
||||
{
|
||||
return $this->hasMany(Article::class, 'card_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::deleting(function ($card) {
|
||||
// Hapus semua Articles terkait
|
||||
$card->articles()->each(function ($article) {
|
||||
// Hapus semua SubArticles terkait dengan Article
|
||||
$article->subArticles()->delete();
|
||||
// Hapus Article
|
||||
$article->delete();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Comment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = ['user_id', 'topic_id', 'content', 'parent_id'];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function topic()
|
||||
{
|
||||
return $this->belongsTo(Topic::class);
|
||||
}
|
||||
|
||||
public function likes()
|
||||
{
|
||||
return $this->morphMany(Like::class, 'likeable');
|
||||
}
|
||||
|
||||
public function parent()
|
||||
{
|
||||
return $this->belongsTo(Comment::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function replies()
|
||||
{
|
||||
return $this->hasMany(Comment::class, 'parent_id');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class HarianAyam extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'harian_ayam';
|
||||
|
||||
protected $fillable = [
|
||||
'id_populasi',
|
||||
'nama_batch',
|
||||
'tanggal_input',
|
||||
'jumlah_ayam_mati',
|
||||
'jumlah_ayam_sakit',
|
||||
'user_id',
|
||||
];
|
||||
|
||||
public function populasiAyam()
|
||||
{
|
||||
return $this->belongsTo(PopulasiAyam::class, 'id_populasi');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::creating(function ($harian) {
|
||||
$harian->nama_batch = $harian->populasiAyam->nama_batch;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class KandangAyam extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'kandang_ayam';
|
||||
|
||||
protected $fillable = [
|
||||
'nama_kandang',
|
||||
'kapasitas',
|
||||
'status_kandang',
|
||||
'user_id',
|
||||
];
|
||||
|
||||
const STATUS_AKTIF = 'Aktif';
|
||||
const STATUS_TIDAK_AKTIF = 'Tidak Aktif';
|
||||
|
||||
public static function getStatusOptions()
|
||||
{
|
||||
return [self::STATUS_AKTIF, self::STATUS_TIDAK_AKTIF];
|
||||
}
|
||||
|
||||
public function populasiAyam()
|
||||
{
|
||||
return $this->hasMany(PopulasiAyam::class, 'kandang_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Like extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = ['user_id', 'likeable_type', 'likeable_id'];
|
||||
|
||||
// Polymorphic relationship
|
||||
public function likeable()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Pakan extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'pakan';
|
||||
protected $fillable = [
|
||||
'nama_pakan',
|
||||
'jenis_pakan',
|
||||
'berat',
|
||||
'tanggal_masuk',
|
||||
'harga_per_kg',
|
||||
'user_id',
|
||||
];
|
||||
|
||||
// Relasi dengan PenggunaanPakan
|
||||
public function penggunaan()
|
||||
{
|
||||
return $this->hasMany(PenggunaanPakan::class, 'pakan_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Pendapatan extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
protected $table = 'pendapatan';
|
||||
protected $fillable = [
|
||||
'kategori',
|
||||
'jumlah',
|
||||
'satuan',
|
||||
'harga_per_satuan',
|
||||
'total_pendapatan',
|
||||
'tanggal_transaksi',
|
||||
'nama_pembeli',
|
||||
'nama_perusahaan',
|
||||
'user_id',
|
||||
];
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
static::creating(function ($pendapatan) {
|
||||
$pendapatan->total_pendapatan = $pendapatan->jumlah * $pendapatan->harga_per_satuan;
|
||||
});
|
||||
|
||||
static::updating(function ($pendapatan) {
|
||||
$pendapatan->total_pendapatan = $pendapatan->jumlah * $pendapatan->harga_per_satuan;
|
||||
});
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Pengeluaran extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
protected $table = 'pengeluaran';
|
||||
protected $fillable = [
|
||||
'category',
|
||||
'description',
|
||||
'jumlah',
|
||||
'satuan',
|
||||
'harga_per_satuan',
|
||||
'total_biaya',
|
||||
'supplier',
|
||||
'tanggal_pembelian',
|
||||
'user_id',
|
||||
];
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::creating(function ($pengeluaran) {
|
||||
$pengeluaran->total_biaya = $pengeluaran->jumlah * $pengeluaran->harga_per_satuan;
|
||||
});
|
||||
|
||||
static::updating(function ($pengeluaran) {
|
||||
$pengeluaran->total_biaya = $pengeluaran->jumlah * $pengeluaran->harga_per_satuan;
|
||||
});
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class PenggunaanPakan extends Model
|
||||
{
|
||||
protected $table = 'penggunaan_pakan';
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = [
|
||||
'pakan_id',
|
||||
'tanggal_pakai',
|
||||
'jumlah_pakai',
|
||||
'user_id',
|
||||
];
|
||||
|
||||
// Relasi dengan Pakan
|
||||
public function pakan()
|
||||
{
|
||||
return $this->belongsTo(Pakan::class, 'pakan_id');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
|
||||
class PopulasiAyam extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'populasi_ayam';
|
||||
|
||||
protected $fillable = [
|
||||
'kandang_id',
|
||||
'kode_batch',
|
||||
'nama_batch',
|
||||
'tanggal_doc',
|
||||
'jumlah_ayam_masuk',
|
||||
'status_ayam',
|
||||
'user_id',
|
||||
];
|
||||
|
||||
public function harianAyam()
|
||||
{
|
||||
return $this->hasMany(HarianAyam::class, 'id_populasi');
|
||||
}
|
||||
|
||||
public function kandang()
|
||||
{
|
||||
return $this->belongsTo(KandangAyam::class, 'kandang_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::updated(function ($populasi) {
|
||||
// Perbarui field nama_batch di semua record harian ayam yang terkait
|
||||
$populasi->harianAyam()->update(['nama_batch' => $populasi->nama_batch]);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class SubArticle extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'article_id',
|
||||
'title',
|
||||
'image',
|
||||
'content',
|
||||
'order_number',
|
||||
'user_id',
|
||||
];
|
||||
public function article(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Article::class, 'article_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Tag extends Model
|
||||
{
|
||||
protected $fillable = ['name'];
|
||||
public function articles()
|
||||
{
|
||||
return $this->belongsToMany(Article::class, 'article_tags');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Topic extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
protected $table = 'topics';
|
||||
protected $fillable = ['user_id', 'title', 'content', 'is_pinned'];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function comments()
|
||||
{
|
||||
return $this->hasMany(Comment::class);
|
||||
}
|
||||
|
||||
public function likes()
|
||||
{
|
||||
return $this->morphMany(Like::class, 'likeable');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens, HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
'role',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
|
||||
public function topics()
|
||||
{
|
||||
return $this->hasMany(Topic::class);
|
||||
}
|
||||
|
||||
public function comments()
|
||||
{
|
||||
return $this->hasMany(Comment::class);
|
||||
}
|
||||
|
||||
public function likes()
|
||||
{
|
||||
return $this->hasMany(Like::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Article;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class ArticlePolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, Article $article): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Article $article): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Article $article): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, Article $article): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, Article $article): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\ArticleTag;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class ArticleTagPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, ArticleTag $articleTag): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, ArticleTag $articleTag): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, ArticleTag $articleTag): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, ArticleTag $articleTag): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, ArticleTag $articleTag): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\CardArticle;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class CardArticlePolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, CardArticle $cardArticle): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, CardArticle $cardArticle): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, CardArticle $cardArticle): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, CardArticle $cardArticle): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, CardArticle $cardArticle): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\HarianAyam;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class HarianAyamPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, HarianAyam $harianAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, HarianAyam $harianAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, HarianAyam $harianAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, HarianAyam $harianAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, HarianAyam $harianAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\KandangAyam;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class KandangAyamPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, KandangAyam $kandangAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, KandangAyam $kandangAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, KandangAyam $kandangAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, KandangAyam $kandangAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, KandangAyam $kandangAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Pakan;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class PakanPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, Pakan $pakan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Pakan $pakan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Pakan $pakan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, Pakan $pakan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, Pakan $pakan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Pendapatan;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class PendapatanPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, Pendapatan $pendapatan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Pendapatan $pendapatan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Pendapatan $pendapatan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, Pendapatan $pendapatan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, Pendapatan $pendapatan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Pengeluaran;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class PengeluaranPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, Pengeluaran $pengeluaran): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Pengeluaran $pengeluaran): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Pengeluaran $pengeluaran): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, Pengeluaran $pengeluaran): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, Pengeluaran $pengeluaran): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\PenggunaanPakan;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class PenggunaanPakanPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, PenggunaanPakan $penggunaanPakan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, PenggunaanPakan $penggunaanPakan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, PenggunaanPakan $penggunaanPakan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, PenggunaanPakan $penggunaanPakan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, PenggunaanPakan $penggunaanPakan): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\PopulasiAyam;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class PopulasiAyamPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, PopulasiAyam $populasiAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, PopulasiAyam $populasiAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, PopulasiAyam $populasiAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, PopulasiAyam $populasiAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, PopulasiAyam $populasiAyam): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\SubArticle;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class SubArticlePolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, SubArticle $subArticle): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, SubArticle $subArticle): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, SubArticle $subArticle): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, SubArticle $subArticle): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, SubArticle $subArticle): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Tag;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class TagPolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*/
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*/
|
||||
public function view(User $user, Tag $tag): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*/
|
||||
public function update(User $user, Tag $tag): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*/
|
||||
public function delete(User $user, Tag $tag): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*/
|
||||
public function restore(User $user, Tag $tag): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*/
|
||||
public function forceDelete(User $user, Tag $tag): bool
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
// use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The model to policy mappings for the application.
|
||||
*
|
||||
* @var array<class-string, class-string>
|
||||
*/
|
||||
protected $policies = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any authentication / authorization services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Broadcast;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class BroadcastServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
Broadcast::routes();
|
||||
|
||||
require base_path('routes/channels.php');
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue