anggarisky / belibang

0 stars 0 forks source link

/Code review #1

Open budistwn15 opened 6 months ago

budistwn15 commented 6 months ago

File: FrontController References: https://github.com/anggarisky/belibang/blob/main/app/Http/Controllers/FrontController.php

  1. Method index
    public function index(){
    return Inertia::render('HomeRun');
    }

    catatan:

rekomendasi:

use Inertia\Response;
public function index(): Response
{
  return Inertia::render('HomeRun');
}
  1. Method benefits
    public function benefits(){
        return Inertia::render('Benefits');
    }

    catatan:

rekomendasi:

use Inertia\Response;
    public function benefits(): Response
{
        return Inertia::render('Benefits');
    }
  1. Method discover

    public function discover(){
        $products = Product::orderBy('id', 'DESC')->get();
    
        return Inertia::render('DiscoverProducts', [
            'products' => $products
        ]);
    }

    catatan:

rekomendasi:

use Inertia\Response;
    public function discover(): Response
    {
        $products = Product::query()->select('id','name','slug','path_cover','category')->orderByDesc('id')->get();

        return Inertia::render('DiscoverProducts', [
            'products' => $products
        ]);
    }
  1. method details
    public function details(Product $product){
        return Inertia::render('DetailsProduct', [
            'product' => $product
        ]);
    }

    catatan:

rekomendasi:

use Inertia\Response;

    public function details(Product $product): Response
{

        return Inertia::render('DetailsProduct', [
            'product' => $product
        ]);
    }
  1. method checkout

    public function checkout(Product $product){
    
        $user_id = Auth::user()->id;
    
        if($product->user_id === $user_id){
    
            session()->flash('error', 'Stop downloading your own product');
            return redirect()->back();
    
        }
    
        $order = Order::firstOrCreate(
            [
                'buyer_id' => $user_id,
                'product_id' => $product->id
            ],
            [
                'creator_id' => $product->user->id,
                'total_price' => $product->price,
                'is_paid' => 0,
            ]
        );
    
        $order->save();
    
        $transaction = Transaction::firstOrCreate(
            [
                'user_id' => $user_id,
                'product_id' => $product->id
            ],
            [
                'total_price' => $product->price,
                'is_paid' => 0,
            ]
        );
    
        $transaction->save();
    
        return Inertia::render('CheckoutProduct', [
            'product' => $product
        ]);
    
    }

catatan:

rekomendasi:

use Inertia\Response;
use Illuminate\Http\RedirectResponse;

    public function checkout(Product $product): Response|RedirectResponse
{

        $user_id = Auth::user()->id;

        if($product->user_id === $user_id){

            session()->flash('error', 'Stop downloading your own product');
            return redirect()->back();

        }

        $order = Order::firstOrCreate(
            [
                'buyer_id' => $user_id,
                'product_id' => $product->id
            ],
            [
                'creator_id' => $product->user->id,
                'total_price' => $product->price,
                'is_paid' => 0,
            ]
        );

        $order->save();

        $transaction = Transaction::firstOrCreate(
            [
                'user_id' => $user_id,
                'product_id' => $product->id
            ],
            [
                'total_price' => $product->price,
                'is_paid' => 0,
            ]
        );

        $transaction->save();

        return Inertia::render('CheckoutProduct', [
            'product' => $product
        ]);

    }
  1. method download

    public function download(Product $product){
        $user_id = Auth::user()->id;
    
        $paidTransactionExists = Transaction::where('user_id', $user_id)
            ->where('product_id', $product->id)
            ->where('is_paid', 1)
            ->exists();
    
        if (!$paidTransactionExists) {
            session()->flash('error', 'You must purchase the product before download');
            return redirect()->back();
        }
    
        $filePath = $product->path_file;
    
        // Check if file exists
        if (!Storage::disk('public')->exists($filePath)) {
            abort(404); // or handle the error as you prefer
        }
    
        // Return the file as a download
        return Storage::disk('public')->download($filePath);
    
    }

catatan:

rekomendasi:

// model
    public function scopePaid(Builder $query): Builder
    {
        return $query->where('is_paid', 1);
    }

    public function scopeUnpaid(Builder $query): Builder
    {
        return $query->where('is_paid', 0);
    }

// atau bisa menggunakan params
    public function scopeIsPaid(Builder $query, int $params): Builder
    {
        return $query->where('is_paid', $params);
    }

// controller
use Inertia\Response;
use Illuminate\Http\RedirectResponse;
use Symfony\Component\HttpFoundation\StreamedResponse;

    public function download(Product $product): StreamedResponse|RedirectResponse
{
        $user_id = Auth::user()->id;

        $paidTransactionExists = Transaction::where('user_id', $user_id)
            ->where('product_id', $product->id)
            ->paid()
            ->exists();

        if (!$paidTransactionExists) {
            session()->flash('error', 'You must purchase the product before download');
            return redirect()->back();
        }

        $filePath = $product->path_file;

        // Check if file exists
        if (!Storage::disk('public')->exists($filePath)) {
            abort(404); // or handle the error as you prefer
        }

        // Return the file as a download
        return Storage::disk('public')->download($filePath);
    }
budistwn15 commented 6 months ago

File: OrderController reference: https://github.com/anggarisky/belibang/blob/main/app/Http/Controllers/OrderController.php

  1. method index

    public function index()
    {
    
        $my_orders = Order::with('product', 'buyer')->where('creator_id', Auth::id())->orderBy('id', 'DESC')->get();
    
        return Inertia::render('MyOrders', [
            'my_orders' => $my_orders
        ]);
    }

catatan:

rekomendasi:

use Inertia\Response;
    public function index(): Response
    {
        $my_orders = Order::with('product', 'buyer')->where('creator_id', Auth::id())->orderByDesc('id')->get();

        return Inertia::render('MyOrders', [
            'my_orders' => $my_orders
        ]);
    }
  1. method approve

    public function approve(Order $order){
        // Update the order status to "paid"
        $order->update(['is_paid' => 1]);
    
        Transaction::where('user_id', $order->buyer_id)->where('product_id', $order->product_id)->update([
            'is_paid' => 1
        ]);
    
        // Redirect the user back or to another page with a success message
        return redirect()->back()->with('message', 'Order approved successfully.');
    }

catatan:

rekomendasi:

use Illuminate\Http\RedirectResponse;

    public function approve(Order $order): RedirectResponse
{
        // Update the order status to "paid"
        $order->update(['is_paid' => 1]);

        Transaction::where('user_id', $order->buyer_id)->where('product_id', $order->product_id)->update([
            'is_paid' => 1
        ]);

        // Redirect the user back or to another page with a success message
        return redirect()->back()->with('message', 'Order approved successfully.');
    }

Method yang lain nya jika tidak digunakan lebih baik di hapus saja dari controller, dan mungkin karena pada route dibuat resource untuk OrderController jadi pada route bisa disesuaikan hanya method2 yang digunakan saja

budistwn15 commented 6 months ago

File: Product Controller References: https://github.com/anggarisky/belibang/blob/main/app/Http/Controllers/ProductController.php

  1. method index

    public function index()
    {
        //
        $my_products = Product::whereUserId(Auth::id())->orderBy('id', 'DESC')->get();
    
        return Inertia::render('MyProducts', [
            'my_products' => $my_products
        ]);
    }

catatan:

rekomendasi:

use Inertia\Response;

    public function index(): Response
    {
        //
        $my_products = Product::whereUserId(Auth::id())->orderByDesc('id')->get();

        return Inertia::render('MyProducts', [
            'my_products' => $my_products
        ]);
    }
  1. method create
    public function create()
    {
        //
        return Inertia::render('CreateProduct');
    }

catatan:

rekomendasi:

use Inertia\Response;

    public function create(): Response
    {
        //
        return Inertia::render('CreateProduct');
    }
  1. method store

    public function store(Request $request)
    {
        //
        $request->validate([
            'name' => 'required|string|max:255',
            'slug' => 'sometimes|string|unique:products,slug', // Ensure the slug is unique in the 'products' table
            'category' => 'required|string|in:Ebook,Course,Template',
            'price' => 'required|numeric',
            'path_cover' => 'required|file|mimes:png',
            'path_file' => 'required|file|mimes:zip',
            // other validation rules...
        ]);
    
        $slug = Str::slug($request->name);
        $user_id = Auth::user()->id;
    
        $product = new Product([
            'name' => $request->name,
            'category' => $request->category,
            'price' => $request->price,
            'slug' => $slug,
            'user_id' => $user_id
        ]);
    
        if($request->hasFile('path_cover')){
            $pathCover = $request->file('path_cover')->store('cover_products', 'public');
            $product->path_cover = $pathCover;
        }
    
        if($request->hasFile('path_file')){
            $pathFile = $request->file('path_file')->store('file_products', 'public');
            $product->path_file = $pathFile;
        }
    
        $product->save();
    
        session()->flash('message', 'Product saved successfully!');
        return Inertia::location(route('products.index'));
    }

    catatan:

    • pisahkan validate request ke dalam request terpisah

rekomendasi


// ProductRequest
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ProductRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'name' => 'required|string|max:255',
            'slug' => 'sometimes|string|unique:products,slug', // Ensure the slug is unique in the 'products' table
            'category' => 'required|string|in:Ebook,Course,Template',
            'price' => 'required|numeric',
            'path_cover' => 'required|file|mimes:png',
            'path_file' => 'required|file|mimes:zip',
        ];
    }

    public function attributes(): array
    {
        return [
            'name' => 'Name',
            'slug' => 'Slug',
            'category' => 'Category',
            'price' => 'Price',
            'path_cover' => 'Path Cover',
            'path_file' => 'Path File'
        ];
    }

    public function authorize(): bool
    {
        return true;
    }
}

use Illuminate\Http\RedirectResponse;
use App\Http\Requests\ProductRequest;

public function store(ProductRequest $request): RedirectResponse
    {
        $product = new Product([
            'name' => $name = $request->name,
            'category' => $request->category,
            'price' => $request->price,
            'slug' => str()->slug($name),
            'user_id' => auth()->user()->id
        ]);

        if($request->hasFile('path_cover')){
            $pathCover = $request->file('path_cover')->store('cover_products', 'public');
            $product->path_cover = $pathCover;
        }

        if($request->hasFile('path_file')){
            $pathFile = $request->file('path_file')->store('file_products', 'public');
            $product->path_file = $pathFile;
        }

        $product->save();

        session()->flash('message', 'Product saved successfully!');
        return Inertia::location(route('products.index'));
    }
budistwn15 commented 6 months ago

File: TransactionController References: https://github.com/anggarisky/belibang/blob/main/app/Http/Controllers/TransactionController.php

  1. method index

    public function index()
    {
        //
        $my_transactions = Transaction::with('product.user')->where('user_id', Auth::id())->orderBy('id', 'DESC')->get();
    
        return Inertia::render('MyTransactions', [
            'my_transactions' => $my_transactions
        ]);
    }

catatan:

rekomendasi:

use Inertia\Response;

    public function index(): Response
    {
        //
        $my_transactions = Transaction::with('product.user')->where('user_id', Auth::id())->orderByDesc('id')->get();

        return Inertia::render('MyTransactions', [
            'my_transactions' => $my_transactions
        ]);
    }
budistwn15 commented 6 months ago

File: Order (Model) references: https://github.com/anggarisky/belibang/blob/main/app/Models/Order.php

class Order extends Model
{
    use HasFactory, SoftDeletes;

    protected $guarded = [
        'id'
    ];

    public function product(): BelongsTo {
        return $this->belongsTo(Product::class);
    }

    public function buyer(){
        return $this->belongsTo(User::class, 'buyer_id');
    }
}

pada method yang ada pada model ini lebih baik di berikan return type yang sesuai dengan method yang dibuat

rekomendasi:

class Order extends Model
{
    use HasFactory, SoftDeletes;

    protected $guarded = [
        'id'
    ];

    public function product(): BelongsTo {
        return $this->belongsTo(Product::class);
    }

    public function buyer(): BelongsTo
{
        return $this->belongsTo(User::class, 'buyer_id');
    }
}
budistwn15 commented 6 months ago

File: Product (Model) references: https://github.com/anggarisky/belibang/blob/main/app/Models/Product.php

class Product extends Model
{
    use HasFactory, SoftDeletes;

    protected $guarded = [
        'id'
    ];

    public function user(){
        return $this->belongsTo(User::class);
    }
}

pada method yang ada pada model ini lebih baik di berikan return type yang sesuai dengan method yang dibuat

rekomendasi:

use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Product extends Model
{
    use HasFactory, SoftDeletes;

    protected $guarded = [
        'id'
    ];

    public function user(): BelongsTo
{
        return $this->belongsTo(User::class);
    }
}
budistwn15 commented 6 months ago

File: Transaction (Model) references: https://github.com/anggarisky/belibang/blob/main/app/Models/Transaction.php

budistwn15 commented 6 months ago

File: Order (Migrations) references: https://github.com/anggarisky/belibang/blob/main/database/migrations/2024_02_22_012021_create_orders_table.php

        Schema::create('orders', function (Blueprint $table) {
            $table->id();
            $table->integer('total_price');
            $table->foreignId('product_id')->constrained()->onDelete('cascade');
            $table->unsignedBigInteger('buyer_id');
            $table->boolean('is_paid');
            $table->softDeletes();
            $table->timestamps();

            $table->foreign('buyer_id')->references('id')->on('users')->onDelete('cascade');
        });

catatan:

rekomendasi:

        Schema::create('orders', function (Blueprint $table) {
            $table->id();
            $table->integer('total_price');
            $table->foreignId('product_id')->constrained()->cascadeOnDelete(');
            $table->foreignId('buyer_id')->constrained('users')->cascadeOnDelete();
            $table->boolean('is_paid');
            $table->softDeletes();
            $table->timestamps();
        });

File: Order (Migrations) references: https://github.com/anggarisky/belibang/blob/main/database/migrations/2024_02_22_014549_add_creator_id_to_orders_table.php

    public function up(): void
    {
        Schema::table('orders', function (Blueprint $table) {
            //
            $table->unsignedBigInteger('creator_id');

            $table->foreign('creator_id')->references('id')->on('users')->onDelete('cascade');
        });
    }

catatan:

rekomendasi:

    public function up(): void
    {
        Schema::table('orders', function (Blueprint $table) {
            $table->foreignId('creator_id')->constrained('users')->cascadeOnDelete();
        });
    }
budistwn15 commented 6 months ago

files: routes (web) references: https://github.com/anggarisky/belibang/blob/main/routes/web.php

budistwn15 commented 6 months ago

Views

  1. meta pada beberapa file jsx terdapat penggunaan kode meta lebih baik di buat ke dalam sebuah komponen, karena jika dilihat isinya sama yang membedakan value nya

export default function MetaTags({ image = 'https://buildwithangga.com/themes/front/images/meta/kelas-online-belajar-ui-ux-design-dan-web-development-build-with-angga.png', title = 'BuildWithAngga', description = 'BuildWithAngga menyediakan kelas online bersertifikat dan komunitas untuk belajar skills UI UX design dan coding yang dibimbing oleh mentor expert. Jadilah ahli bersama kami!', url = 'https://buildwithangga.com', }) { return (

);

}


- contoh penggunaan misalnya pada file `Benefits.jsx`
```javascript

import Navigation from '@/Components/Navigation';
import { Head } from '@inertiajs/react';
import MetaTags from '@/Components/MetaTags';

export default function Benefits({}) {
    return (
        <div>

            <Head title="Benefits" />
            <MetaTags
                title="Discover Products"
                description="Explore our wide range of products."
                url="http://example.com/page"
            />

            <Navigation/>
        </div>
    );
}