feat: adds ability for approved users to approve artwork
This commit is contained in:
parent
bc66edb3ce
commit
eb931bbb6a
@ -8,11 +8,10 @@ services:
|
||||
dockerfile: Dockerfile
|
||||
container_name: ${CONTAINER_NAME:-pcag-laravel}
|
||||
volumes:
|
||||
- /var/www/html/vendor/
|
||||
- ${PATH_TO_SITE}:/var/www/html:cached
|
||||
- ${PATH_TO_STATIC}:/static:cached
|
||||
- ./nginx/default.conf:/etc/nginx/sites-available/default:cached
|
||||
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:cached
|
||||
- ${PATH_TO_SITE}:/var/www/html
|
||||
- ${PATH_TO_STATIC}:/static
|
||||
- ./nginx/default.conf:/etc/nginx/sites-available/default
|
||||
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||
environment:
|
||||
TZ: UTC
|
||||
PUID: ${UID:-1000}
|
||||
@ -27,19 +26,7 @@ services:
|
||||
LARAVEL_SCHEDULE_ENABLED: true
|
||||
PHP_OPEN_BASEDIR: "/var/www/html:/static"
|
||||
ports:
|
||||
- "8776:80"
|
||||
restart: always
|
||||
networks:
|
||||
- proxy
|
||||
- default
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=proxy"
|
||||
# Entry Point for https
|
||||
- "traefik.http.routers.podcastartgen-secure.entrypoints=websecure"
|
||||
- "traefik.http.routers.podcastartgen-secure.rule=Host(`www.noagendaartgenerator.com`) || HOST(`noagendaartgenerator.com`)"
|
||||
- "traefik.http.routers.podcastartgen-secure.service=podcastartgen-service"
|
||||
- "traefik.http.services.podcastartgen-service.loadbalancer.server.port=80"
|
||||
- "80:80"
|
||||
links:
|
||||
- db
|
||||
- redis
|
||||
@ -47,25 +34,13 @@ services:
|
||||
static:
|
||||
image: nginx:alpine
|
||||
volumes:
|
||||
- ${PATH_TO_STATIC}:/usr/share/nginx/html:cached
|
||||
- ./static:/usr/share/nginx/html
|
||||
environment:
|
||||
TZ: UTC
|
||||
PUID: ${UID:-1000}
|
||||
PGID: ${GID:-1000}
|
||||
ports:
|
||||
- "8777:80"
|
||||
networks:
|
||||
- proxy
|
||||
- default
|
||||
restart: always
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=proxy"
|
||||
# Entry Point for https
|
||||
- "traefik.http.routers.podcastartstatic-secure.entrypoints=websecure"
|
||||
- "traefik.http.routers.podcastartstatic-secure.rule=Host(`static.noagendaartgenerator.com`)"
|
||||
- "traefik.http.routers.podcastartstatic-secure.service=podcastartstatic-service"
|
||||
- "traefik.http.services.podcastartstatic-service.loadbalancer.server.port=80"
|
||||
- "8181:80"
|
||||
db:
|
||||
image: mariadb:latest
|
||||
env_file: .env
|
||||
@ -76,46 +51,17 @@ services:
|
||||
MARIADB_DATABASE: ${LIVE_DB_DATABASE}
|
||||
MARIADB_PASSWORD: ${LIVE_DB_PASSWORD}
|
||||
volumes:
|
||||
- "./db/data:/var/lib/mysql:cached"
|
||||
- "./db/dump:/docker-entrypoint-initdb.d:cached"
|
||||
networks:
|
||||
- proxy
|
||||
- default
|
||||
- "./db/data:/var/lib/mysql"
|
||||
- "./db/dump:/docker-entrypoint-initdb.d"
|
||||
ports:
|
||||
- "51533:3306" # Adjust the external port if needed
|
||||
restart: always
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=proxy"
|
||||
- "traefik.http.routers.podcastartdb-secure.entrypoints=websecure"
|
||||
- "traefik.http.routers.podcastartdb-secure.rule=Host(`podcastartdb.noagenda.dev`)"
|
||||
- "traefik.http.routers.podcastartdb-secure.service=podcastartdb-service"
|
||||
- "traefik.http.services.podcastartdb-service.loadbalancer.server.port=3306"
|
||||
- "3306:3306"
|
||||
redis:
|
||||
image: redis:alpine
|
||||
command: redis-server --appendonly yes --requirepass ${REDIS_SEC_PASSWORD}
|
||||
image: redis:latest
|
||||
ports:
|
||||
- "56379:6379"
|
||||
volumes:
|
||||
- ./redis/redis.conf:/usr/local/etc/redis/redis.conf:cached
|
||||
- ./redis/redis-data:/var/lib/redis:cached
|
||||
environment:
|
||||
- REDIS_REPLICATION_MODE=master
|
||||
restart: always
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=proxy"
|
||||
- "traefik.http.routers.paredis-secure.entrypoints=websecure"
|
||||
- "traefik.http.routers.paredis-secure.rule=Host(`paredis.noagenda.dev`)"
|
||||
- "traefik.http.routers.paredis-secure.service=paredis-service"
|
||||
- "traefik.http.services.paredis-service.loadbalancer.server.port=6379"
|
||||
- "6379:6379"
|
||||
npm:
|
||||
image: node:latest
|
||||
working_dir: /var/www/html
|
||||
entrypoint: ["npm"]
|
||||
volumes:
|
||||
- ./site:/var/www/html
|
||||
networks:
|
||||
proxy:
|
||||
external: true
|
||||
|
||||
- ./site:/var/www/html
|
@ -37,9 +37,7 @@ public function index()
|
||||
->orderBy('episode_number', 'desc')
|
||||
->orderBy('artworks.created_at', 'desc')
|
||||
->paginate($perPage = 52, $columns = ['*'], $pageName = 'artworks');
|
||||
$podcasts = Cache::remember('publishedPodcasts', 30, function() {
|
||||
return Podcast::where('published', true)->get();
|
||||
});
|
||||
$podcasts = $this->publishedPodcasts();
|
||||
return view('explore.artworks', [
|
||||
'user' => $user,
|
||||
'pageTitle' => 'Explore',
|
||||
@ -56,9 +54,7 @@ public function index()
|
||||
public function create()
|
||||
{
|
||||
$user = auth()->user();
|
||||
$podcasts = Cache::remember('publishedPodcasts', 30, function() {
|
||||
return Podcast::where('published', true)->get();
|
||||
});
|
||||
$podcasts = $this->publishedPodcasts();
|
||||
return view('artworks.submit', [
|
||||
'user' => $user,
|
||||
'pageTitle' => 'Submit New Artwork',
|
||||
@ -66,6 +62,41 @@ public function create()
|
||||
]);
|
||||
}
|
||||
|
||||
public function pendingApproval(Request $request)
|
||||
{
|
||||
$user = auth()->user();
|
||||
if ($request->user()->cannot('approve', Artwork::class)) {
|
||||
abort(403);
|
||||
}
|
||||
$artworks = Artwork::whereNull('approved_by')
|
||||
->orderBy('created_at', 'desc')
|
||||
->paginate(50);
|
||||
$podcasts = $this->publishedPodcasts();
|
||||
return view('artworks.approvals', [
|
||||
'user' => $user,
|
||||
'pageTitle' => 'Approve Artworks',
|
||||
'podcasts' => $podcasts,
|
||||
'artworks' => $artworks,
|
||||
]);
|
||||
}
|
||||
|
||||
public function approve(Request $request)
|
||||
{
|
||||
$user = $request->user();
|
||||
if ($request->user()->cannot('approve', Artwork::class)) {
|
||||
abort(403);
|
||||
}
|
||||
$validated = $request->validate([
|
||||
'artwork_id' => 'required|exists:artworks,id'
|
||||
]);
|
||||
$artwork = Artwork::find($request->artwork_id);
|
||||
if (is_null($artwork->approved_by)) {
|
||||
$artwork->approved_by = $user->artists->first()->id;
|
||||
$artwork->save();
|
||||
}
|
||||
return redirect('/approve-artworks');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
@ -108,7 +139,7 @@ public function store(Request $request): RedirectResponse
|
||||
'description' => $request->description,
|
||||
'overlay_id' => null,
|
||||
'podcast_id' => $podcast->id,
|
||||
'episode_id' => $episode->id,
|
||||
'episode_id' => $episode->id,
|
||||
//'approved_by' => 4,
|
||||
'filename' => $filename,
|
||||
'created_at' => now(),
|
||||
@ -190,16 +221,6 @@ public function destroy(Artwork $artwork)
|
||||
//
|
||||
}
|
||||
|
||||
public function approve(Artwork $artwork)
|
||||
{
|
||||
$user = auth()->user();
|
||||
$awatingApproval = Artwork::whereNull('approved_by')
|
||||
->with('podcast')
|
||||
->with('podcast.episode')
|
||||
->orderBy('created_at', 'asc')
|
||||
->get();
|
||||
}
|
||||
|
||||
public function legacyArtLink(Request $request, $any = null)
|
||||
{
|
||||
phpinfo();
|
||||
@ -228,4 +249,11 @@ public function downloadArchiveList(Request $request, $type = 'sd')
|
||||
->header('Content-Disposition', 'attachment; filename="naartgen-archivelist-' . $type . '.txt"');
|
||||
}
|
||||
|
||||
private function publishedPodcasts() {
|
||||
$podcasts = Cache::remember('publishedPodcasts', 30, function() {
|
||||
return Podcast::where('published', true)->get();
|
||||
});
|
||||
return $podcasts;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ public function show(Request $request, $podcast_slug, $slug)
|
||||
->with('artworks')
|
||||
->with('artwork')
|
||||
->with('podcast')
|
||||
->whereNotNull('artworks.approved_by')
|
||||
->firstOrFail();
|
||||
$podcasts = Podcast::where('published', true)->with('episodes', function ($query) {
|
||||
$query->orderBy('episode_number', 'desc');
|
||||
|
@ -65,9 +65,9 @@ public function artworks()
|
||||
return $this->hasManyThrough(Artwork::class, Artist::class);
|
||||
}
|
||||
|
||||
public function episodes()
|
||||
public function selectedForEpisodes()
|
||||
{
|
||||
return $this->hasManyThrough(Episode::class, Artwork::class);
|
||||
return $this->artists()->first()->episodes;
|
||||
}
|
||||
|
||||
public function wallets()
|
||||
|
34
site/app/Policies/ArtworkPolicy.php
Normal file
34
site/app/Policies/ArtworkPolicy.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Artwork;
|
||||
|
||||
class ArtworkPolicy
|
||||
{
|
||||
/**
|
||||
* Create a new policy instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function viewAny(?User $user): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function approve(User $user): bool
|
||||
{
|
||||
if ($user->id == 4) {
|
||||
return true;
|
||||
}
|
||||
$selectedCount = $user->selectedForEpisodes()->count();
|
||||
if ($selectedCount > 5) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -4,6 +4,8 @@
|
||||
|
||||
// use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use App\Policies\ArtworkPolicy;
|
||||
use App\Models\Artwork;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
@ -13,7 +15,7 @@ class AuthServiceProvider extends ServiceProvider
|
||||
* @var array<class-string, class-string>
|
||||
*/
|
||||
protected $policies = [
|
||||
//
|
||||
Artwork::class => ArtworkPolicy::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
93
site/resources/views/artworks/approvals.blade.php
Normal file
93
site/resources/views/artworks/approvals.blade.php
Normal file
@ -0,0 +1,93 @@
|
||||
@extends('layouts.master')
|
||||
|
||||
@section('page-title', 'Approve Artwork')
|
||||
|
||||
@section('meta_description', 'Approve Artwork to have it published for non-priviledged eyeballs to view.')
|
||||
|
||||
@section('page-top')
|
||||
<section class="inner-page-banner bg-2 bg-image">
|
||||
<div class="container">
|
||||
<div class="inner text-center">
|
||||
<h1 class="title">Artwork Pending Approval</h1>
|
||||
<nav class="mt-4">
|
||||
<ol class="breadcrumb justify-content-center">
|
||||
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
||||
<li class="breadcrumb-item active"><a href="/artworks">Explore Artwork</a></li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
@section('page-content')
|
||||
<section class="pt-120 pb-90 masonary-wrapper-activation">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
{{ $artworks->links() }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="d-flex-between flex-wrap">
|
||||
<div
|
||||
class="button-group default-tab-list isotop-filter flex-wrap filters-button-group d-flex justify-content-start justify-content-lg-start mb-6 ">
|
||||
<button data-filter="*" class="is-checked"><span class="filter-text">View All</span></button>
|
||||
@foreach ($podcasts as $podcast)
|
||||
<button data-filter=".podcast--{{ $podcast->slug }}"><span class="filter-text">{{ $podcast->name }}</span></button>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-filter-wrapper masonry-list">
|
||||
<div class="resizer"></div>
|
||||
@foreach ($artworks as $artwork)
|
||||
@php
|
||||
$thisArtwork = $artwork;
|
||||
$thisPodcast = $artwork->podcast;
|
||||
$thisEpisode = $artwork->episode;
|
||||
@endphp
|
||||
<div class="grid-item podcast--{{ $artwork->podcast->slug }}">
|
||||
<div class="explore-style-one">
|
||||
<div class="thumb">
|
||||
<img src="{{ config('app.static_asset_url') . '/thumbnails/' . $thisArtwork->filename ?? '#'}}"
|
||||
alt="{{ $thisArtwork->title }} by {{ $thisArtwork->artist->name }}">
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="header d-flex-between pt-4 pb-1">
|
||||
<h3 class="title">“{{ $thisArtwork->title }}”</h3>
|
||||
</div>
|
||||
{{-- End .header --}}
|
||||
<div class="product-owner py-1 d-flex-between">
|
||||
<span class="bid-owner">Artwork By <br><strong><a
|
||||
href="/artist/{{ $thisArtwork->artist->slug }}">{{ $thisArtwork->artist->name ?? 'Unknown' }}</a></strong></span>
|
||||
<span class="profile-share d-flex-center"><a href="/artist/{{ $thisArtwork->artist->slug }}"
|
||||
class="avatar" data-bs-toggle="tooltip"
|
||||
data-bs-placement="top"
|
||||
title="{{ $thisArtwork->artist->name }}">
|
||||
<img class="avatar_img" src="{{ $thisArtwork->artist->avatar() }}"
|
||||
alt="{{ $thisArtwork->artist->name }}"></a>
|
||||
</span>
|
||||
</div>
|
||||
{{-- End .product-owner --}}
|
||||
<div class="action-wrapper py-5 d-flex align-items-center justify-content-center">
|
||||
<form action="/approve-artworks" method="POST" class="approve-artwork-form" name="approve-artwork-{{ $thisArtwork->id}}" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<input name="artwork_id" type="hidden" value="{{ $thisArtwork->id }}">
|
||||
<button type="submit" class="btn btn-gradient btn-medium justify-content-center"><span>Approve and Publish</span></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
{{ $artworks->links() }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
|
||||
|
||||
|
@ -11,6 +11,11 @@
|
||||
<li>
|
||||
<a {!! request()->is(['create-artwork', 'create-artwork/*']) ? 'class="active"' : '' !!} href="/create-artwork">Create</a>
|
||||
</li>
|
||||
@can('approve', App\Models\Artwork::class)
|
||||
<li>
|
||||
<a {!! request()->is(['approve-artworks']) ? 'class="active"' : '' !!} href="/approve-artworks">Approve</a>
|
||||
</li>
|
||||
@endcan
|
||||
@endif
|
||||
<li>
|
||||
<a rel="me" {!! request()->is(['support*']) ? 'class="active"' : '' !!} href="/support-development">History & Support</a>
|
||||
|
@ -43,6 +43,8 @@
|
||||
Route::post('/create-artwork', [ArtworkController::class, 'store']);
|
||||
Route::get('/update-avatar', [ArtistController::class, 'avatar'])->name('avatar.edit');
|
||||
Route::post('/update-profile', [ArtistController::class, 'update'])->name('profile-details.edit');
|
||||
Route::get('/approve-artworks', [ArtworkController::class, 'pendingApproval'])->name('show-approve-artwork');
|
||||
Route::post('/approve-artworks', [ArtworkController::class, 'approve'])->name('approve-artwork');
|
||||
});
|
||||
|
||||
Route::get('/counter', Counter::class);
|
||||
|
Loading…
Reference in New Issue
Block a user