Merged in feature_users (pull request #4)
Simple user invtes interface.
This commit is contained in:
commit
719e552088
|
@ -23,6 +23,12 @@ user_register:
|
||||||
method: GET
|
method: GET
|
||||||
inviteCode: \w{32}
|
inviteCode: \w{32}
|
||||||
|
|
||||||
|
user_account_invites:
|
||||||
|
path: /account/invites
|
||||||
|
controller: App\Controller\AccountController::invites
|
||||||
|
requirements:
|
||||||
|
method: GET
|
||||||
|
|
||||||
user_login:
|
user_login:
|
||||||
path: /login
|
path: /login
|
||||||
controller: App\Controller\SecurityController::login
|
controller: App\Controller\SecurityController::login
|
||||||
|
|
23
src/Controller/AccountController.php
Normal file
23
src/Controller/AccountController.php
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Entity\User;
|
||||||
|
use App\Repository\InviteRepository;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class AccountController extends Controller
|
||||||
|
{
|
||||||
|
public function invites(InviteRepository $inviteRepo): Response
|
||||||
|
{
|
||||||
|
/** @var User $user */
|
||||||
|
if (null === $user = $this->getUser()) {
|
||||||
|
throw $this->createAccessDeniedException('User not found exception');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('Account/invites.html.twig', [
|
||||||
|
'invites' => $inviteRepo->findInvitesByUser($user),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ class Invite
|
||||||
/**
|
/**
|
||||||
* @var User
|
* @var User
|
||||||
*
|
*
|
||||||
* @ORM\ManyToOne(targetEntity="App\Entity\User")
|
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="invites")
|
||||||
* @ORM\JoinColumn(name="user_id", nullable=false)
|
* @ORM\JoinColumn(name="user_id", nullable=false)
|
||||||
*/
|
*/
|
||||||
private $user;
|
private $user;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Repository;
|
namespace App\Repository;
|
||||||
|
|
||||||
use App\Entity\Invite;
|
use App\Entity\{Invite, User};
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Symfony\Bridge\Doctrine\RegistryInterface;
|
use Symfony\Bridge\Doctrine\RegistryInterface;
|
||||||
|
|
||||||
|
@ -17,4 +17,16 @@ class InviteRepository extends ServiceEntityRepository
|
||||||
{
|
{
|
||||||
$this->getEntityManager()->persist($invite);
|
$this->getEntityManager()->persist($invite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return Invite[] */
|
||||||
|
public function findInvitesByUser(User $user): iterable
|
||||||
|
{
|
||||||
|
$qb = $this->createQueryBuilder('i');
|
||||||
|
$qb
|
||||||
|
->select(['i', 'uu'])
|
||||||
|
->leftJoin('i.usedBy', 'uu')
|
||||||
|
;
|
||||||
|
|
||||||
|
return $qb->getQuery()->getResult();
|
||||||
|
}
|
||||||
}
|
}
|
30
templates/Account/invites.html.twig
Normal file
30
templates/Account/invites.html.twig
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>Your invites</h1>
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th><i class="icon-external-link"></i></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{# @var invite \App\Entity\Invite #}
|
||||||
|
{% for invite in invites %}
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{{ loop.index }}</th>
|
||||||
|
<td>
|
||||||
|
{% if invite.usedBy %}
|
||||||
|
Used by <strong>{{ invite.usedBy.username }}</strong>.
|
||||||
|
{% else %}
|
||||||
|
{% set invite_url = url('user_register', { inviteCode: invite.code }) %}
|
||||||
|
<input class="form-control" type="url" value="{{ invite_url }}" readonly="readonly" onclick="this.select()">
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
|
@ -13,6 +13,8 @@
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<!-- Bootstrap core CSS -->
|
<!-- Bootstrap core CSS -->
|
||||||
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<!-- Font Awesome -->
|
||||||
|
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
|
||||||
<link href="/css/style.css" rel="stylesheet">
|
<link href="/css/style.css" rel="stylesheet">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
|
@ -20,7 +22,7 @@
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
|
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
|
||||||
<a class="navbar-brand" href="{{ path('index') }}">Magnetico Web</a>
|
<a class="navbar-brand" href="{{ path('index') }}"><i class="icon-magnet"></i> Magnetico Search</a>
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -30,10 +32,11 @@
|
||||||
<ul class="navbar-nav mr-auto">
|
<ul class="navbar-nav mr-auto">
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a href="#" class="nav-link dropdown-toggle" role="button" data-toggle="dropdown">
|
<a href="#" class="nav-link dropdown-toggle" role="button" data-toggle="dropdown">
|
||||||
{{ app.user.username }}
|
<i class="icon-user"></i> {{ app.user.username }}
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<a href="{{ path('user_logout') }}" class="dropdown-item">Logout</a>
|
<a href="{{ path('user_account_invites') }}" class="dropdown-item"><i class="icon-group"></i> Invites</a>
|
||||||
|
<a href="{{ path('user_logout') }}" class="dropdown-item"><i class="icon-signout"></i> Logout</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -42,7 +45,7 @@
|
||||||
<form class="form-inline my-2 my-lg-0" action="{{ path('torrents_search') }}" method="get">
|
<form class="form-inline my-2 my-lg-0" action="{{ path('torrents_search') }}" method="get">
|
||||||
<input name="query" class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search"
|
<input name="query" class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search"
|
||||||
value="{% if searchQuery is defined %}{{ searchQuery }}{% endif %}">
|
value="{% if searchQuery is defined %}{{ searchQuery }}{% endif %}">
|
||||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
<button class="btn btn-outline-success my-2 my-sm-0" type="submit"><i class="icon-search"></i> Search</button>
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -53,10 +56,10 @@
|
||||||
</main><!-- /.container -->
|
</main><!-- /.container -->
|
||||||
|
|
||||||
{% block javascript %}
|
{% block javascript %}
|
||||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
|
<script src="//code.jquery.com/jquery-3.3.1.slim.min.js"></script>
|
||||||
<script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery-slim.min.js"><\/script>')</script>
|
<script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery-slim.min.js"><\/script>')</script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
|
<script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
|
||||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
|
<script src="//stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="well">
|
<div class="well">
|
||||||
{% if not is_granted('ROLE_USER') %}
|
{% if not is_granted('ROLE_USER') %}
|
||||||
<a href="{{ path('user_login') }}" class="btn btn-lg btn-primary">Login</a>
|
<a href="{{ path('user_login') }}" class="btn btn-lg btn-primary"><i class="icon-signin"></i> Login</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
Loading…
Reference in a new issue