Podcast management (WIP)

This commit is contained in:
dece 2023-10-14 18:26:09 +02:00
parent 4566f8b85b
commit c39e7039ac
12 changed files with 73 additions and 57 deletions

View file

@ -15,14 +15,14 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\String\Slugger\SluggerInterface; use Symfony\Component\String\Slugger\SluggerInterface;
#[Route('/manage/podcast')] #[Route('/manage/podcasts')]
class PodcastController extends AbstractController class PodcastController extends AbstractController
{ {
#[Route('/', name: 'app_podcast_index', methods: ['GET'])] #[Route('/', name: 'app_podcast_index', methods: ['GET'])]
public function index(PodcastRepository $podcastRepository): Response public function index(PodcastRepository $podcastRepository): Response
{ {
return $this->render('podcast/index.html.twig', [ return $this->render('podcast/index.html.twig', [
'podcasts' => $podcastRepository->findAllOrderedById(), 'podcasts' => $podcastRepository->findOwnedBy($this->getUser())
]); ]);
} }

View file

@ -47,7 +47,7 @@ class PodcastType extends AbstractType
]), ]),
]) ])
->add('owner', EntityType::class, [ ->add('owner', EntityType::class, [
'help' => 'The podcast owner is the only user of this instance able to see and modify it.', 'help' => 'The podcast owner is the only user of this instance able to modify it.',
'class' => User::class, 'class' => User::class,
'disabled' => true, 'disabled' => true,
]) ])

View file

@ -3,6 +3,7 @@
namespace App\Repository; namespace App\Repository;
use App\Entity\Podcast; use App\Entity\Podcast;
use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ManagerRegistry;
@ -39,8 +40,8 @@ class PodcastRepository extends ServiceEntityRepository
} }
} }
public function findAllOrderedById(): array public function findOwnedBy(User $user): array
{ {
return $this->findBy([], ['id' => 'ASC']); return $this->findBy(['owner' => $user], ['id' => 'ASC']);
} }
} }

View file

@ -4,11 +4,13 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}LSBC{% endblock %}</title> <title>{% block title %}LSBC{% endblock %}</title>
<style> {% block stylesheets %}
img { max-width: 100%; } <style>
.help-text { font-size: 0.8em; } img { max-width: 100%; }
</style> .help-text { font-size: 0.8em; }
<link rel="stylesheet" href="/simple-v1.min.css"> </style>
<link rel="stylesheet" href="/simple-v1.min.css">
{% endblock %}
</head> </head>
<body> <body>
{% block body %}{% endblock %} {% block body %}{% endblock %}

View file

@ -8,4 +8,5 @@
{% endfor %} {% endfor %}
</ul> </ul>
<p>The <a href="https://git.dece.space/dece/lsbc">LSBC</a> project is licensed as GPLv3.</p> <p>The <a href="https://git.dece.space/dece/lsbc">LSBC</a> project is licensed as GPLv3.</p>
<a href="/login"><button>Login</button></a>
{% endblock %} {% endblock %}

View file

@ -22,8 +22,7 @@ form { display: flex; flex-direction: column; gap: 0.5em; }
<label for="password">Password:</label> <label for="password">Password:</label>
<input type="password" id="password" name="_password"> <input type="password" id="password" name="_password">
{# If you want to control the URL the user is redirected to on success <input type="hidden" name="_target_path" value="/manage/podcasts">
<input type="hidden" name="_target_path" value="/account"> #}
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}"> <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">

View file

@ -1,4 +1,8 @@
<form method="post" action="{{ path('app_podcast_delete', {'id': podcast.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');"> <form
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ podcast.id) }}"> method="post"
<button class="btn">Delete</button> action="{{ path('app_podcast_delete', {'id': podcast.id}) }}"
onsubmit="return confirm('Are you sure you want to delete this podcast?');"
>
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ podcast.id) }}">
<button class="btn">Delete</button>
</form> </form>

View file

@ -1,4 +1,4 @@
{{ form_start(form) }} {{ form_start(form) }}
{{ form_widget(form) }} {{ form_widget(form) }}
<button class="btn">{{ button_label|default('Save') }}</button> <button class="btn">{{ button_label|default('Save') }}</button>
{{ form_end(form) }} {{ form_end(form) }}

View file

@ -3,11 +3,11 @@
{% block title %}Edit Podcast{% endblock %} {% block title %}Edit Podcast{% endblock %}
{% block body %} {% block body %}
<h1>Edit Podcast</h1> <h1>Edit Podcast</h1>
{{ include('podcast/_form.html.twig', {'button_label': 'Update'}) }} {{ include('podcast/_form.html.twig', {'button_label': 'Update'}) }}
<a href="{{ path('app_podcast_index') }}">back to list</a> <a href="{{ path('app_podcast_index') }}">back to list</a>
{{ include('podcast/_delete_form.html.twig') }} {{ include('podcast/_delete_form.html.twig') }}
{% endblock %} {% endblock %}

View file

@ -5,42 +5,44 @@
{% block stylesheets %} {% block stylesheets %}
{{ parent() }} {{ parent() }}
<style> <style>
td img { width: 5em; } td img { width: 5em; }
</style> </style>
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<h1>Podcast index</h1> <h1>Your podcasts</h1>
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
<th>Id</th> <th>Id</th>
<th>Name</th> <th>Name</th>
<th>Author</th> <th>Author</th>
<th>Logo</th> <th>Logo</th>
<th>actions</th> <th>actions</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for podcast in podcasts %} {% for podcast in podcasts %}
<tr> <tr>
<td>{{ podcast.id }}</td> <td>{{ podcast.id }}</td>
<td>{{ podcast.name }}<br>(<code>{{ podcast.slug }}</code>)</td> <td>{{ podcast.name }}<br>(<code>{{ podcast.slug }}</code>)</td>
<td>{{ podcast.author }}</td> <td>{{ podcast.author }}</td>
<td><img src="{{ podcast.logoPath }}" alt="{{ podcast.name }} logo"></td> <td><img src="{{ podcast.logoPath }}" alt="{{ podcast.name }} logo"></td>
<td> <td>
<a href="{{ path('app_podcast_show', {'id': podcast.id}) }}">show</a> <a href="{{ path('app_podcast_show', {'id': podcast.id}) }}"
<a href="{{ path('app_podcast_edit', {'id': podcast.id}) }}">edit</a> ><button>Show</button></a>
</td> <a href="{{ path('app_podcast_edit', {'id': podcast.id}) }}"
</tr> ><button>Edit</button></a>
{% else %} </td>
<tr> </tr>
<td colspan="5">no records found</td> {% else %}
</tr> <tr>
{% endfor %} <td colspan="5">No podcasts found.</td>
</tbody> </tr>
</table> {% endfor %}
</tbody>
</table>
<a href="{{ path('app_podcast_new') }}">Create new</a> <a href="{{ path('app_podcast_new') }}"><button>Create new</button></a>
{% endblock %} {% endblock %}

View file

@ -3,9 +3,9 @@
{% block title %}New Podcast{% endblock %} {% block title %}New Podcast{% endblock %}
{% block body %} {% block body %}
<h1>Create new Podcast</h1> <h1>Create new Podcast</h1>
{{ include('podcast/_form.html.twig') }} {{ include('podcast/_form.html.twig') }}
<a href="{{ path('app_podcast_index') }}">back to list</a> <a href="{{ path('app_podcast_index') }}">back to list</a>
{% endblock %} {% endblock %}

View file

@ -2,8 +2,15 @@
{% block title %}Podcast{% endblock %} {% block title %}Podcast{% endblock %}
{% block stylesheets %}
{{ parent() }}
<style>
th { min-width: 8em; }
</style>
{% endblock %}
{% block body %} {% block body %}
<h1>Podcast</h1> <h1>Podcast {{ podcast.name }}</h1>
<table class="table"> <table class="table">
<tbody> <tbody>