Skip to content
Davide64-dev edited this page Jan 28, 2024 · 1 revision

PA: Product and Presentation

In today's dynamic social media landscape, there's a growing need for a user-friendly platform, especially among students and academics seeking reliable information and effective communication tools. With this goal in mind, our network aims to redefine the social networking experience.

A9: Product

We are an academic social network designed to foster collaborative learning. Our platform provides a space for students to explore new subjects and assist each other in their academic pursuits.

Our mission is to make learning accessible and enjoyable for everyone. We believe in the power of community and the importance of sharing knowledge.

Whether you're a student looking to expand your horizons or an educator seeking to connect with learners, we welcome you to our network. Together, we can make learning an exciting journey.

1. Installation

Source code

The source code is available here under the PA tag.

Running the image

docker run -it -p 8000:80 --name=lbaw2391 -e DB_DATABASE="lbaw2391" -e DB_SCHEMA="lbaw2391" -e DB_USERNAME="lbaw2391" -e DB_PASSWORD="vUVTyupt" git.fe.up.pt:5050/lbaw/lbaw2324/lbaw2391

2. Usage

Link for the website

https://lbaw2391.lbaw.fe.up.pt

2.1. Administration Credentials

Administration URL: https://lbaw2391.lbaw.fe.up.pt/admin/user

Username Password
admin admin

2.2. User Credentials

Type Username Password
basic account user 1 password
group owner (of prolog enthusiasts) johndoe hello

3. Application Help

In order to provide a smoother user experience, we implemented static pages which explain what the app is and what it can do, as well as other contextual help in the user interface.

3.1. Contextual help in the UI

Some examples include:

3.1.1. * to indicate which fields of a form are required to fill out and which are not.

image

image

3.1.2. Confirmation modals on destructive actions

For example:

Logging out

This was done in order to prevent unfortunate misclicks.

image

Deleting a user

image

3.1.3. Snackbars indicating success on an action

For example:

Copying a post link

When clicking the link symbol near the title of the post in a post card, a snackbar appears indicating that the link was copied.

image

Promoting a group user to owner

When promoting a group user, after the action is succeded, there is a snackbar indicating so.

image

3.2. Help static pages

image

3.2.2. About page

image

We also added a contacts section where the users can find information of how to reach out to us in case of any questions or issues.

image

3.2.4. Faq Page

In this page, as the name suggests, users will be able to find answers to a lot of common questions, which may be extremely helpful to them.

image

4. Input Validation

4.1. Server Side

On the server side, we used the validate function from the Request class in Laravel, where we forced the data being received to be according to the defined parameters.

Some examples include:

4.1.1. Creating a post
$request->validate([
    'title' => 'required|string|max:255',
    'content' => 'required|string',
    'attachment' => 'nullable|file',
    'group' => 'nullable|integer',
    'is_private' => 'required|boolean',
    'poll_options' => 'nullable|array'
]);
4.1.2. Adding a reaction
$request->validate([
    'type' => Rule::in(Reaction::$possible_types)
]);

The Reaction::$possible_types is a static array containing the possible string values for a type of a reaction

4.1.3. Registering a user
$request->validate([
    'username' => 'required|string|max:250|unique:users',
    'email' => 'required|email|max:250|unique:users',
    'password' => 'required|min:8|confirmed',
    'academic_status' => 'required|string|max:250',
    'university' => 'required|string|max:250',
    'description' => 'nullable|string|max:512',
    'display_name' => 'required|string|max:32',
    'is_private' => 'required|bool',
]);

4.2. Client Side

On the client side, we validated using both HTML built-in attributes to do that such as the required one as well as javascript.

Some examples include:

4.2.1. Validating username and email does not already exist

We used AJAX to perform this, so that the user knows before submitting that the request will be rejected because of them using an already taken username or email.

async function checkUsernameExists(data) {
	const element = document.getElementById("username");
	const errorMessage = document.getElementById("username-error");
	const response = await fetch("/api/users/username/" + data);

	if (response.status === 404) {
		errorMessage.textContent = "";
		element.setCustomValidity("");
	} else if (response.status === 200) {
		errorMessage.textContent = "Username is already in use";
		element.setCustomValidity("Username is already in use");
	} else {
		console.error("Error fetching data:", error);
	}
}

image

4.2.2. Validating that the post title and content are not empty

image

This is done through the required attribute of the HTML element.

<textarea
	required
	name="content"
	id="content"
	rows="5"
	class="mt-1 p-2 border border-gray-300 rounded-md w-full resize-none"
></textarea>

5. Check Accessibility and Usability

Provide the results of accessibility and usability tests using the following checklists. Include the results as PDF files in the group's repository. Add individual links to those files here.

Accessibility: https://ux.sapo.pt/checklists/acessibilidade/

Usability: https://ux.sapo.pt/checklists/usabilidade/

5.1. Usability

The score was 27/28

The usability checklist can be found here

5.2. Accessibility

The score was 16/18

The acessiblity checklist can be found here

6. HTML & CSS Validation

6.1. CSS Validation

app.css Link

6.2. HTML Validation

6.2.1. Group page

HTML Validation

6.2.2. Home page

HTML Validation

6.2.3. Post page

HTML Validation

7. Revisions to the Project

7.1. Database

Users

Added parameters to the users in order to support description and university.

Groups

Added parameters to the groups in order to support banner and image.

Notifications

Added parameter read to the nofications tables in order to save the state of the notification:

  • post_tag_not
  • group_request_not
  • friend_request_not
  • comment_not
  • reaction_not

Also added parameters is_accepted to the friend_request_not and group_request_not tables in order to save the state of the request

Reset password

Added one table to support password resets:

  • password_reset_tokens
Group invitations

Added two tables in order to support group invites:

  • group_invitations
  • group_invitation_nots

Creation of a trigger that creates a group_request_not when a group request is accepted

Creation of a trigger that creates a group_invitation_nots when a group invite is created

Polls

Added three tables in order to support polls in posts (only 1 per post):

  • polls
  • poll_options
  • poll_option_votes
Reactions

We added two more reactions to the previously defined enum in our database:

  • 'HANDSHAKE'
  • 'HANDPOINTUP'
Appeals

Added two parameters created_at and updated_at to the appeal table in order to support the timestamps of the appeals.

7.2. Polls

7.2.1. Polls
  • POST /poll/{id} $\rightarrow$ Vote on a poll
  • DELETE /poll/{id} $\rightarrow$ Remove vote from poll
7.2.2. Reset password

We also added new routes for the reset password mechanism

  • GET /reset-password/{token} $\rightarrow$ Get the form to input the email of the account
  • POST /reset-password/{token}$\rightarrow$ Send a reset confirmation request
  • GET /reset-password/{token} $\rightarrow$ Get the form to input new passwords
  • POST /reset-password/{token} $\rightarrow$ Set a new password
7.2.3. Notifications
  • GET /notifications $\rightarrow$ Get the HTML for the notifications page
  • GET /api/notifications/{filter} $\rightarrow$ Get the notifications based on a filter (e.g. reactions, comments)
7.2.4. Reactions
  • GET /comment/{id}/reaction $\rightarrow$ Get the reactions for a comment
  • POST /comment/{id}/reaction $\rightarrow$ Add a reaction to a comment
  • DELETE /comment/{id}/reaction $\rightarrow$ Remove a reaction from a comment
7.2.5. Friends
  • GET /api/users/{username}/friends $\rightarrow$ Get the friend cards via ajax
7.2.6. Groups
  • GET /api/group/{id}

7.3. User stories

There were only two new user stories added that were not on the initial planning of the project in the previous artifacts.

As a post author, I should be able to create a poll so that I can better get in touch with the community's feelings

  • As an Authenticated User, I need to be able to vote on a poll so that I can express my opinion on a certain matter.
  • As an Authenticated User, I need to be able to remove my vote on a poll so that I can retract my opinion from a certain matter.

8. Implementation Details

8.1. Libraries Used

Used as a framework for developing a server-side web app.

Used as a library in order to ease the process of adding icons to our web app.

In the root page of the website, you are going to be able to see icons, which are from FontAwesome.

Used as a CSS library, in order to accelerate the process of styling the pages of the application, instead of us having to write custom css as well as it has better support for the majority of the browsers and screen readers out of the box, without us having to write custom css rules specific to each browser engine.

Used in order to provide real time features to our web app such as:

  • When a user receives a notification (e.g. comment or reaction on their posts or a friend request), it appears realtime on their browsers.
  • When an admin is on the admin dashboard and it receives an appban appeal, the UI is updated to reflect that fact.

This was used in order to crop the images sent to the backend in order to spare space on the server.

Instead of storing a big image, we just store the parts that will be needed to show to the other users by creating a small and medium versions of the image that will be used in different places.

Also helps when the page style is turned off, since it shows images with a more consistent and small size.

Examples of that type of use include:

Profile page
<img src="{{ $user->getProfileImage('medium') }}" ... />
User card (e.g. the cards shown upon searching for an user)
<img src="{{ $user->getProfileImage('small') }}" ... />

We used tagify in order to implement the ability for users to tag other friends in their posts.

We used Mailtrap in the reset password feature, since on free plans we can't really send actual emails to other real email addresses.

8.2 User Stories

This subsection should include all high and medium priority user stories, sorted by order of implementation. Implementation should be sequential according to the order identified below.

If there are new user stories, also include them in this table. The owner of the user story should have the name in bold. This table should be updated when a user story is completed and another one started.

Identifier Name Module Priority Team Members State
US01 View Public Timeline M02 High Tomás Palma 100%
US02 View Public Profiles M05 High João Fernandes 100%
US03 Search for Public Users M06 High Tomás Palma 100%
US04 Exact Match Search M02 High Tomás Palma 100%
US05 Full Text Search M06 High Tomás Palma 100%
US06 Search Over Multiple Attributes M06 Medium Tomás Palma 100%
US07 Search Filter M06 Medium Tomás Palma, Pedro Oliveira, Davide Teixeira, João Fernandes 100%
US08 Contextual Error Messages - Medium Pedro Olveira, Davide Teixeira, João Fernandes, Tomás Palma 100%
US09 Contextual Help - Medium Davide Teixeira, Pedro Oliveira, João Fernandes, Tomás Palma 100%
US10 About US M04 Medium João Fernandes 100%
US11 Contacts M04 Low João Fernandes 100%
US12 Main Features M04 Low João Fernandes 100%
US13 Placeholders in Form Inputs - Low Pedro Oliveira, João Fernandes 100%
US14 Login M01 High Davide Teixeira 100%
US15 Register M01 High Davide Teixeira, João Fernandes 100%
US16 Logout M01 High Davide Teixeira 100%
US17 Search M06 High Tomás Palma 100%
US18 View Profile M05 High João Fernandes 100%
US19 Send Friend Request M05 High João Fernandes 100%
US20 Manage Received Friend Requests M05 High João Fernandes 100%
US21 Manage Friends M05 High João Fernandes 100%
US22 Create Post M07 High Pedro Oliveira 100%
US23 View Personalized Timeline M02 High Tomás Palma 100%
US24 Support Profile Picture M05 Medium João Fernandes 100%
US25 Recover Password M05 Medium Tomás Palma 100%
US26 Delete Account M05 Medium João Fernandes 100%
US27 Edit Profile M05 Medium João Fernandes 100%
US28 View Personal Notifications M09 Medium Tomás Palma, João Fernandes, Pedro Oliveira, Davide Texeira 100%
US29 Appeal for Unblock M05 Medium Tomás Palma 100%
US30 Comment on Posts M07 Medium Pedro Oliveira 100%
US31 React to Post M07 Medium Tomás Palma 100%
US32 React to Comment M10 Medium Tomás Palma 100%
US33 Create Group M08 Medium Pedro Oliveira 100%
US34 Manage Group Invitations M08 Medium Davide Teixeira, Tomás Palma 100%
US35 View Friends' Feed M05 Medium Tomás Palma 100%
US37 Friend Requests M05 Medium João Fernandes 100%
US39 Copy post link M07 Low Tomás Palma 100%
US40 View Group's Members M08 Medium Tomás Palma, Davide Teixeira 100%
US41 Post on Group M07 Medium Pedro Oliveira, Davide Teixeira 100%
US42 Leave Group M08 Medium Davide Teixeira 100%
US43 Add to Group M08 High Davide Teixeira, Tomás Palma 100%
US44 Manage Join Requests M08 High Davide Teixeira 100%
US45 Edit Group Info M08 Medium João Fernandes 100%
US46 Remove Member M08 Medium Tomás Palma 100%
US47 Remove Post From Group M08 Medium Pedro Oliveira 100%
US48 Change Group Visibility M08 Medium João Fernandes 100%
US49 Edit Post M07 High Pedro Oliveira 100%
US50 Delete Post M07 High Pedro Oliveira 100%
US51 Likes on Own Post M07 Medium Tomás Palma 100%
US52 Comments on Own Posts M08 Medium Pedro Oliveira 100%
US53 Manage Post Visibility M07 Low Pedro Oliveira 100%
US54 Edit Comment M10 Medium Pedro Oliveira 100%
US55 Delete Comment M10 Medium Pedro Oliveira 100%
US56 Delete Reaction M07 Medium Tomás Palma 100%
US57 Administer Account M03 High Tomás Palma 100%
US58 Manage User Accounts M03 High Tomás Palma 100%
US59 Delete Users Accounts M03 High Tomás Palma 100%
US60 Create Users Accounts M03 High Tomás Palma 100%
US61 Edit Users Accounts M03 High Tomás Palma 100%
US62 Block User M03 Medium Tomás Palma 100%
US63 Unblock User M03 Medium Tomás Palma 100%
US64 Create poll on post M07 Low Tomás Palma 100%
US65 Vote on poll M11 Low Tomás Palma 100%
US66 Remove vote on poll M11 Low Tomás Palma 100%
US36 Tag Friends in Post M07 Low Tomás Palma, Pedro Oliveira 50%
US38 Upload CV M05 Low Tomás Palma 0%

A10: Presentation

This artifact corresponds to the presentation of the product.

1. Product presentation

URL to the product: https://lbaw2391.lbaw.fe.up.pt

Gamma are an academic social network designed to foster collaborative learning. Our platform provides a space for students to explore new subjects and assist each other in their academic pursuits, whose mission is to make learning accessible and enjoyable for everyone. We believe in the power of community and the importance of sharing knowledge.

In Gamma, you can connect with other people by seeing, reacting or commenting on their posts, as well as trying to build a community by creating and joining groups. Besides that, you are also able to make friend and connections with other people. You can also express your opinions by creating posts, writting comments or voting on polls.

2. Video presentation

Screenshot of the video plus the link to the lbaw2391.mp4 file.

https://youtu.be/rEHUUQ-hCiE

image


Revision history

Changes made to the first submission:

  1. Added product vision and instructions to run commands (18th december 2023)
  2. Added user stories table and filled some of them (18th december 2023)
  3. Added input validation examples. (20th december 2023)
  4. Added contextual help examples on our web app. (20th december 2023)
  5. Added intervention/image to libraries used. (20th december 2023)
  6. Added tagify to libraries used. (21th december 2023)
  7. Finished the user stories table. (21th december 2023)
  8. Polished user stories table. (21th december 2023)
  9. Corrected user credentials (21th december 2023)

GROUP2391, 21/12/2023

Clone this wiki locally