Added Front listings and member editing

Added the template for to display locations on the front end. Still need
to add template for individual locations.

Also added member editing. Still need to wire up the avatar uploading
but adding and editing member information is possible. Still need to
fine tune it according to roles
symfony-version
Ro 2 years ago
parent e897453664
commit c5d1ab0266

@ -1,6 +1,8 @@
section[role="den-login"] { section[role="den-login"] {
padding: 30px; width: 100%;
width: 300px; max-width: 600px;
padding: 10px;
margin: 0 auto;
color: var(--highlight); color: var(--highlight);
} }
@ -12,7 +14,10 @@ section[role="den-login"] div[role="system-notice"] {
} }
section[role="den-index"] { section[role="den-index"] {
padding: 20px; width: 100%;
max-width: 600px;
padding: 10px;
margin: 0 auto;
color: var(--white); color: var(--white);
} }

@ -1,5 +1,8 @@
section[role="loc-index"] { section[role="loc-index"] {
padding: 20px; width: 100%;
max-width: 600px;
padding: 10px;
margin: 0 auto;
} }
section[role="loc-index"] img { section[role="loc-index"] img {

@ -0,0 +1,7 @@
section[role="members-index"] {
width: 100%;
max-width: 600px;
padding: 10px;
margin: 0 auto;
color: var(--white);
}

@ -4,4 +4,5 @@
@import "../global/frame.css"; @import "../global/frame.css";
@import "../global/icons.css"; @import "../global/icons.css";
@import "locations.css"; @import "locations.css";
@import "members.css";
@import "index.css"; @import "index.css";

@ -2,7 +2,7 @@ section[role="about"] {
background: var(--primary); background: var(--primary);
width: 100%; width: 100%;
max-width: 600px; max-width: 600px;
padding: 100px; padding: 10px;
margin: 0 auto; margin: 0 auto;
color: var(--white); color: var(--white);
} }

@ -2,8 +2,7 @@ section[role="listings"] {
background: var(--primary); background: var(--primary);
width: 100%; width: 100%;
max-width: 600px; max-width: 600px;
border-radius: 3px; padding: 10px;
padding: 100px;
margin: 0 auto; margin: 0 auto;
color: var(--white); color: var(--white);
} }

@ -9,58 +9,66 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Doctrine\Persistence\ManagerRegistry;
//use App\Utils\PageRender;
//use App\Utils\StringTools;
use App\Service\Auth;
use App\Service\HandleMembers; use App\Service\HandleMembers;
use App\Service\Render;
use App\Service\Auth;
class Members extends AbstractController class Members extends AbstractController
{ {
/** /**
* @Route("/dashboard/members", name="dash-members") * @Route("/den/members/page/{pageNum}", name="den-locations")
*/ */
public function showMembers( public function showMembers(
Request $request, Request $request,
Auth $auth Auth $auth,
): Response { Render $render,
HandleMembers $members,
int $pageNum = 1
) {
$result = $auth->status(); $result = $auth->status();
if ($result["status"]) { if ($result["status"]) {
/* $self = $members->getYou();
return $render->renderPage( $you = $self->getId();
["bgImage" => "", "mode" => "index"], $list = $members->getMemberPage($pageNum);
"The Nile List | Members",
"dash/members.html.twig" return $render->page([
); "mode" => "index",
*/ "you" => $you,
"list" => $list], "Bad Space | Members", "back/members.twig");
} else { } else {
//back to index to login
header("Location:/knockknock");
return new Response("<html><body>LOGGED IN</body></html>");
} }
} }
/** /**
* @Route("/den/members/add", name="members-add") * @Route("/den/members/{action}/{id}", name="den-members")
*/ */
public function addMembers( public function handleMemberActions(
Request $request, Request $request,
Auth $auth, Auth $auth,
Render $render,
HandleMembers $members, HandleMembers $members,
ManagerRegistry $doctrine string $action = "index",
int $id = 0
): Response { ): Response {
$result = $auth->status(); $result = $auth->status();
if ($result["status"]) { if ($result["status"]) {
if ($request->getMethod() == "GET") { if ($request->getMethod() == "GET") {
return $this->render("back/members.twig", [ $self = $members->getYou();
"title" => "Get a class from the cupboard", $you = $self->getId();
"mode" => "add" $member = [];
]); if ($id != 0) {
$member = $members->getMemberById($id);
}
return $render->page([
"mode" => $action,
"you" => $you,
"currentMember" => $member], "Bad Space | Members", "back/members.twig");
} else { } else {
//add new member //add new member
$token = $request->get("token"); $token = $request->get("token");
$notice = ""; $notice = "";
$entityManager = $doctrine->getManager(); $mode = $request->get("mode");
$id = $request->get("member_id");
//token check //token check
if (!$this->isCsrfTokenValid("upload", $token)) { if (!$this->isCsrfTokenValid("upload", $token)) {
@ -74,7 +82,12 @@ class Members extends AbstractController
] ]
); );
} }
$self = $members->getYou();
$you = $self->getId();
$member = [];
if ($id != 0) {
$member = $members->getMemberById($id);
}
if ( if (
$request->request->get("handle") == "" || $request->request->get("handle") == "" ||
$request->request->get("role") == "" || $request->request->get("role") == "" ||
@ -82,48 +95,44 @@ class Members extends AbstractController
$request->request->get("email") == "" || $request->request->get("email") == "" ||
$request->request->get("pronoun") == "" $request->request->get("pronoun") == ""
) { ) {
return new Response("<html><body>All fields required</body></html>");
/*
$notice = "All fields are required, champ."; $notice = "All fields are required, champ.";
return $render->renderPage( return $render->page([
["bgImage" => "", "mode" => "add", "notice" => $notice], "notice" => $notice,
"The Nile List | Add Member Error", "mode" => $mode,
"dash/members.html.twig" "you" => $you,
); "currentMember" => $member], "Bad Space | Members", "back/members.twig");
*/
} }
//empty valid email check
if ( if (
!filter_var($request->request->get("email"), FILTER_VALIDATE_EMAIL) !filter_var($request->request->get("email"), FILTER_VALIDATE_EMAIL)
) { ) {
return new Response("<html><body>BOGUS EMAIL</body></html>");
/*
$notice = "Need a valid email, slick."; $notice = "Need a valid email, slick.";
return $render->renderPage( return $render->page([
["bgImage" => "", "mode" => "add", "notice" => $notice], "notice" => $notice,
"The Nile List | Add Member Error", "mode" => $mode,
"dash/members.html.twig" "you" => $you,
); "currentMember" => $member], "Bad Space | Members", "back/members.twig");
*/ }
// password confirm check
if ($request->request->get("new_pass") != "") {
if ($request->request->get("new_pass") != $request->request->get("new_pass_confirm")) {
$notice = "New password must be confirmed";
return $render->page([
"notice" => $notice,
"mode" => $mode,
"you" => $you,
"currentMember" => $member], "Bad Space | Members", "back/members.twig");
}
} }
//check clear, call add method //check clear, call add method
$response = $members->addMember($request); $response = $members->modifyMember($request, $id, $mode);
if ($response["status"]) { if ($response["status"]) {
/* return $render->page([
return $render->renderPage(
[
"bgImage" => "",
"mode" => "add",
"notice" => $response["message"], "notice" => $response["message"],
], "mode" => $mode,
"The Nile List | Add Members", "you" => $you,
"dash/members.html.twig" "currentMember" => $member], "Bad Space | Members", "back/members.twig");
);
*/
return new Response("<html><body>MEMBER ADDED</body></html>");
} else { } else {
return new Response("<html><body>" . $response["message"] . "</body></html>"); return new Response("<html><body>" . $response["message"] . "</body></html>");
/* /*
@ -138,7 +147,7 @@ class Members extends AbstractController
} else { } else {
//back to index to login //back to index to login
header("Location:/den"); header("Location:/den");
return new Response("<html><body>LOGGED IN</body></html>"); return new Response("<html><body>TO THE FRONT</body></html>");
} }
} }
} }

@ -24,6 +24,7 @@ class HandleMembers
{ {
private $session; private $session;
private $entityManager; private $entityManager;
private $limit = 5;
public function __construct( public function __construct(
EntityManagerInterface $entityManager, EntityManagerInterface $entityManager,
@ -38,22 +39,63 @@ class HandleMembers
* *
* @return MEMBERS data object * @return MEMBERS data object
*/ */
public function getMember() public function getYou()
{ {
$member = $this->session->get("member"); $member = $this->session->get("member");
return $member; return $member;
} }
public function getMemberById(int $id)
{
$member = $this->entityManager->getRepository(Member::class)->find($id);
return $member;
}
public function getMemberPage(int $page, string $active = "all")
{
$members = $this->entityManager->getRepository(Member::class);
if ($active == "true" || $active == "false") {
$list = $members->findBy(["active" => $active], ["id" => "ASC"]);
} else {
$list = $members->findBy([], ["id" => "ASC"]);
}
$count = ceil(count($list) / $this->limit);
$totalCount = count($list);
$shelf = [];
$range = $page * $this->limit - $this->limit;
for ($i = 0; $i <= $this->limit; $i++) {
try {
array_push($shelf, $list[$i + $range]);
} catch (Exception $error) {
}
}
return [
"members" => $shelf,
"total" => $count,
"totalMembers" => $totalCount,
];
}
/** /**
* Add new member to db * Add or edit new member
* *
* @param Request $request object containing posted data * @param Request $request object containing posted data
* @return JSON * @param int $memberId member identifier
* @param string $action request task
* @return Object
*/ */
public function addMember($request) public function modifyMember($request, $memberId, $action)
{ {
$errorMessage = null; $errorMessage = null;
if ($action == "add") {
$member = new Member(); $member = new Member();
} else {
$member = $this->entityManager->getRepository(Member::class)->find($memberId);
}
//submitted values //submitted values
$handle = $request->request->get("handle"); $handle = $request->request->get("handle");
@ -69,15 +111,23 @@ class HandleMembers
//set defaults //set defaults
//$utils = new StringTools(); //$utils = new StringTools();
$uuid = $hash = password_hash("passw0rd!", PASSWORD_DEFAULT); if ($action == "add") {
$hash = password_hash("passw0rd!", PASSWORD_DEFAULT);
$member->setPassword($hash); $member->setPassword($hash);
$member->setActive(false);
$member->setAvatar("default-member-avatar"); $member->setAvatar("default-member-avatar");
$member->setUuid(Uuid::v4()); $member->setUuid(Uuid::v4());
$member->setActive(false); $this->entityManager->persist($member);
$member->setCreatedAt(new \DateTimeImmutable()); $member->setCreatedAt(new \DateTimeImmutable());
$member->setLastLogin(new \DateTimeImmutable()); $member->setLastLogin(new \DateTimeImmutable());
} else {
$this->entityManager->persist($member); $active = ($request->request->get("active") == "true" ? true : false);
$member->setActive($active);
if ($request->request->get("new_pass") != "") {
$hash = password_hash($request->request->get("new_pass"), PASSWORD_DEFAULT);
$member->setPassword($hash);
}
}
try { try {
$this->entityManager->flush(); $this->entityManager->flush();
@ -93,10 +143,16 @@ class HandleMembers
$errorMessage = $error->getMessage(); $errorMessage = $error->getMessage();
} }
// return result status // return result status
$message = "";
if ($action == "add") {
$message = "New member added. Woohoo!";
} else {
$message = "Member Info Edited";
}
if ($errorMessage == null) { if ($errorMessage == null) {
return $response = [ return $response = [
"status" => true, "status" => true,
"message" => "New member added. Woohoo!", "message" => $message,
]; ];
} else { } else {
return $response = ["status" => false, "message" => $errorMessage]; return $response = ["status" => false, "message" => $errorMessage];
@ -112,8 +168,7 @@ class HandleMembers
public function updateMember($request) public function updateMember($request)
{ {
$errorMessage = null; $errorMessage = null;
$currentMember = $this->getMember(); $id = $request->request->get("member_id");
$id = $currentMember->getMemberId();
$member = $this->entityManager->getRepository(Members::class)->find($id); $member = $this->entityManager->getRepository(Members::class)->find($id);
$image = $request->files->get("avi"); $image = $request->files->get("avi");
if (!empty($image)) { if (!empty($image)) {

@ -4,9 +4,30 @@
{% endblock %} {% endblock %}
{% block main %} {% block main %}
<section role="intro"> <section role="members-index">
This is the screendoor member page
{% if options.mode == "index" %}
<h1>Members</h1>
<h2>Manage member accounts</h2>
<a href="/den/members/edit/{{ options.you }}">Edit Profile</a>
|
<a href="/den/members/add">Add Members</a>
<h3>Current Members</h3>
{% for member in options.list.members %}
{% if member.role != 1 %}
<a href="/den/members/edit/{{ member.id }}">{{ member.handle }}</a>
<br>
{% endif %}
{% endfor %}
{% elseif options.mode == "add" %}
<h1>Add Member</h1>
{{ include("forms/add-member-form.twig") }} {{ include("forms/add-member-form.twig") }}
{% elseif options.mode == "edit" %}
<h1>Edit Member</h1>
{{ include("forms/edit-member.twig") }}
{% endif %}
</section> </section>
{% endblock %} {% endblock %}

@ -30,7 +30,7 @@
<a href="/den" title="den index" role="nav-links"> <a href="/den" title="den index" role="nav-links">
<i class="ti ti-door" title="den index"></i> <i class="ti ti-door" title="den index"></i>
</a> </a>
<a href="/den/members" title="members" role="nav-links"> <a href="/den/members/page/1" title="members" role="nav-links">
<i class="ti ti-users" title="members"></i> <i class="ti ti-users" title="members"></i>
</a> </a>
<a href="/den/locations/page/1" title="locations" role="nav-links"> <a href="/den/locations/page/1" title="locations" role="nav-links">

@ -1,4 +1,4 @@
<form action="{{ path('members-add') }}" method="post" enctype="multipart/form-data"> <form action="{{ path('den-members') }}" method="post" enctype="multipart/form-data">
<div> <div>
<label>Handle</label><br/> <label>Handle</label><br/>
<input type="text" name="handle" value=""/> <input type="text" name="handle" value=""/>
@ -33,4 +33,5 @@
</select> </select>
</div> </div>
<input type="hidden" name="token" value="{{ csrf_token('upload') }}"/> <input type="hidden" name="token" value="{{ csrf_token('upload') }}"/>
<input type="hidden" name="mode" value="add"/>
<input type="submit" value="Add Member" name="submit_button"></form> <input type="submit" value="Add Member" name="submit_button"></form>

@ -0,0 +1,80 @@
<form action="{{ path('den-members') }}" method="post" enctype="multipart/form-data">
<div>
<label>Handle</label><br/>
<input type="text" name="handle" value="{{ options.currentMember.handle }}"/>
<br/>
<label>Email</label><br/>
<input type="text" name="email" value="{{ options.currentMember.email }}"/>
<br/>
<label>New Password</label><br/>
<input type="password" name="new_pass" value=""/>
<br/>
<label>New Password Confirm</label><br/>
<input type="password" name="new_pass_confirm" value=""/>
<br/>
<label>Gender</label><br/>
<select name="gender">
{% if options.currentMember.gender is same as ("non_binary") %}
<option value="man">Man</option>
<option value="woman">Woman</option>
<option value="non_binary" selected>Non-Binary</option>
{% elseif options.currentMember.gender is same as ("woman") %}
<option value="man">Man</option>
<option value="woman" selected>Woman</option>
<option value="non_binary">Non-Binary</option>
{% elseif options.currentMember.gender is same as ("man") %}
<option value="man" selected>Man</option>
<option value="woman">Woman</option>
<option value="non_binary">Non-Binary</option>
{% endif %}
</select>
<br/>
<label>Pronoun</label><br/>
<select name="pronoun">
{% if options.currentMember.pronoun is same as ("they/them") %}
<option value="they/them" selected>They/Them</option>
<option value="she/her">She/Her</option>
<option value="he/him">He/Him</option>
{% elseif options.currentMember.pronoun is same as ("she/her") %}
<option value="they/them">They/Them</option>
<option value="she/her" selected>She/Her</option>
<option value="he/him">He/Him</option>
{% elseif options.currentMember.pronoun is same as ("he/him") %}
<option value="they/them">They/Them</option>
<option value="she/her">She/Her</option>
<option value="he/him" selected>He/Him</option>
{% endif %}
</select>
<br/>
<label>Active?</label><br/>
<select name="active">
{% if options.currentMember.active %}
<option value="false">No</option>
<option value="true" selected>Yes</option>
{% else %}
<option value="false" selected>No</option>
<option value="true">Yes</option>
{% endif %}
</select><br/>
<label>Role</label><br/>
<select name="role">
{% if options.currentMember.role is same as (1) %}
<option value="1" selected>Admin</option>
<option value="2">Editor</option>
<option value="3">Contributer</option>
{% elseif options.currentMember.role is same as (2) %}
<option value="1">Admin</option>
<option value="2" selected>Editor</option>
<option value="3">Contributer</option>
{% elseif options.currentMember.role is same as (3) %}
<option value="1">Admin</option>
<option value="2">Editor</option>
<option value="3" selected>Contributer</option>
{% endif %}
</select>
</div>
<input type="hidden" name="token" value="{{ csrf_token('upload') }}"/>
<input type="hidden" name="member_id" value="{{ options.currentMember.id }}"/>
<input type="hidden" name="mode" value="edit"/>
<input type="submit" value="Edit Member" name="submit_button"></form>

@ -5,16 +5,22 @@
{% block main %} {% block main %}
<section role="about"> <section role="about">
<h1>About The Bad Space</h1> <h1>About</h1>
<p>The Bad Space project was born from a need to effectively identify instances that house bad actors and are poorly moderated, which puts marginalized communities at risk. It is an extension of the
<h2>What is The Bad Space?</h2>
<p>The Bad Space project was born from a need to effectively identify instances that house bad actors and are poorly moderated, which puts marginalized communities at risk.
<p>
It is an extension of the
<strong>#fediblock</strong> <strong>#fediblock</strong>
hashtag created hashtag created by
<a href="https://www.artistmarciax.com/">by Arist Maricia X <a href="https://www.artistmarciax.com/">Artist Marcia X</a>
</a>with additional support from with additional support from
<a href="https://digital.rooting.garden">Ginger</a> <a href="https://digital.rooting.garden">Ginger</a>
to provide a catolog of instances seek to cause harm and reduce the quality of experience in the fediverse. to provide a catolog of instances seek to cause harm and reduce the quality of experience in the fediverse.
</p> </p>
</p>
<p> <p>

Loading…
Cancel
Save