diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..5cc1382 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,15 @@ +dist: xenial +language: python +sudo: required +python: "3.7" +script: +- python test1.py +install: + - pip install -r requirements.txt +deploy: + provider: heroku + api_key: + secure: SRQYTCaJ7yYNsVUIG70tF13JW7PQynp9XGwxb7R6neG8R13dsZ1Aip/oyN/4WtpIRBTh9YgH5QO/bqe5MusejDt7j3uGJ9/zAjZj6iY8NVzlglJjHOGWJY9yPLmlqq/vBPIkX9JOdJMHjBDve/fqDSdDUlqOQYRpZq1aCPnKCnhjk2tfux4aWi8kOPayM8tl4mRolTWvrntcgrkenJIQx07GsTO1LwAoum2tlmGiHvbv610xpyIIUIqKNdqv676YdAxKBhQDPjFfORmMMXZswJs2jinrYpnfmwiI0TxU/YiYySjsr6yc/7PVwM/U7Z0Ehz+vuSQDFbR7lGw0XsoEhIkSbg4vKDropClndT7+1rDugc/IfQThkeRlnUGcNTkNkEaTKIgneWLPDx+Oz3mADx5Qp8zfEOXBgk5tRXkAH9M/RStQmeBhvHABmmz33a9GuNZwud6i5J0lhMpI9afNdNznH0f3AN8YKT5WG0/BQMgyXXdVfRVX+nkBff49emDgqbOaygpV0byfv4Ylla3yRdxFsxetrM/HMfCMw6y6wFtkRH07J+PwHAqOhFf0SLTrZ0VQzNKjL8bBQFeHKYd2ZRZozMsnJp9gY/7q2Z72bDg3hdgwyQ/8savJRB0AYbDiOJk8G9TLIOKWPIWhtZiscbaePpG6BUiI7WbrvGyUuXQ= + app: bc-app-class + on: + repo: DataMascara/cisc3140-su19-project diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..8c9f65a --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: gunicorn --chdir app app:app diff --git a/Quality Control/Written Reports of Tests/New Issues (Most Up to Date).pdf b/Quality Control/Written Reports of Tests/New Issues (Most Up to Date).pdf new file mode 100644 index 0000000..dad69b1 Binary files /dev/null and b/Quality Control/Written Reports of Tests/New Issues (Most Up to Date).pdf differ diff --git a/Quality Control/Written Reports of Tests/Scenario Test Documents/TestScenariosCisc3140 b/Quality Control/Written Reports of Tests/Scenario Test Documents/TestScenariosCisc3140 new file mode 100644 index 0000000..b7ed541 --- /dev/null +++ b/Quality Control/Written Reports of Tests/Scenario Test Documents/TestScenariosCisc3140 @@ -0,0 +1,88 @@ +Feature: Automated/manual test + Using cisc3140 group app developement + + Background: + Given I use dev url to navigate to login page + + + @Functional #pass scenario + Scenario: Hamburger menu expand for login page + Given user navigate to application login page + When I am not logged in to the app + Then I can see sign in and register button display + Then I can see username and password field display + + @Functional #pass scenario + Scenario: Hamburger menu hide for logged in user + Given I navigate to application login page + When I am not logged in to the app + When I type valid and to login + Then menu is in hidden state + +@Regression #pass scenario + Scenario Outline: invalid user cannot login to the app + Given I navigate to application login page + When I type valid and to login + Then error message should display for invalid user + + Examples: + | userName | password | + | ahkdahsj | jsadhjhdsjjasdja | + | 20hdjhadss | 55651/3^%$,`~* | + | &^.#-?jhadss | 1545645*sd | + | 20hdjhadss.hhd d | 12k | + + @Functional #Failed scenario + Scenario: able to like the post + Given I login to the app + When I click on like button on post + Then total like is added next to post + + @Functional #Failed scenario + Scenario: able to dislike the post + Given I login to the app + When I click on like button on post + Then total dislike is added next to post + + @Functional #Failed scenario + Scenario: able to add comments on the post + Given I login to the app + When I click on comment button on post + When I type some comments on the text field + Then I can see my comments added to the post + + @Functional #Failed scenario + Scenario: sort the post by hot or new + Given I login to the app + When I click on sort by dropdown + Then I select hot post + Then post display for hot + Then I select new post + Then post is display for new + + @EndToEnd #Failed scenario + Scenario: create a post and view the created post + Given I login to the app + When I click on create post button + And I select communities from dropdown + And I type all required field and submit + Then I can see my post on my profile + + @EndToEnd #pass scenario under condition, need to rework, i don't wanna see json output in email + Scenario: get notification on email after register + Given I login to the app + When I register for new user + And I type all required fields + And I click on register button + Then I get an email notification + + @Functional #pass scenario + Scenario: user successfully logout from the application + Given I login with valid username and password + When I click on logout button + Then I see signIn and register button again + + + + + diff --git a/Quality Control/Written Reports of Tests/TestScenariosCisc3140 b/Quality Control/Written Reports of Tests/TestScenariosCisc3140 new file mode 100644 index 0000000..b7ed541 --- /dev/null +++ b/Quality Control/Written Reports of Tests/TestScenariosCisc3140 @@ -0,0 +1,88 @@ +Feature: Automated/manual test + Using cisc3140 group app developement + + Background: + Given I use dev url to navigate to login page + + + @Functional #pass scenario + Scenario: Hamburger menu expand for login page + Given user navigate to application login page + When I am not logged in to the app + Then I can see sign in and register button display + Then I can see username and password field display + + @Functional #pass scenario + Scenario: Hamburger menu hide for logged in user + Given I navigate to application login page + When I am not logged in to the app + When I type valid and to login + Then menu is in hidden state + +@Regression #pass scenario + Scenario Outline: invalid user cannot login to the app + Given I navigate to application login page + When I type valid and to login + Then error message should display for invalid user + + Examples: + | userName | password | + | ahkdahsj | jsadhjhdsjjasdja | + | 20hdjhadss | 55651/3^%$,`~* | + | &^.#-?jhadss | 1545645*sd | + | 20hdjhadss.hhd d | 12k | + + @Functional #Failed scenario + Scenario: able to like the post + Given I login to the app + When I click on like button on post + Then total like is added next to post + + @Functional #Failed scenario + Scenario: able to dislike the post + Given I login to the app + When I click on like button on post + Then total dislike is added next to post + + @Functional #Failed scenario + Scenario: able to add comments on the post + Given I login to the app + When I click on comment button on post + When I type some comments on the text field + Then I can see my comments added to the post + + @Functional #Failed scenario + Scenario: sort the post by hot or new + Given I login to the app + When I click on sort by dropdown + Then I select hot post + Then post display for hot + Then I select new post + Then post is display for new + + @EndToEnd #Failed scenario + Scenario: create a post and view the created post + Given I login to the app + When I click on create post button + And I select communities from dropdown + And I type all required field and submit + Then I can see my post on my profile + + @EndToEnd #pass scenario under condition, need to rework, i don't wanna see json output in email + Scenario: get notification on email after register + Given I login to the app + When I register for new user + And I type all required fields + And I click on register button + Then I get an email notification + + @Functional #pass scenario + Scenario: user successfully logout from the application + Given I login with valid username and password + When I click on logout button + Then I see signIn and register button again + + + + + diff --git a/README.md b/README.md index 46c4b35..e4f9b6f 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,57 @@ -# CISC 3140 - Summer 2019 Project -This is the repository for the group project in CISC 3140 class at Brooklyn College. +# CISC 3140 - Summer 2019 Project [![Build Status](https://travis-ci.org/DataMascara/cisc3140-su19-project.svg?branch=master)](https://travis-ci.org/DataMascara/cisc3140-su19-project) +This is the repository for the group project in CISC 3140 Summer Session 2 2019 class at Brooklyn College. ## UnderDogs - UnderDogs is an information hub for Brooklyn College Computer Science students and faculty. Users can share original content, ask for assistance from other students, find collaborators, and have discussions across an array of curated communities. -## Team-Specific ReadMe -- [Product Team README](https://github.com/DataMascara/cisc3140-su19-project/blob/master/product/README.md) -- Backend -- ect. - -# Setup - -## Installation - -Base-requirements: Python3, Flask Web Framework - -## Installing dependencies from the `requirements.txt` file. - -- To install dependencies from the `requirements.txt` file. - `pip3 install -r requirements.txt` -- When new Python libraries are required, update the `requirements.txt` file using the command. - `pip3 freeze > requirements.txt` and push the file to Github. (or `pip` instead of `pip3` - -## Running - -- **NOTE:** MinimalAPI functionality is currently implemented, with no VIEW/connecting link to the front end. -- Alpha release will be served on a server soon so that features can be continuously implemented -- Navigate to the `app/` folder and execute `python main.py` or `python3 main.py` (depending on your setup) -- Use postman ([https://www.getpostman.com/](https://www.getpostman.com/)) to test the API. -- Debug user that already exists is :chalshaff12 (it returns their full record) - Currently, the API is just working in some cases and not linked to a view page - yet - - Server hosting for live demo is coming soon. - -## Try a GET Request - -First, make sure you have the API running and you note down the url ie `127.0.0.0:5000` - -- Open Postman and go to the header tab and your header Content-Type to "application/json" -- Go to the "Body" tab and check the "raw" and "JSON(application/json) options under that tab -- Now put `{"user":"chalshaff12"}` into the raw body (if chalshaff12 exists, so you should get a response that indicates that ) -- Set the request to GET and the URL `http://YOURLOCALHOSTURL:5000/user` - - TADA! You should see a json response with that user's information in the response body below with a status of 200! - - Currently looks like this, but will be cleaned up for easy data getting. -``` -{ - "users": [ - { - "avatarUrl": null, - "dateCreated": "2019-07-25 23:46:14", - "dateModified": null, - "email": "chalshaff12@gmail.com", - "first": "Michal", - "isActive": 1, - "last": "Shaffer", - "password": "hashedpassword", - "userid": 246815, - "username": "chalshaff12" - } - ] -} -``` - -### Test on a user that doesn't exist - -- Follow the above steps but put `{"user":"notrealuser13"}` into the raw body (notrealuser13 does NOT exist, so you should get a response that indicates that) - TADA! You should see `{"error": "User Not found!"}` in the response body below with a status of 404! +## Alpha Site : [https://bc-app-class.herokuapp.com/](https://bc-app-class.herokuapp.com/) +## Launch Form/Feedback : [https://forms.gle/DWKj28iPHTBTwDvK8](https://forms.gle/DWKj28iPHTBTwDvK8) +## Setup +### Installation +- [Python3](https://www.python.org/downloads/) +- Flask Web Framework (`pip3 install flask`) + +### Requirements +- To install dependencies from the `requirements.txt` file: +```pip3 install -r requirements.txt``` +- When new Python libraries are required, update the `requirements.txt` file using the command and push the file to Github. +```pip3 freeze > requirements.txt``` + +## Deployment +### Running +***NOTE:** API connectivity is implemented. Please be careful when editting files as some files are necessary in order to keep the connection running.* + +- Alpha release will be served on a server soon so that features can be continuously implemented. +- Navigate to the `/app` folder and execute `python3 app.py` + +## Usage +### Notes +- Make sure that the dependencies are up to date. +- Make sure that UnderDogs website is running in your web browser. + +### Registration +*Alternatively, you can fast track to the [**Signing In**](#Login) section* + +- Open the tab on the left side of the browser +- Select the `Register` button +- Enter your registration details into the fields. + +### Login +First, make sure you have the API running and you note down the url ie `localhost:8080` + +- Open the tab on the left and enter the following information into the fields: +- Username: `username` +- Password: `password` + +## Contributing +### Before Pushing +- Please run `git fetch` in order to update your current working branch with any recent commits pushed to the repo. This will help minimize the frequency at which your old code from another file overwrites the code that was recently updated in that file. + +### Suggested Flow +The following method, known as Git Workflow, is ideally the way we should be approaching updates to the repo: +- When you are working on a new feature or issue or anything, create a new branch with: ` git checkout -b `. Essentially, the branch name tends to be a short but descriptive name of the task being done in that branch. +- When you are finished with your code, commit and push your branch to the repo using: ```git commit -am "" +git push origin ``` +- Lastly, create a pull request from your branch to the master branch, then the update is discussed and then merged through the pull request. + +This method of updating the app, known as the Git Workflow, decreases the oppourtunity for old code to rewrite new code. diff --git a/WeeklyReports&Updates/GroupMe Messages.json b/WeeklyReports&Updates/GroupMe Messages - Front End - New.json similarity index 80% rename from WeeklyReports&Updates/GroupMe Messages.json rename to WeeklyReports&Updates/GroupMe Messages - Front End - New.json index 6e9e1c1..b5269ee 100644 --- a/WeeklyReports&Updates/GroupMe Messages.json +++ b/WeeklyReports&Updates/GroupMe Messages - Front End - New.json @@ -1,4 +1,491 @@ [ + { + "attachments": [ + { + "loci": [ + [ + 0, + 12 + ], + [ + 18, + 14 + ] + ], + "type": "mentions", + "user_ids": [ + "73038172", + "73038236" + ] + } + ], + "avatar_url": "https://i.groupme.com/2464x1632.jpeg.3e7778f39c2c43f698817188ab0d4431", + "created_at": 1565858545, + "favorited_by": [], + "group_id": "51738438", + "id": "156585854528137097", + "name": "Miriam Briskman", + "sender_id": "73038271", + "sender_type": "user", + "source_guid": "a21bffd1c4b1d70cd0625356415d3e56", + "system": false, + "text": "@Isaiah Khan and @Chunhao Zheng , please take a look at the presentation and add your slides. Thank you!", + "user_id": "73038271", + "platform": "gm" + }, + { + "attachments": [], + "avatar_url": "https://i.groupme.com/2464x1632.jpeg.3e7778f39c2c43f698817188ab0d4431", + "created_at": 1565839600, + "favorited_by": [], + "group_id": "51738438", + "id": "156583960032197502", + "name": "Miriam Briskman", + "sender_id": "73038271", + "sender_type": "user", + "source_guid": "b7b2a7a4ee31872cd50438be4a1db862", + "system": false, + "text": "Guys, do not forget that the link to the presentation is https://docs.google.com/presentation/d/1fjSRKs4d32VYo8MdCyT6pzdjQPn_ZESeGfMqvJQJ62g/edit?usp=sharing", + "user_id": "73038271", + "platform": "gm" + }, + { + "attachments": [ + { + "charmap": [ + [ + 18, + 21 + ] + ], + "placeholder": "�", + "type": "emoji" + } + ], + "avatar_url": "https://i.groupme.com/2464x1632.jpeg.3e7778f39c2c43f698817188ab0d4431", + "created_at": 1565836048, + "favorited_by": [], + "group_id": "51738438", + "id": "156583604858086373", + "name": "Miriam Briskman", + "sender_id": "73038271", + "sender_type": "user", + "source_guid": "e966ead4f80f5a5188513babd1232a4f", + "system": false, + "text": "�", + "user_id": "73038271", + "platform": "gm" + }, + { + "attachments": [], + "avatar_url": "https://i.groupme.com/728x728.jpeg.d7b02260f9a64ebc8562ad0baab7677c", + "created_at": 1565836027, + "favorited_by": [], + "group_id": "51738438", + "id": "156583602732357097", + "name": "Johnny Lee", + "sender_id": "64569956", + "sender_type": "user", + "source_guid": "5E49EF5E-FE6C-4224-B1DA-DBE29B5F5947", + "system": false, + "text": "Me too, thanks!", + "user_id": "64569956", + "platform": "gm" + }, + { + "attachments": [ + { + "loci": [ + [ + 148, + 11 + ] + ], + "type": "mentions", + "user_ids": [ + "64569956" + ] + } + ], + "avatar_url": "https://i.groupme.com/2464x1632.jpeg.3e7778f39c2c43f698817188ab0d4431", + "created_at": 1565835654, + "favorited_by": [], + "group_id": "51738438", + "id": "156583565423149038", + "name": "Miriam Briskman", + "sender_id": "73038271", + "sender_type": "user", + "source_guid": "3f2eeb2dbb52584eb12857682bf78c58", + "system": false, + "text": "It seems like the slides you wrote are sufficient. They look really great and interesting! I am looking forward to hear your presentation's speech, @Johnny Lee !", + "user_id": "73038271", + "platform": "gm" + }, + { + "attachments": [], + "avatar_url": "https://i.groupme.com/728x728.jpeg.d7b02260f9a64ebc8562ad0baab7677c", + "created_at": 1565834842, + "favorited_by": [], + "group_id": "51738438", + "id": "156583484218517097", + "name": "Johnny Lee", + "sender_id": "64569956", + "sender_type": "user", + "source_guid": "411B978F-EF5F-4C65-BB5B-C6995051794B", + "system": false, + "text": "Great!I just finished my slides, you can look at it, if you want me to present more, just let me knows thanks", + "user_id": "64569956", + "platform": "gm" + }, + { + "attachments": [], + "avatar_url": "https://i.groupme.com/2464x1632.jpeg.3e7778f39c2c43f698817188ab0d4431", + "created_at": 1565833535, + "favorited_by": [], + "group_id": "51738438", + "id": "156583353516217988", + "name": "Miriam Briskman", + "sender_id": "73038271", + "sender_type": "user", + "source_guid": "44fe3480496a7bd196e3ddcfb3f907be", + "system": false, + "text": "No problem! Code is always dynamic. You can present the code that you wrote. Just when you present, explain that it is the code that you wrote initially. Thank you very much!", + "user_id": "73038271", + "platform": "gm" + }, + { + "attachments": [ + { + "loci": [ + [ + 0, + 16 + ] + ], + "type": "mentions", + "user_ids": [ + "73038271" + ] + } + ], + "avatar_url": "https://i.groupme.com/728x728.jpeg.d7b02260f9a64ebc8562ad0baab7677c", + "created_at": 1565829072, + "favorited_by": [], + "group_id": "51738438", + "id": "156582907253981716", + "name": "Johnny Lee", + "sender_id": "64569956", + "sender_type": "user", + "source_guid": "EE3B44E6-123B-4D8C-B086-37FFECCBC771", + "system": false, + "text": "@Miriam Briskman I just see the final version of the code, I saw you add the jinja in the html, it look different from my version coding. However, I will just present my version of the html and JS, and you can finalize the jinja things in closing. How it sound ? ", + "user_id": "64569956", + "platform": "gm" + }, + { + "attachments": [ + { + "loci": [ + [ + 0, + 16 + ] + ], + "type": "mentions", + "user_ids": [ + "73038271" + ] + } + ], + "avatar_url": null, + "created_at": 1565807219, + "favorited_by": [], + "group_id": "51738438", + "id": "156580721921405993", + "name": "Mg", + "sender_id": "73039282", + "sender_type": "user", + "source_guid": "7570CB34-9F28-43F1-B213-1182C8883E71", + "system": false, + "text": "@Miriam Briskman ", + "user_id": "73039282", + "platform": "gm" + }, + { + "attachments": [], + "avatar_url": null, + "created_at": 1565807215, + "favorited_by": [], + "group_id": "51738438", + "id": "156580721542551041", + "name": "Mg", + "sender_id": "73039282", + "sender_type": "user", + "source_guid": "20A345B8-0DB9-4933-BD89-0C4FDE1B7A1D", + "system": false, + "text": "Hey, I got it working okay now. Are you seeing the new issues on GitHub?", + "user_id": "73039282", + "platform": "gm" + }, + { + "attachments": [ + { + "loci": [ + [ + 7, + 3 + ] + ], + "type": "mentions", + "user_ids": [ + "73039282" + ] + } + ], + "avatar_url": "https://i.groupme.com/2464x1632.jpeg.3e7778f39c2c43f698817188ab0d4431", + "created_at": 1565745870, + "favorited_by": [], + "group_id": "51738438", + "id": "156574587045966108", + "name": "Miriam Briskman", + "sender_id": "73038271", + "sender_type": "user", + "source_guid": "9be59f6eb24fad429097996bb6d13e35", + "system": false, + "text": "Hello, @Mg . To include the second-level comments, each comment dict has to have a key called 'comments' whose value is a dictionary, which refers to the second level comments under this 1st-level. Please see the 'test.py' for the exact data structure. I believe all of this is stored inside the dict 'post' on that file. Thanks!", + "user_id": "73038271", + "platform": "gm" + }, + { + "attachments": [], + "avatar_url": null, + "created_at": 1565716085, + "favorited_by": [], + "group_id": "51738438", + "id": "156571608500261424", + "name": "Mg", + "sender_id": "73039282", + "sender_type": "user", + "source_guid": "2ED4B622-9644-449D-967E-43483936C9AC", + "system": false, + "text": " level one comments work, not level two yet ", + "user_id": "73039282", + "platform": "gm" + }, + { + "attachments": [ + { + "loci": [ + [ + 4, + 16 + ] + ], + "type": "mentions", + "user_ids": [ + "73038271" + ] + } + ], + "avatar_url": null, + "created_at": 1565716062, + "favorited_by": [], + "group_id": "51738438", + "id": "156571606294653974", + "name": "Mg", + "sender_id": "73039282", + "sender_type": "user", + "source_guid": "6BA08961-0806-4D14-8BB4-7F30B32E4F11", + "system": false, + "text": "Hey @Miriam Briskman just pushed the post page to work ", + "user_id": "73039282", + "platform": "gm" + }, + { + "attachments": [ + { + "charmap": [ + [ + 18, + 21 + ], + [ + 3, + 17 + ] + ], + "placeholder": "�", + "type": "emoji" + }, + { + "loci": [ + [ + 5, + 3 + ] + ], + "type": "mentions", + "user_ids": [ + "73039282" + ] + } + ], + "avatar_url": "https://i.groupme.com/2464x1632.jpeg.3e7778f39c2c43f698817188ab0d4431", + "created_at": 1565485093, + "favorited_by": [], + "group_id": "51738438", + "id": "156548509350539038", + "name": "Miriam Briskman", + "sender_id": "73038271", + "sender_type": "user", + "source_guid": "d63b2f2ae0b12ddeb74229aab44f77c2", + "system": false, + "text": "Ohh, @Mg ! I am so happy to hear that you witness progress. I'll be finishing uploading the remaining four templates today & tomorrow. I'll also create a short PDF with explanation of what template should each 'href' and 'action' redirect the user to. I so much thankful to you and to the entire Back End team for such an amazing work! ��", + "user_id": "73038271", + "platform": "gm" + }, + { + "attachments": [ + { + "loci": [ + [ + 0, + 16 + ] + ], + "type": "mentions", + "user_ids": [ + "73038271" + ] + } + ], + "avatar_url": null, + "created_at": 1565474725, + "favorited_by": [], + "group_id": "51738438", + "id": "156547472561246810", + "name": "Mg", + "sender_id": "73039282", + "sender_type": "user", + "source_guid": "0D2B13B9-7FDB-48FE-87F7-19E022AD7A8B", + "system": false, + "text": "@Miriam Briskman Thank you for uploading that! We’ve got a bit of progress. I just added basic login/logout sessions and a bunch of new api responses to be used in the calling_api.py. We have implemented a few of them (mainly logging in, out, adding post). We’d love it for you all to look it over, try it out, and contribute a bit/guide the templates. Ie comment on a method and put in the template/expected info you’d want rendered. I have been using your documentation thus far, and it is very helpful! These smaller guides however will speed up the integration process. Please let me know if you have any questions/if I can help ", + "user_id": "73039282", + "platform": "gm" + }, + { + "attachments": [], + "avatar_url": "https://i.groupme.com/2464x1632.jpeg.3e7778f39c2c43f698817188ab0d4431", + "created_at": 1565382812, + "favorited_by": [ + "73039282" + ], + "group_id": "51738438", + "id": "156538281278811985", + "name": "Miriam Briskman", + "sender_id": "73038271", + "sender_type": "user", + "source_guid": "349a8ed8d03f512bb0febb0e85811cd9", + "system": false, + "text": "And good job for your work on the Back End side so far! I'll copy the changes that you made so far within the templates into the templates in my PC.", + "user_id": "73038271", + "platform": "gm" + }, + { + "attachments": [ + { + "loci": [ + [ + 7, + 3 + ] + ], + "type": "mentions", + "user_ids": [ + "73039282" + ] + } + ], + "avatar_url": "https://i.groupme.com/2464x1632.jpeg.3e7778f39c2c43f698817188ab0d4431", + "created_at": 1565382619, + "favorited_by": [], + "group_id": "51738438", + "id": "156538261903730250", + "name": "Miriam Briskman", + "sender_id": "73038271", + "sender_type": "user", + "source_guid": "5bafa88421a0fe65687c9ebf16f6f633", + "system": false, + "text": "Hello, @Mg . I'll be happy to do so. Please tells me everything that I need to do! Also, the 'register.html' contains the signup form, and it was uploaded yesterday to 'templates'. Thank you so much!", + "user_id": "73038271", + "platform": "gm" + }, + { + "attachments": [], + "avatar_url": null, + "created_at": 1565359908, + "favorited_by": [], + "group_id": "51738438", + "id": "156535990864025779", + "name": "Mg", + "sender_id": "73039282", + "sender_type": "user", + "source_guid": "F88EE531-A838-4249-A564-C53C5514E25A", + "system": false, + "text": "We really need your guys’ help to try and write the calling_api.py... we are writing the methods and trying to render templates, but I need to edit many things in your html to get the logic to flow. As soon as you make a change to the templates, and update them, we will have to start over. They are small things, but it just is counter productive for me to edit it if once there’s an edit on your end, the calling_api.py will no longer work due to the backend’s need to correct for the differences. Who on your team can lead on collaborating with us to write and upkeep a common flow of how the backend connects to the front and how to front connects to the back?", + "user_id": "73039282", + "platform": "gm" + }, + { + "attachments": [], + "avatar_url": null, + "created_at": 1565358376, + "favorited_by": [], + "group_id": "51738438", + "id": "156535837632129962", + "name": "Mg", + "sender_id": "73039282", + "sender_type": "user", + "source_guid": "F23FCF24-50CE-4B84-A8B4-4502E1E5BDD5", + "system": false, + "text": "Hey, on which template is the register new account form? ", + "user_id": "73039282", + "platform": "gm" + }, + { + "attachments": [ + { + "loci": [ + [ + 0, + 3 + ], + [ + 34, + 12 + ] + ], + "type": "mentions", + "user_ids": [ + "73039282", + "73713638" + ] + } + ], + "avatar_url": "https://i.groupme.com/2464x1632.jpeg.3e7778f39c2c43f698817188ab0d4431", + "created_at": 1565316461, + "favorited_by": [], + "group_id": "51738438", + "id": "156531646160609631", + "name": "Miriam Briskman", + "sender_id": "73038271", + "sender_type": "user", + "source_guid": "a2bac06a88d201579130256bb530d278", + "system": false, + "text": "@Mg , thank you for adding Derick @Derick 3140 to the group!", + "user_id": "73038271", + "platform": "gm" + }, { "attachments": [], "avatar_url": null, @@ -1805,4 +2292,4 @@ "user_id": "64569956", "platform": "gm" } -] \ No newline at end of file +] diff --git a/WeeklyReports&Updates/Link to Front End Team's Presentation b/WeeklyReports&Updates/Link to Front End Team's Presentation new file mode 100644 index 0000000..0ab8c31 --- /dev/null +++ b/WeeklyReports&Updates/Link to Front End Team's Presentation @@ -0,0 +1,3 @@ +The following is a link to the Front End Team's Google Slides Presentation that has been shown on 08.15.2019. +https://docs.google.com/presentation/d/1fjSRKs4d32VYo8MdCyT6pzdjQPn_ZESeGfMqvJQJ62g/edit?usp=sharing +The speaker's notes contain notes about the organization of the presentation process. diff --git a/app/Template-Arguments-Guide.docx b/app/Template-Arguments-Guide.docx new file mode 100644 index 0000000..86a3dee Binary files /dev/null and b/app/Template-Arguments-Guide.docx differ diff --git a/app/app.py b/app/app.py new file mode 100644 index 0000000..7374f84 --- /dev/null +++ b/app/app.py @@ -0,0 +1,1147 @@ +from flask import Flask, render_template, request, redirect, url_for, session +import requests +import json +import urllib.request +import webbrowser +import os.path + +# Relative path to reach the templates folder +app = Flask(__name__, template_folder="templates") +# Re-gen secret before production level +app.secret_key = "test" + +# Assuming the API is running at the local ip below +api = "https://bc-api-class.herokuapp.com" +# api = "http://127.0.0.1:5000" + +@app.route("/", methods=["GET"]) +def redirect_home(): + return redirect("/home/") + +""" +-------------LOGIN------------- +""" +@app.route("/login/", methods=["POST", "GET"]) +def login_api(): + # already logged in + trending = trending_ports() + if "loggedin" in session: + return redirect("/home/") + else: + if request.method == "POST": + res = request.form + print(res) + # Grab the user and pw + username = res["username"] + password = res["password"] + api_res = requests.post( + f"{api}/login/", json={"username": username, "password": password} + ).json() + try: + # Make sure there is a user before we do anything with sessions + if api_res["user"]["username"]: + # Create session data, we can access this data in other routes + session["loggedin"] = True + # session['id'] = account['id'] + session["username"] = username + session["user"] = api_res["user"] + session["subscriptions"] = requests.get( + f"{api}/ports-for-username/", json={"username": username} + ).json()["all_subscriptions for {data_value}"] + session["votes"] = requests.get( + f"{api}/votes-for-username/", json={"username": username} + ).json()["voted_data"] + session["comment_votes"] = requests.get( + f"{api}/comment-votes-for-username/", json={"username": username} + ).json()["voted_data"] + trending = trending_ports() + session.pop("trending", None) + trending = trending_ports() + return redirect("/home/") + else: + return render_template( + "base.html", errLogIn=True, trendPorts=trending + ) + except: + return render_template( + "base.html", errLogIn=True, trendPorts=trending + ) + else: + return redirect('/home/') + + + +""" +-------------LOG-OUT------------- +""" +@app.route("/logout/") +def logout(): + session.pop("loggedin", None) + session.pop("id", None) + session.pop("username", None) + session.pop("user", None) + session.pop("subscriptions", None) + session.pop("votes", None) + session.pop("trending", None) + session.pop("comment_votes", None) + # Redirect to login page + return redirect("/home/") + +""" +-------------HOMEPAGE------------- +""" +@app.route("/home/", methods=["GET", "POST"]) +def home(): + # Use the helper method to grab "tredning ports" + trending = trending_ports() + # if loggedin home will show users subscribed posts + if "loggedin" in session: + posts = requests.get( + f"{api}/posts-from-subscribed-ports/", + json={"username": session["username"]}, + ).json() + # else will show main port + else: + posts = requests.get(f"{api}/posts-by-portname/", json={"portname": "Main"}).json() + posts['name'] = "all" + # sort by new is the default + sort = "new" + if request.method == "POST": + res = request.form + if res['sortByBtn'] == "hot": + posts['posts'].sort(key= lambda x:x["votes"], reverse=True) + sort = "hot" + # print(post) + if "loggedin" in session: + update_vote_for_post(posts) + return render_template( + "posts.html", + name="Home", + user=session["user"], + trendPorts=trending, + port=posts, sort=sort, + notifiNum = 1) + else: + return render_template( + "posts.html", + name="Log In", + trendPorts=trending, + port=posts, sort=sort + ) + +""" +-------------/PORT(aka subreddit)------------- +- Uses the url to decide what port the user wants to go to. + - So, this should +""" +@app.route("/p//", methods=["GET", "POST"]) +def portpost(portname): + port = requests.get(f"{api}/posts-by-portname/", json={"portname": portname}).json() + sort = "new" + if request.method == "POST": + res = request.form + if res['sortByBtn'] == "hot": + port['posts'].sort(key= lambda x:x["votes"], reverse=True) + sort = "hot" + print(type(port)) + trending = trending_ports() + if "loggedin" in session: + update_vote_for_post(port) + return render_template( + "posts.html", + name="p/" + portname, + user=session["user"], + trendPorts=trending, + port=port, sort=sort, notifiNum = 1 + ) + else: + return render_template( + "posts.html", + name="p/" + portname, + trendPorts=trending, + port=port, sort=sort + ) + +''' +--------POST HISTORY------ +''' +# gets user's post history +@app.route("/u//posts/", methods=["GET", "POST"]) +def my_posts(username): + trending = trending_ports() + port = requests.get(f"{api}/my-posts/", json={"username": username}).json() + if request.method == "POST": + res = request.form + if res['sortByBtn'] == "hot": + port['posts'].sort(key= lambda x:x["votes"], reverse=True) + if res['sortByBtn'] == "new": + port['posts'].sort(key=lambda x: x["dateCreated"], reverse=True) + if "loggedin" in session: + update_vote_for_post(port) + return render_template( + "posts.html", + name=username + "'s Post", + user=session["user"], + trendPorts=trending, + port=port, + notifiNum = 1 + ) + # return port + else: + return render_template( + "posts.html", + name=username + "'s Post", + trendPorts=trending, + port=port + ) + +""" +-------------SIGN-UP------------- +""" +@app.route("/signup/", methods=["POST", "GET"]) +def sign_up(): + trending = trending_ports() + # if loggedin why you signing up + if "loggedin" in session: + return redirect("/home/") + + if request.method == "POST": + # Grab the form + res = request.form + print(res) + email = res["email"] + username = res["username"] + password = res["password"] + first = res["first"] + last = res["last"] + # avatarurl = res['imageUpload'] + try: + avatarurl = res["addimage"] + except: + avatarurl = ' ' + # currently signup page has no description box + # description = res["description"] + description = "" + + api_res = requests.post( + f"{api}/signup/", + json={ + "email": email, + "password": password, + "username": username, + "first": first, + "last": last, + "avatarurl": avatarurl, + "description": description, + }, + ).json() + try: + # Try and get the new user, meaning they registered + username = api_res["user"][0]["username"] + return redirect("/home/") + except: + # Otherwise, render an error + return render_template( + "register.html", errUsernameInUse=api_res["error"], trendPorts=trending + ) + + # if this line is successful then the user is created + # Load uses helper method returns the dict of the user + # representation for local storage + session["user"] = load_user(username) + session["loggedin"] = True + # session['id'] = account['id'] + session["username"] = username + session["subscriptions"] = requests.get( + f"{api}/ports-for-username/", json={"username": username} + ).json()["all_subscriptions for {data_value}"] + session["votes"] = requests.get( + f"{api}/votes-for-username/", json={"username": username} + ).json()["voted_data"] + session["user"]["avatarUrl"] = avatarurl + print(session) + return redirect("/home/") + else: + return render_template("register.html", trendPorts=trending) + +""" +-------------NEW POST------------- +""" +@app.route("/new-post/", methods=["GET", "POST"]) +def post(): + trending = trending_ports() + # Make sure the user is logged in + if "loggedin" in session: + # If we are making a post + + if request.method == "POST": + try: + res = request.form + title = res["title"] + portname = res["communitysearch"] + text = res["text"] + print(res) + try: + print("the tried") + print() + if(len(res["postImg"] ) > 3 ): + img = res["postImg"] + else: + img = 'https://i.imgur.com/KdKU0UD.png' + except: + img = 'https://i.imgur.com/KdKU0UD.png' + # print(img) + response = requests.post( + f"{api}/newpost/", + json={ + "title": title, + "text": text, + "portname": portname, + "userId": session["user"]["userId"], + "username": session["username"], + "image":img + }, + ).json() + session["votes"] = requests.get( + f"{api}/votes-for-username/", json={"username": session['username']} + ).json()["voted_data"] + return render_template( + "postSubmitted.html", + user=session["user"], + name="What Name", + trendPorts=trending, ports=trending, postId=response["posts"][0]["postId"], notifiNum = 1 + ) + + except: + return render_template( + "writePost.html", + user=session["user"], + error="Invalid Post", + trendPorts=trending, notifiNum = 1 + ) + # If it's a GET request + else: + ports = trending_ports() + print(ports) + return render_template( + "writePost.html", user=session["user"], trendPorts=trending, ports=ports, notifiNum = 1 + ) + # If we're not logged in... + else: + return redirect("/home/") + +""" +-------------USER SUBSCRIBED POSTS------------- + - Given a user, return all the posts from the ports they are subscribed to +""" +@app.route("/subscribed-posts/", methods=["GET", "POST"]) +def subscribedposts(): + if "loggedin" in session: + trending = trending_ports() + posts = requests.get( + f"{api}/posts-from-subscribed-ports/", + json={"username": session["username"]}, + ).json() + sort = "new" + if request.method == "POST": + res = request.form + if res['sortByBtn'] == "hot": + posts['posts'].sort(key=lambda x: x["votes"], reverse=True) + sort = 'hot' + update_vote_for_post(post) + return render_template( + "posts.html", + name="Your feed", + user=session["user"], + trendPorts=trending, + port=posts, sort=sort, notifiNum = 1 + ) + else: + return redirect("/home/") + +''' +---------VOTE ON POST-------- +''' +@app.route("/vote/", methods=["POST"]) +def vote(): + if "loggedin" in session: + res = request.form + print(res) + value = res["value"] + id = res["id"] + originalValue = res["originalValue"] + type = res['type'] + if type == 'post': + response = ( + requests.post( + f"{api}/vote/", + json={ + "username": session["username"], + "value": value, + "postId": id, + "originalValue": originalValue, + }, + ).json() + )["voted_data"] + session["votes"] = response + elif type == 'comment': + response = ( + requests.post( + f"{api}/vote-comment/", + json={ + "username": session["username"], + "value": value, + "commentId": id, + "originalValue": originalValue, + }, + ).json() + )["voted_data"] + session["comment_votes"] = response + return "UPDATED" + else: + return redirect("/home/") + +@app.route("/save/", methods=["POST"]) +def save(): + if "loggedin" in session: + res = request.form + postId = res["postId"] + # Boolean + button = res["savePostBtn"] + print(res) + response = requests.post(f"{api}/save/", + json={ + "username": session["username"], + "postId": postId, + "button": button + }).json() + return "UPDATED" + else: + return redirect("/home/") + +""" +-------------PORT INDEX------------- +- Allows logged in users to brows ports +""" +@app.route("/portindex/", methods=["GET"]) +def portindex(): + trending = trending_ports() + ports = requests.get(f"{api}/allports/").json()["all_ports"] + + if "loggedin" in session: + subscribed_ports = requests.get( + f"{api}/ports-for-username/", json={"username": session["username"]} + ).json()["all_subscriptions for {data_value}"] + + # this will iterate through all the ports that existing + for port in ports: + # gets the number of members + users = requests.get( + f"{api}/users-in-port/", json={"portname": port["name"]} + ).json()["all_subscriptions for {data_value}"] + port.update({"mem": len(users)}) + # this will iterate through all the ports that the user is subscribed + for subscribed_port in subscribed_ports: + # if the ids match then the user is subscribed to the port so 'isSubscribed' + # will be set to True + if port["id"] == subscribed_port["portId"]: + # "isSubscribed" notifies the html page what + # state the button should be in + port.update({"isSubscribed": True}) + break + return render_template( + "portIndex.html", + name="Port Index", + user=session["user"], + ports=ports, + trendPorts=trending, notifiNum = 1 + ) + else: + return render_template( + "portIndex.html", name="Port Index", ports=ports, trendPorts=trending + ) + + +""" +-------------SUBSCRIBE TO PORT------------- +""" +@app.route("/subscribe/", methods=["POST"]) +def subscribe(): + if "loggedin" in session: + res = request.form + print(res) + portname = res["portname"] + username = session["username"] + # Either going be joined(you're subscribing) or Subscribed, + # meaning you want to unsubscribe + state = res["value"] + + # If you click on subscribe(you just joined the port), + if state == "Joined": + requests.post( + f"{api}/subscribe-to-port/", + json={"portname": portname, "username": username}, + ) + else: + requests.post( + f"{api}/unsubscribe-to-port/", + json={"portname": portname, "username": username}, + ) + session["subscriptions"] = requests.get( + f"{api}/ports-for-username/", json={"username": username} + ).json()["all_subscriptions for {data_value}"] + session.pop("trending", None) + # session.modified = True + print(session["subscriptions"]) + trending_ports() + return res + else: + return redirect("/home/") + +''' +--- POST --- +''' +@app.route("/post/", methods = ["POST", "GET"]) +def post_by_title(postId): + trending = trending_ports() + ##Get post by post ID + post = requests.get( + f"{api}/post-by-id/", + json={"id": postId}).json()['posts'][0] + print(post) + if "loggedin" in session: + for voted in session["votes"]: + if voted['postId'] == post['postId']: + post.update({"upOrDownvoted": voted['vote']}) + + saved = requests.get(f"{api}/saved-posts-for-username/", + json={"username": session['username']}).json()["posts"] + for saved_posts in saved: + if post['postId'] == saved_posts["postId"]: + post.update({"isSaved": True}) + try: + # Grab all the comments and reply's from ONE api call + comments_and_reps = requests.get( + f"{api}/comments-by-post/", + json={"id": postId}).json() + update_vote_for_comment(comments_and_reps) + except Exception as e: + redirect("/home/") + if(request.method == "GET"): + # If you click on subscribe(you just joined the port), + print(comments_and_reps) + return render_template('postDetails.html', user = session['user'], name = "Post", post=post, comments= comments_and_reps, trendPorts=trending, notifiNum = 1) + ## MEANING WE ARE POSTING A COMMENT + elif(request.method == "POST"): + res = request.form + print(res) + if "loggedin" in session: + # If you click on subscribe(you just joined the port) + # text, post_id, parent_id, author + text = res["commentToPostText"] + post_id = post["postId"] + author = session['username'] + try: + parent_id = res["parentId"] + except: + parent_id = "NULL" + print("we got to text") + print(author) + try: + add_comment = requests.post( + f"{api}/add-comment/", + json={"text": text, "postId":post_id, "parentId":parent_id, "author":author}).json() + print("GOT HERE TOO!") + print(add_comment) + session['comment_votes'] = requests.get( + f"{api}/comment-votes-for-username/", json={"username": session['username']} + ).json()["voted_data"] + comments_and_reps = requests.get( + f"{api}/comments-by-post/", + json={"id": postId}).json() + update_vote_for_comment(comments_and_reps) + return render_template('postDetails.html', user = session['user'], name = "Post", post=post, comments = comments_and_reps, commentSubmittedMessage = True, trendPorts=trending, notifiNum = 1) + except: + return redirect("/home/") + else: + return redirect("/home/") + +""" + ---------PROFILE-------- +""" +@app.route("/profile/", methods=["GET", "POST"]) +def profile(): + trending = trending_ports() + if "loggedin" in session: + print("In User Profile.") + #check if user visit other's profile + #receive a json with viewdUser's Name + #show viewdUser's profile if it exist. + viewedUser = {} + res = request.get_json() + try: + if 'username' in res: + if (res["username"] != session["user"]["username"]): + viewedUser = requests.get( + f"{api}/user/", json={"username": res["username"]} + ).json()['user'] + viewedUser = viewedUser[0] + else: + viewedUser = session["user"] + except: + viewedUser = session["user"] + #if user update their profile + #get the form from website, convert it to JSON + #update the description and avaterURL that user entered. + if request.method == "POST": + form = request.form.to_dict() + headers = {"Content-Type": "application/json"} + data = json.dumps( + { "username":session["user"]["username"], + "field":"description", + "value":form["descriptionTextArea"] }) + try: + response = requests.put(api + "/update/", + data=data, + headers = headers) + #update session when user update their description. + session["user"].pop("description", None) + session["user"]["description"] = form["descriptionTextArea"] + session.modified = True + print("Update description successful!") + except: + print("Error: Can't update your description.") + print(response.content) + data = json.dumps( + { "username":session["user"]["username"], + "field":"avatarUrl", + "value":form["avatarURL"] }) + try: + response = requests.put(api + "/update/", + data=data, + headers = headers) + #update session when user update their avatarURL. + session["user"].pop("avatarUrl", None) + session["user"]["avatarUrl"] = form["avatarURL"] + session.modified = True + print("Update avatarUrl successful!") + except: + print("Error: Can't update your avatarUrl.") + print(response.content) + return render_template( + "userInfo.html", + userProfile=True, + name=session["user"]["username"], + user=session["user"], + viewedUser=viewedUser, + trendPorts=trending, + notifiNum = 1 + ) + else: + print("Not loggin yet.") + return redirect("/home/") + +""" +------UPDATE----- +""" +@app.route("/update/", methods=["GET", "POST"]) +def update(): + if "loggedin" in session: + trending = trending_ports() + form = request.form.to_dict() + headers = {"Content-Type": "application/json"} + if request.method == "POST": + #get new email from request, put it in DB + if "emailSetting" in form.keys(): + print("In Account Settings: Email and Password.") + payload = json.dumps( + { + "username": session["user"]["username"], + "field": "email", + "value": form["emailSetting"], + } + ) + try: + response = requests.put(api + "/update/", + data=payload, + headers=headers) + #update session's user email + session["user"].pop("email", None) + session["user"]["email"] = form["emailSetting"] + session.modified = True + print("Update email successful!") + except: + print("Error: Can't change your email.") + print(response.content) + return render_template( + "userInfo.html", + name=session["user"]["username"], + user=session["user"], + accountSettings=True, + emailAndPassword=True, + trendPorts=trending, + notifiNum = 1 + ) + #get new password, put it into DB + elif "passwordSetting" in form.keys(): + print("In Account Settings: Email and Password.") + payload = json.dumps( + { + "username": session["user"]["username"], + "field": "password", + "value": form["passwordSetting"], + } + ) + try: + response = requests.put(api + "/update/", + data=payload, + headers=headers) + #update session's user password + session["user"].pop("password", None) + session["user"]["password"] = form["passwordSetting"] + session.modified = True + print("Update password successful!") + except: + print("Error: Can't change your password.") + print(response.content) + return render_template( + "userInfo.html", + name=session["user"]["username"], + user=session["user"], + accountSettings=True, + emailAndPassword=True, + trendPorts=trending, + notifiNum = 1 + ) + elif "notifications" in form.keys(): + print("In Account Settings: Notifications.") + #make it intentional, can't find any api to access these parameters. + session["user"]["isPostCommentNotificationsEnabled"]=True + session["user"]["isCommentReplyEnabled"]=True + session["user"]["isEmailPrivate"]=False + return render_template( + "userInfo.html", + name=session["user"]["username"], + user=session["user"], + notifications=True, + accountSettings=True, + trendPorts=trending, + notifiNum = 1 + ) + return render_template( + "userInfo.html", + name=session["user"]["username"], + user=session["user"], + accountSettings=True, + emailAndPassword=True, + trendPorts=trending, + notifiNum = 1 + ) + else: + print("In Account Settings: main page.") + return render_template( + "userInfo.html", + name=session["user"]["username"], + user=session["user"], + accountSettings=True, + emailAndPassword=True, + trendPorts=trending, + notifiNum = 1 + ) + else: + print("Not loggin yet.") + return redirect("/home/") + +""" +------DASHBOARD----- +""" +@app.route("/dashboard/", methods=["GET", "POST"]) +def dashBoard(): + if "loggedin" in session: + trending = trending_ports() + if request.method == "POST": + form = request.form.to_dict() + #if user click subscription + if "subscriptions" in form.keys(): + #get ports user subscribed + try: + res = requests.get( + f"{api}/ports-for-username/", json={"username": session["user"]["username"]} + ).json()["all_subscriptions for {data_value}"] + except: + print("Error: can't get ports user subscribed.") + user = session["user"] + user["myPorts"] = [] + users = {} + for key in res: + #see how many people subscribed the port + try: + users = requests.get( + f"{api}/users-in-port/", json={"portname": key["portName"]} + ).json()["all_subscriptions for {data_value}"] + except: + print("Error: can't get ports user subscribed.") + temp = {} + temp["id"] = key["portId"] + temp["name"] = key["portName"] + temp['mem'] = len(users) + temp.update({"isSubscribed": True}) + user["myPorts"].append(temp) + print(user["myPorts"]) + return render_template( + "userInfo.html", + dashboard=True, + subscrptions=True, + name=session["user"]["username"], + user=user, + viewedUser=session["user"], + trendPorts=trending, + notifiNum = 1 + ) + #show user's comments + elif "comments" in form.keys(): + + try: + res = requests.get( + f"{api}/comments-by-user/", json={"username": session["user"]["username"]} + ).json() + print(res) + except: + print("Error: can't get user's comments.") + print("In Dashboard Comments.") + user = session["user"] + user["myComments"] = [] + #get the user's comments + for key in res['comments']: + #get where comment post and port's info + # Need a better way to do this, to many API calls + # Maybe add a API endpoint to get all post's with info from one response instead... + postInfo = {} + print(key) + # try: + # postInfo = requests.get( + # f"{api}/post-by-id/", json={"id": key['postId']} + # ).json()['posts'][0] + # except: + # print("Error: can't get post and port info.") + print(postInfo) + temp = {} + temp["dateCreated"] = key["dateCreated"] + temp["totalVotes"] = key["votes"] + temp["text"] = key["commentText"] + # temp["portname"] = postInfo["portName"] + # temp["postname"] = postInfo["postTitle"] + temp["postId"] = key['postId'] + user["myComments"].append(temp) + print("In Dashboard comments.") + return render_template( + "userInfo.html", + dashboard=True, + comments=True, + name=session["user"]["username"], + user=user, + viewedUser=session["user"], + trendPorts=trending, + notifiNum = 1 + ) + #show user's saved posts. + elif "savedPosts" in form.keys(): + posts = requests.get(f"{api}/saved-posts-for-username/", json={"username": session["user"]["username"]}).json() + print(posts) + user = session["user"] + user["savedPosts"] = [] + ##For now sends User's post's as saved posts.. + for post in posts["posts"]: + temp = {} + temp["postId"] = post["postId"] + temp["totalVotes"] = post["votes"] + temp["portname"] = post["portName"] + temp["title"] = post["postTitle"] + temp["text"] = post["postText"] + temp["dateCreated"] = post["dateCreated"] + temp["avatarUrl"] = post["image"] + user["savedPosts"].append(temp) + print("In Dashboard savedPosts.") + return render_template( + "userInfo.html", + dashboard=True, + savedPosts=True, + name=session["user"]["username"], + user=user, + viewedUser=session["user"], + trendPorts=trending, + notifiNum = 1 + ) + #show user's posts + elif "myPosts" in form.keys(): + print("In Dashboard myPosts.") + try: + posts = requests.get(f"{api}/my-posts/", + json={"username": session["user"]["username"]} + ).json() + except: + print("Error: Can't get user's posts.") + user = session["user"] + user["myPosts"] = [] + for post in posts["posts"]: + temp = {} + temp["postId"] = post["postId"] + temp["totalVotes"] = post["votes"] + temp["portname"] = post["portName"] + temp["title"] = post["postTitle"] + temp["text"] = post["postText"] + temp["dateCreated"] = post["dateCreated"] + temp["commentNum"] = 3 + temp["imageUrl"] = post["image"] + user["myPosts"].append(temp) + return render_template( + "userInfo.html", + name=session["user"]["username"], + trendPorts=trending, + user=user, + dashboard=True, + myPosts=True, + notifiNum = 1 + ) + #Default Dashboard + try: + res = requests.get( + f"{api}/ports-for-username/", json={"username": session["user"]["username"]} + ).json()["all_subscriptions for {data_value}"] + except: + print("Error: can't get ports user subscribed.") + user = session["user"] + user["myPorts"] = [] + users = {} + for key in res: + #see how many people subscribed the port + try: + users = requests.get( + f"{api}/users-in-port/", json={"portname": key["portName"]} + ).json()["all_subscriptions for {data_value}"] + except: + print("Error: can't get ports user subscribed.") + temp = {} + temp["id"] = key["portId"] + temp["name"] = key["portName"] + temp['mem'] = len(users) + temp.update({"isSubscribed": True}) + user["myPorts"].append(temp) + print(user["myPorts"]) + print("In Dashboard main page.") + return render_template( + "userInfo.html", + dashboard=True, + user=session["user"], + name=session["user"]["username"], + subscrptions=True, + trendPorts=trending, + notifiNum = 1 + ) + else: + print("Not loggin yet.") + return redirect("/home/") + +""" +------OUR TEAM PAGE----- +""" +@app.route("/ourteam/") +def ourteam(): + trending = trending_ports() + if "loggedin" in session: + return render_template( + "genLinks.html", user=session["user"], about=True, trendPorts=trending, notifiNum = 1 + ) + else: + return render_template("genLinks.html", about=True, trendPorts=trending) + +""" +------CONTACT PAGE----- +""" +@app.route("/contact/") +def contact(): + trending = trending_ports() + if "loggedin" in session: + return render_template( + "genLinks.html", user=session["user"], contact=True, trendPorts=trending, notifiNum = 1 + ) + else: + return render_template("genLinks.html", contact=True, trendPorts=trending) + +""" +------TERMS PAGE----- +""" +@app.route("/terms/") +def terms(): + trending = trending_ports() + if "loggedin" in session: + return render_template( + "genLinks.html", user=session["user"], terms=True, trendPorts=trending, notifiNum = 1 + ) + else: + return render_template("genLinks.html", terms=True, trendPorts=trending) + +""" +------NEWS FEED----- +""" +@app.route("/newsfeed/") +def hello9(): + user = session["user"] + trending = trending_ports() + if 'loggedin' in session: + return render_template("posts.html", name="Main - UnderDogs", trendPorts=trending, port="Main", user = user, notifiNum = 1) + else: + return render_template("posts.html", name="Main - UnderDogs", trendPorts=trending, port="Main") + + +""" +------FORGOTPW----- +""" +@app.route("/forgot/") +def forgot(): + trending = trending_ports() + return render_template('noPasswordReminders.html', name = "Bla", trendPorts = trending) + + + +@app.route("/Regist_Pending/") +def pending(): + trending = trending_ports() + return render_template( + "genLinks.html", name = "Registration Pending", user=user, trendPorts=trending + ) + + + +@app.route('/search/', methods= ["POST"]) +def search(): + user = session["user"] + trending = trending_ports() + return render_template('_404Error.html', name = "404", trendPorts = trending, user = user, notifiNum = 1) + + +""" +**** App of the Month Registration Form: **** +""" + +@app.route('/app-of-the-month-register/') +def appOfTheMonth(): + if 'loggedin' in session: + user = session["user"] + trending = trending_ports() + return render_template('appOfTheMonthRegister.html', name = "App Registration", trendPorts = trending, user = user, notifiNum = 1) + else: + return redirect('/home/') + +@app.route('/app-registration-form-submitted/', methods=['GET', 'POST']) +def appOfTheMonthFormSubmitted (): + if 'loggedin' in session and request.method == 'POST': + user = session["user"] + trending = trending_ports() + theForm = request.form # Holds the dictionary of the form. Has 5 keys: 'first', 'last', 'email', 'appname' and 'addimage'. + # ---> Back End code to retrieve info from form and process it. + return render_template('appSubmitted.html', name = "App Submitted!", trendPorts = trending, user = user, notifiNum = 1) + else: + return redirect('/home/') + +""" +**** Notification UI: **** +""" + +@app.route('/notifications/', methods=["POST", "GET"]) +def notificationsFunc (): + if 'loggedin' in session: + user = session["user"] + trending = trending_ports() + # Example of what the 'notifications' List shall look like: + notifications = [{'author': "markkduke", + 'postId': 171, + 'postTitle': "Shall We Sit in the Pizza, or Take the Restaurant Away?", + 'dateCreated': "2019-08-16 13:45:07", + 'commentText': "No"}, + {'author': "mary060196", + 'postId': 229, + 'yourCommentsText': "bla\nbla\nbla", + 'dateCreated': "2019-08-18 04:39:04", + 'commentText': "bla\n\nbla\n\nbla (ENTER hit twice in-between each)"}] + # ---> Back End code to retrieve info from form and process it. + return render_template('notifications.html', + name = "Notifications", + trendPorts = trending, + user = user, + notifiNum = 0, + notifications = notifications) + else: + return redirect('/home/') + + +''' +----HELPER FUNCTIONS--- +''' + +# helper function to get "trending posts" +# WIll do this by just getting three three random ports +def trending_ports(): + try: + # tries to return trending ports + # will only fail if session['trending'] hasn't been initialized + # which will usually be when a user first comes to the site + return session['trending'] + except: + # will only occur when a user first comes to the site or a user logs in or subscribes + print("GOTE HERE") + ports = requests.get(f"{api}/allports/").json()['all_ports'] + for port in ports: + users = requests.get( + f"{api}/users-in-port/", json={"portname": port["name"]} + ).json()["all_subscriptions for {data_value}"] + port.update({"mem": len(users)}) + if "loggedin" in session: + for subscribe_ports in session['subscriptions']: + if port['id'] == subscribe_ports['portId']: + port.update({"isSubscribed": True}) + break + ports.sort(key=lambda x: x["mem"], reverse=True) + session['trending'] = ports[:5] + return session['trending'] + +def update_vote_for_post(port): + if "loggedin" in session: + try: + for posts in port["posts"]: + for votes in session["votes"]: + if posts["postId"] == votes["postId"]: + # print(votes["vote"]) + posts.update({"upOrDownvoted": votes["vote"]}) + break + return port + except: + + return redirect('/home/') + else: + return None + +def update_vote_for_comment(comments_and_reps): + if "loggedin" in session: + try: + for votes in session['comment_votes']: + for comments in comments_and_reps["comments"]: + if comments['commentId'] == votes['postId']: + comments.update({"upOrDownvoted": votes['vote']}) + for replies in comments_and_reps["replies"]: + if replies['commentId'] == votes['postId']: + replies.update({"upOrDownvoted": votes['vote']}) + except: + return redirect('/home/') + else: + return None + +def load_user(username): + user = (requests.get(f"{api}/user", json={"username": username}).json())["user"][0] + print(user) + return user + + +if __name__ == "__main__": + webbrowser.open_new("localhost:8080") + app.run("localhost", 8080, debug=True) diff --git a/app/calling_api.py b/app/calling_api.py deleted file mode 100644 index 3fe6329..0000000 --- a/app/calling_api.py +++ /dev/null @@ -1,478 +0,0 @@ -from flask import Flask, render_template, request, redirect, url_for, session -import requests -import json -import urllib.request -import webbrowser - -# Example calling the API from another python file - -# Relative path to reach the templates folder -app = Flask(__name__, template_folder="templates") -app.secret_key = "test" - -# Assuming the API is running at the local ip below -api = "https://bc-api-class.herokuapp.com/" - - -@app.route("/", methods=["GET"]) -def redirect_home(): - if "loggedin" in session: - return redirect("/home/") - return redirect("/login/") - - -""" --------------LOGIN------------- -""" -@app.route("/login/", methods=["POST", "GET"]) -def login_api(): - # already logged in - trending = trending_ports()["all_ports"] - if "loggedin" in session: - return redirect("/home/") - else: - if request.method == "POST": - res = request.form - print(res) - # Grab the user and pw - username = res["username"] - password = res["password"] - api_res = requests.post( - f"{api}/login/", - json={"username": username, "password": password} - ).json() - try: - # Make sure there is a user before we do anything with sessions - if api_res["user"]["username"]: - session["user"] = api_res["user"] - # Create session data, we can access this data in other routes - session["loggedin"] = True - # session['id'] = account['id'] - session["username"] = username - session["user"] = api_res["user"] - return redirect("/home/") - return render_template( - "base.html", title="Logged In", user=session["user"] - ) - else: - return render_template( - "base.html", title="", errLogIn=True, trendPorts=trending - ) - except: - return render_template( - "base.html", title="", errLogIn=True, trendPorts=trending - ) - else: - return render_template( - "base.html", title="Please Log in", trendPorts=trending - ) - -""" --------------LOG-OUT------------- -""" -@app.route("/logout/") -def logout(): - session.pop("loggedin", None) - session.pop("id", None) - session.pop("username", None) - session.pop("user", None) - # Redirect to login page - return redirect("/login/") - -""" --------------HOMEPAGE------------- -""" -@app.route("/home/", methods=["GET"]) -def home(): - # Use the helper method to grab "tredning ports" - trending = trending_ports()["all_ports"] - port = requests.get(f"{api}/posts-by-portname/", json={"portname": "Main"}).json() - if "loggedin" in session: - return render_template( - "posts.html", - name="Home", - user=session["user"], - trendPorts=trending, - port=port, - search="My First Search!", - ) - else: - return render_template( - "posts.html", - name="Log In", - trendPorts=None, - port=None, - search="My First Search!", - ) - - -""" --------------/PORT(aka subreddit)------------- -- Uses the url to decide what port the user wants to go to. - - So, this should -""" -@app.route("/p//", methods=["GET"]) -def portpost(portname): - port = requests.get(f"{api}/posts-by-portname/", - json={"portname": portname}).json() - print(type(port)) - trending = trending_ports()["all_ports"] - if "loggedin" in session: - return render_template( - "posts.html", - name="p/" + portname, - user=session["user"], - trendPorts=trending, - port=port, - search="My First Search!", - ) - else: - return render_template( - "posts.html", - name="p/" + portname, - trendPorts=trending, - port=port, - search="My First Search!", - ) - - -# gets user's post history -@app.route("/u//posts/", methods=["GET"]) -def my_posts(username): - trending = trending_ports()["all_ports"] - port = requests.get(f"{api}/my-posts/", - json={"username": username}).json() - if "loggedin" in session: - return render_template( - "posts.html", - name=username + "'s Post", - user=session["user"], - trendPorts=trending, - port=port, - search="My First Search!", - ) - # return port - else: - return render_template( - "posts.html", - name=username + "'s Post", - trendPorts=trending, - port=port, - search="My First Search!", - ) - - """ --------------SIGN-UP------------- -""" -@app.route("/signup/", methods=["POST", "GET"]) -def sign_up(): - trending = trending_ports()["all_ports"] - # if loggedin why you signing up - if "loggedin" in session: - return redirect("/home/") - - if request.method == "POST": - # Grab the form - res = request.form - print(res) - email = res["email"] - username = res["username"] - password = res["password"] - first = res["first"] - last = res["last"] - # avatarurl = res['imageUpload'] - avatarurl = "" - # currently signup page has no description box - # description = res["description"] - description = "" - - api_res = requests.post( - f"{api}/signup/", - json={ - "email": email, - "password": password, - "username": username, - "first": first, - "last": last, - "avatarurl": avatarurl, - "description": description, - }, - ).json() - try: - # Try and get the new user, meaning they registered - username = api_res["user"][0]["username"] - except: - # Otherwise, render an error - return render_template( - "register.html", errUsernameInUse=api_res["error"], trendPorts=trending - ) - - # if this line is successful then the user is created - # Load uses helper method returns the dict of the user - # representation for local storage - session["user"] = load_user(username) - session["loggedin"] = True - # session['id'] = account['id'] - session["username"] = username - redirect("/home/") - return render_template( - "base.html", name="Bla", user=session["user"], trendPorts=trending - ) - else: - return render_template("register.html", trendPorts=trending) - - -""" --------------NEW POST------------- -""" -@app.route("/new-post/", methods=["GET", "POST"]) -def post(): - trending = trending_ports()["all_ports"] - # Make sure the user is logged in - - if "loggedin" in session: - # If we are making a post - - if request.method == "POST": - try: - res = request.form - title = res["title"] - portname = res["portname"] - text = res["text"] - response = requests.post( - f"{api}/newpost/", - json={ - "title": title, - "text": text, - "portname": portname, - "userId": session["user"]["userId"], - "username": session["username"], - }, - ).json() - trending = trending_ports()["all_ports"] - return render_template( - "postSubmitted.html", - user=session["user"], - name="What Name", - trendPorts=trending, - ) - - except: - return render_template( - "writePost.html", - user=session["user"], - error="Invalid Post", - trendPorts=trending, - ) - # If the post fails, try again - else: - return render_template( - "writePost.html", user=session["user"], trendPorts=trending - ) - - else: - return redirect("/login/") - -""" --------------USER SUBSCRIBED POSTS------------- - - Given a user, return all the posts from the ports they are subscribed to -""" -@app.route("/subscribed-posts/", methods=["GET"]) -def subscribedposts(): - if "loggedin" in session: - trending = trending_ports()["all_ports"] - post = requests.get( - f"{api}/posts-from-subscribed-ports/", - json={"username": session["username"]}, - ).json() - return render_template( - "posts.html", - name="Your feed", - user=session["user"], - trendPorts=trending, - port=post, - search="My First Search!", - ) - - return post - else: - return redirect("/login/") - -""" --------------PORT INDEX------------- -- Allows logged in users to brows ports -""" -@app.route("/portindex/", methods=["GET"]) -def portindex(): - trending = trending_ports()["all_ports"] - ports = requests.get(f"{api}/allports/").json()["all_ports"] - - if "loggedin" in session: - subscribed_ports = requests.get( - f"{api}/ports-for-username/", json={"username": session["username"]} - ).json()["all_subscriptions for {data_value}"] - - # this will iterate through all the ports that existing - for p in ports: - # this will iterate through all the ports that the user is subscribed - for sp in subscribed_ports: - # if the ids match then the user is subscribed to the port so 'isSubscribed' - # will be set to True - if p["id"] == sp["portId"]: - # "isSubscribed" notifies the html page what - # state the button should be in - p.update({"isSubscribed": True}) - return render_template( - "portIndex.html", - name="Port Index", - user=session["user"], - ports=ports, - trendPorts=trending, - ) - else: - return render_template( - "portIndex.html", name="Port Index", ports=ports, trendPorts=trending - ) - -""" --------------SUBSCRIBE TO PORT------------- -""" -@app.route("/subscribe/", methods=["POST"]) -def subscribe(): - if "loggedin" in session: - res = request.form - portname = res["portname"] - username = session["username"] - # Either going be joined(you're subscribing) or Subscribed, - # meaning you want to unsubscribe - state = res["value"] - - # If you click on subscribe(you just joined the port), - if state == "Joined": - requests.post( - f"{api}/subscribe-to-port/", - json={"portname": portname, "username": username}, - ) - else: - requests.post( - f"{api}/unsubscribe-to-port/", - json={"portname": portname, "username": username}, - ) - return res - else: - return redirect("/login/") -''' - ------PROFILE----- -''' -@app.route("/profile/") -def profile(): - trending = trending_ports()["all_ports"] - if "loggedin" in session: - print("hello") - return render_template( - "userInfo.html", userProfile = True, user=session["user"], - viewedUser= session["user"], trendPorts=trending) - else: - return redirect('/login/') - -@app.route("/update/", methods=["GET", "POST"]) -def update(): - if "loggedin" in session: - - form = request.form - form = dict(form) - - if request.method == "POST": - - if 'emailSetting' in form.keys(): - - payload = { "username":session["user"]["username"], "field":"email", "value":form["emailSetting"] } - - response = requests.post(api + "/update/", data=payload) - print(response.content) - - return render_template("userInfo.html", user = session["user"]["username"], accountSettings = True, emailAndPassword = True) - - else: - - payload = { "username":session["user"]["username"], "field":"password", "value":form["passwordSetting"] } - - response = requests.post(api + "/update/", data=payload) - print(response.content) - - return render_template("userInfo.html", user = session["user"]["username"], accountSettings = True, emailAndPassword = True) - - return render_template("userInfo.html", user = session["user"]["username"], accountSettings = True, emailAndPassword = True) - else: - return redirect('/login/') - -@app.route("/ourteam/") -def ourteam(): - trending = trending_ports()["all_ports"] - if "loggedin" in session: - return render_template( - "genLinks.html", user=session["user"], about=True, trendPorts=trending - ) - else: - return render_template("genLinks.html", about=True, trendPorts=trending) - - -@app.route("/contact/") -def contact(): - trending = trending_ports()["all_ports"] - if "loggedin" in session: - return render_template( - "genLinks.html", user=session["user"], contact=True, trendPorts=trending - ) - else: - return render_template("genLinks.html", contact=True, trendPorts=trending) - - -@app.route("/terms/") -def terms(): - trending = trending_ports()["all_ports"] - if "loggedin" in session: - return render_template( - "genLinks.html", user=session["user"], terms=True, trendPorts=trending - ) - else: - return render_template("genLinks.html", terms=True, trendPorts=trending) - - -@app.route("/newsfeed/") -def hello9(): - trending = trending_ports()["all_ports"] - return render_template( - "posts.html", - name="Bla", - trendPorts=trending, - port="Main", - search="My First Search!", - ) - - -@app.route("/Regist_Pending/") -def pending(): - user = session["user"] - trending = trending_ports()["all_ports"] - return render_template( - "genLinks.html", name=user["first"], user=user, trendPorts=trending - ) - - -# helper function to get "trending posts" -# WIll do this by just getting three three random ports -def trending_ports(): - ports = requests.get(f"{api}/allports/") - # Add way of deciding what ports are "trending" - # Return a dictonary of the port representation - return ports.json() - - -def load_user(username): - user = (requests.get(f"{api}/user", json={"username": username}).json())["user"][0] - print(user) - return user - -if __name__ == "__main__": - app.run("localhost", 8080, debug=True) diff --git a/app/static/appOfTheMonthRequests.txt b/app/static/appOfTheMonthRequests.txt new file mode 100644 index 0000000..ad765ba --- /dev/null +++ b/app/static/appOfTheMonthRequests.txt @@ -0,0 +1,3 @@ + +First Name Last Name Email App Name Image URL +---------------------------------------------------------------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/app/static/css/stylesAppOfTheMonthRegister.css b/app/static/css/stylesAppOfTheMonthRegister.css new file mode 100644 index 0000000..8fb4a26 --- /dev/null +++ b/app/static/css/stylesAppOfTheMonthRegister.css @@ -0,0 +1,162 @@ +/* CSS Styles for the template: 'appOfTheMonthRegister.html' +Version 1.0 + 08.25.2019 + Description: Creation of file +- Front End Team +*/ + +/* Landscape Media Query */ +@media screen and (min-aspect-ratio: 13/9) +{ + + .signup-wrap{ + margin: 2em auto 2em; + width: 70%; + } + + .panel-frame{ + width: auto; + height: auto; + margin-top: 100px; + padding: 0; + border: 0; + text-align: center; + } + + .header-wrapper{ + margin-top: 12px; + margin-bottom: 12px; + } + + .panel-content{ + text-align: left; + } + + h1{ + margin-bottom: -10px; + font-size: 25px; + } + + .explanationParag{ + font-size: 12px; + } + + .required{ + color: red; + font-size: 9px; + font-weight: bold; + letter-spacing: 1px; + margin-top: 15px; + } + + input[type="text"], input[type="email"]{ + width: 90%; + padding: 12px 11px 11px 11px; + margin-top: 7.5px; + margin-bottom: 12px; + margin-right: 10px; + border: 0.5px solid #8c918d; + border-radius: 3px; + font-size: 11px; + } + + .registFormButton{ + margin-left: 0.5em; + margin-top: 20px; + padding: 7px; + border: 1px solid #8c918d; + border-radius: 3px; + text-align: center; + display: block; + border: 0; + background-color: #757575; + color: white; + font-size: 8px; + width: 80px; + letter-spacing: 0.5px; + cursor: pointer; + } + + ::placeholder{ + color: black; + } + +} /* Close Media Query */ + +/* Portrait Media Query */ +@media screen and (max-aspect-ratio: 13/9) +{ + + .signup-wrap{ + margin: auto; + } + + .panel-frame{ + width: auto; + height: auto; + margin-top: 5vw; + padding: 0; + border: 0; + text-align: center; + } + + .header-wrapper{ + margin-bottom: 3vw; + } + + .panel-content{ + text-align: center; + margin: auto; + } + + h1{ + margin-bottom: -2vw; + font-size: 8vw; + } + + .explanationParag{ + text-align: left; + font-size: 3vw; + padding-left: 2vw; + padding-right: 2vw; + } + + .required{ + color: red; + font-size: 3vw; + font-weight: bold; + letter-spacing: 0.2vw; + } + + input[type="text"], input[type="email"]{ + width: 90%; + padding: 3vw; + margin-top: 2.5vw; + margin-bottom: 2.5vw; + border: 0.5px solid #8c918d; + border-radius: 1vw; + font-size: 4vw; + } + + .registFormButton{ + margin-top: 4vw; + margin-bottom: 4vw; + padding: 3vw; + border: 1px solid #8c918d; + border-radius: 1vw; + text-align: center; + border: 0; + background-color: #757575; + color: white; + font-size: 4vw; + width: 30%; + letter-spacing: 0.2vw; + cursor: pointer; + box-shadow: 1px 1px 1px lightgrey; + } + + ::placeholder{ + color: black; + } + +} /* Close Media Query */ diff --git a/app/static/css/stylesBase.css b/app/static/css/stylesBase.css index d43084e..cc2098a 100644 --- a/app/static/css/stylesBase.css +++ b/app/static/css/stylesBase.css @@ -1,27 +1,35 @@ /* CSS Styles for Base Templates: 'baseLoggedIn.html' and 'baseLoggedOut.html' +Version 1.2 + 08.18.2019 + Description: Initial media query for portrait screens added. + +Version 1.1.5 + 08.13.2019 + Description: Style Change for the New Underdogs Logo. + +Version 1.1.4 + 08.12.2019 + Description: Flex styling for the 'outerShellForMenuLinks' class added. Inline links + screen reader accessibility issue resolved! + Version 1.1.3 08.06.2019 Description: Addition of 'outline: inherit' to classes 'a' and 'b' -Version 1.1.2 - +Version 1.1.2 08.04.2019 - Description: (1) 'copyright' class was added: 'bottom: calc(1vh + 1vw);' - - (2) 'midContainer' class was added: 'width: 60vmax; height: 90vh; overflow: auto' - (3) 'rightContainer' class: 'position' and 'left' attributes were deleted + (2) 'midContainer' class was added: 'width: 60vmax; height: 90vh; overflow: auto' + (3) 'rightContainer' class: 'position' and 'left' attributes were deleted Version 1.1.1 08.04.2019 Description: (1) 'margin-bottom' of 'forms' set to 0. - (2) 'border' of the 'text' class set to 0. + (2) 'border' of the 'text' class set to 0. Version 1.1 - 08.02.2019 - - Description: Selector 'errLogIn' added. + Description: Selector 'errLogIn' added. Version 1.0 @@ -34,577 +42,1070 @@ Version 1.0 - Front End Team */ +/* --------------------------------------------------- + MEDIA QUERY: Landscape +----------------------------------------------------- */ + /*Attributes for Left Side:*/ -body { - font-family: 'Roboto', sans-serif; - background-color: #ECECEC; - display: inline-block; - margin: 0; - padding: 0; - border: 0; - display: flex; -} - -html{ - padding: 0; - margin: 0; -} - -.leftContainer{ - display: inline-block; - margin: 0; - padding: 0; - font-size: 0px; -} - -.siteLogo{ - position: relative; - margin: calc(1.4vh + 1.4vw); - margin-right: 0; - display: inline-block; - padding: 0; - font-size: 0px; - transition: all 0.3s; -} - -.siteLogo a{ - text-decoration: none; -} - -.a{ - font-family: 'Source Code Pro'; - font-style: italic; - font-size: calc(1.8vh + 1.8vw); - color: #7B2240; - outline: inherit; -} - -.b{ - font-family: 'Source Code Pro'; - font-style: normal; - font-size: calc(2vh + 2vw); - color: #7B2240; - font-weight: bold; - outline: inherit; -} - -.logo{ - display: block; - margin-left: auto; - margin-right: auto; - width: calc(2.1vh + 2.1vw); - height: calc(2.1vh + 2.1vw); - margin-top: calc(1.5vh + 1.5vw); - margin-bottom: calc(1.5vh + 1.5vw); - border-radius: 100%; -} - -a, a:hover, a:focus { - color: inherit; - text-decoration: none; - transition: all 0.3s; -} - -.button1, .button2{ - text-align: center; - display: block; - position: absolute; - border-radius: calc(0.15vh + 0.15vw); - border: 0; - background-color: #757575; - color: white; - font-size: calc(0.43vh + 0.43vw); - width: calc(4.3vh + 4.3vw); - padding-top: calc(0.35vh + 0.35vw); - padding-bottom: calc(0.35vh + 0.35vw); - padding-left: calc(0.35vh + 0.35vw); - padding-right: calc(0.35vh + 0.35vw); - letter-spacing: calc(0.03vh + 0.03vw); - cursor: pointer; - overflow: hidden; - transition: all 1s; -} - -.button1{ - top: calc(13.8vh + 13.8vw); - left: calc(6.7vh + 6.7vw); -} - -.button2{ - top: calc(16vh + 16vw); - left: calc(6.7vh + 6.7vw); -} - -.text{ - border: 0; - width: calc(8.2vh + 8.2vw); - border-radius: calc(0.15vh + 0.15vw); - padding: calc(0.6vh + 0.6vw); - color: black; - background: #fcfcfc; - outline: none; - font-size: calc(0.58vh + 0.58vw); - margin: calc(1vh + 1vw); - margin-top: calc(0.55vh + 0.55vw); - margin-bottom: calc(0.55vh + 0.55vw); - transition: all 1s; -} - -.text::placeholder { - color: black !important; -} - -.sidebarCollapse{ - background-color: #7B2240; - padding: 0; - border: none; -} - -span, a{ - padding: 0; -} - -.username{ - font-size: calc(0.5vh + 0.5vw); - text-align: center; - text-decoration: none; - color: white; - position: relative; - top: calc(-1vh - 1vw); -} - -.profile, .dash, .settings -{ - text-align: center; - display: block; - font-size: calc(0.5vh + 0.5vw); - color: #ECECEC; - border: 0; - border-bottom: solid 1px; - border-bottom-color: #ECECEC; /* gray */ - border-bottom-width: calc(0.08vh + 0.08vw); - background-color: #863550; - padding: calc(0.4vh + 0.4vw); - margin: auto; - width: calc(6vh + 6vw); - margin-bottom: calc(0.5vh + 0.5vw); - border-top-left-radius: calc(0.3vh + 0.3vw) calc(0.3vh + 0.3vw); - border-top-right-radius: calc(0.3vh + 0.3vw) calc(0.3vh + 0.3vw); - cursor: pointer; - overflow: hidden; -} - -.signOut{ - text-align: center; - font-size: calc(0.5vh + 0.5vw); - color: #ECECEC; - margin: auto; - position: relative; - top: calc(0.5vh + 0.5vw); - text-decoration: none; -} +@media screen and (min-aspect-ratio: 13/9) { -/* --------------------------------------------------- - SIDEBAR STYLE ------------------------------------------------------ */ + body { + font-family: 'Roboto', sans-serif; + background-color: #ECECEC; + display: inline-block; + margin: 0; + padding: 0; + border: 0; + display: flex; + } + + html { + scroll-behavior: smooth; + } + + #myBtn { + display: none; + } + + a.skip, a.skip-to-content{ + left:-999px; + position:absolute; + top:auto; + width:1px; + height:1px; + overflow:hidden; + z-index:-999; + } + + html{ + padding: 0; + margin: 0; + } + + .leftContainer{ + display: inline-block; + margin: 0; + padding: 0; + font-size: 0px; + } + + .siteLogo{ + position: relative; + margin: calc(1.4vh + 1.4vw); + margin-right: 0; + display: inline-block; + padding: 0; + font-size: 0px; + transition: all 0.3s; + } + + .siteLogo a{ + text-decoration: none; + } + + .a{ + font-family: "Times New Roman", Times, serif; + font-weight: bold; + font-size: calc(2vh + 2vw); + color: #7B2240; + } + + .logo{ + display: block; + margin-left: auto; + margin-right: auto; + width: calc(2.1vh + 2.1vw); + height: calc(2.1vh + 2.1vw); + margin-top: calc(1.5vh + 1.5vw); + margin-bottom: calc(1.5vh + 1.5vw); + border-radius: 100%; + } + + a, a:hover, a:focus { + color: inherit; + text-decoration: none; + transition: all 0.3s; + } + + .button1, .button2{ + text-align: center; + display: block; + position: absolute; + border-radius: calc(0.15vh + 0.15vw); + border: 0; + background-color: #757575; + color: white; + font-size: calc(0.43vh + 0.43vw); + width: calc(4.3vh + 4.3vw); + padding-top: calc(0.35vh + 0.35vw); + padding-bottom: calc(0.35vh + 0.35vw); + padding-left: calc(0.35vh + 0.35vw); + padding-right: calc(0.35vh + 0.35vw); + letter-spacing: calc(0.03vh + 0.03vw); + cursor: pointer; + overflow: hidden; + transition: all 1s; + } + + .button1{ + top: calc(13.8vh + 13.8vw); + left: calc(6.7vh + 6.7vw); + } + + .button2{ + top: calc(16vh + 16vw); + left: calc(6.7vh + 6.7vw); + } + + .text{ + border: 0; + width: calc(8.2vh + 8.2vw); + border-radius: calc(0.15vh + 0.15vw); + padding: calc(0.6vh + 0.6vw); + color: black; + background: #fcfcfc; + font-size: calc(0.58vh + 0.58vw); + margin: calc(1vh + 1vw); + margin-top: calc(0.55vh + 0.55vw); + margin-bottom: calc(0.55vh + 0.55vw); + transition: all 1s; + } + + .text::placeholder { + color: black !important; + } + + .sidebarCollapse{ + background-color: #7B2240; + padding: 0; + border: none; + } + + span, a{ + padding: 0; + } + + .username{ + font-size: calc(0.5vh + 0.5vw); + text-align: center; + text-decoration: none; + color: white; + position: relative; + top: calc(-1vh - 1vw); + } + + .profile, .dash, .settings, .notifications + { + text-align: center; + display: block; + font-size: calc(0.5vh + 0.5vw); + color: #ECECEC; + border: 0; + border-bottom: solid 1px; + border-bottom-color: #ECECEC; /* gray */ + border-bottom-width: calc(0.08vh + 0.08vw); + background-color: #863550; + padding: calc(0.4vh + 0.4vw); + margin: auto; + width: calc(6vh + 6vw); + margin-bottom: calc(0.5vh + 0.5vw); + border-top-left-radius: calc(0.3vh + 0.3vw) calc(0.3vh + 0.3vw); + border-top-right-radius: calc(0.3vh + 0.3vw) calc(0.3vh + 0.3vw); + cursor: pointer; + overflow: hidden; + } + + .signOut{ + text-align: center; + font-size: calc(0.5vh + 0.5vw); + color: #ECECEC; + margin: auto; + position: relative; + top: calc(0.5vh + 0.5vw); + text-decoration: none; + } + + /* --------------------------------------------------- + SIDEBAR STYLE + ----------------------------------------------------- */ + + .hamMenu{ + width: calc(1.7vh + 1.7vw); + height: calc(1vh + 1vw); + display: block; + padding: 0; + margin: 0; + user-drag: none; + user-select: none; + -moz-user-select: none; + -webkit-user-drag: none; + -webkit-user-select: none; + -ms-user-select: none; + outline: inherit; + font-size: 0; + } + + .outerShellForMenuLinks{ + display: flex; + position: absolute; + bottom: 0; + bottom: calc(1.7vh + 1.7vw); + left: calc(4vh + 4vw); + justify-content: space-around; + } -.hamMenu{ - width: calc(1.7vh + 1.7vw); - height: calc(1vh + 1vw); - display: block; - padding: 0; - margin: 0; - user-drag: none; - user-select: none; - -moz-user-select: none; - -webkit-user-drag: none; - -webkit-user-select: none; - -ms-user-select: none; - outline: inherit; - font-size: 0; -} - -.moreInfo{ - position: absolute; - bottom: 0; - bottom: calc(1.7vh + 1.7vw); - left: calc(4vh + 4vw); -} - -.w2{ - font-size: calc(0.45vh + 0.45vw); -} - -.w1{ - margin-left: calc(-1.3vh - 1.3vw); - margin-right: calc(3.5vh + 3.5vw); - font-size: calc(0.45vh + 0.45vw); -} - -.sidebar { - padding: 0; - padding-top: calc(0.8vh + 0.8vw); - margin: 0; - width: calc(13vh + 13vw); - height: 80vh; - background: #7B2240; - color: #fff; - transition: all 0.3s; - text-align: center; - border-bottom-right-radius: calc(1.8vh + 1.8vw) calc(1.7vh + 1.7vw); - border-top-right-radius: calc(1.8vh + 1.8vw) calc(1.7vh + 1.7vw); - position: relative; - display: block; + .w2{ + font-size: calc(0.45vh + 0.45vw); + } + + .w1{ + margin-left: calc(-1.3vh - 1.3vw); + margin-right: calc(3.5vh + 3.5vw); + font-size: calc(0.45vh + 0.45vw); + } + + .sidebar { + padding: 0; + padding-top: calc(0.8vh + 0.8vw); + margin: 0; + width: calc(13vh + 13vw); + height: 80vh; + background: #7B2240; + color: #fff; + transition: all 0.3s !important; + -webkit-transition: all 0.3s !important; + text-align: center; + border-bottom-right-radius: calc(1.8vh + 1.8vw) calc(1.7vh + 1.7vw); + border-top-right-radius: calc(1.8vh + 1.8vw) calc(1.7vh + 1.7vw); + position: relative; + display: block; + } + + .sidebar.active { + width: 7vw; + text-align: center; + } + + .sidebar.active form, .sidebar.active .passAndRegistr, .sidebar.active .moreInfo, .sidebar.active p, .sidebar.active a{ + display: none; + } + + .forgotPass{ + position: absolute; + text-decoration: none; + display: block; + text-align: left; + font-size: calc(0.45vh + 0.45vw); + left: calc(2vh + 2vw); + top: calc(14.1vh + 14.1vw); + } + + .notAMem{ + position: absolute; + text-align: left; + top: calc(15.85vh + 15.85vw); + left: calc(2.2vh + 2.2vw); + display: block; + font-size: calc(0.45vh + 0.45vw); + } + + .errLogIn{ + font-size: calc(0.75vh + 0.75vw); + position: absolute; + top: calc(5.8vh + 5.8vw); + color: red; + margin: auto; + width: calc(13vh + 13vw); + } -} - -.sidebar.active { - width: 7vw; - text-align: center; -} - -.sidebar.active form, .sidebar.active .passAndRegistr, .sidebar.active .moreInfo, .sidebar.active p, .sidebar.active a{ - display: none; -} - -.forgotPass{ - position: absolute; - text-decoration: none; - display: block; - text-align: left; - font-size: calc(0.45vh + 0.45vw); - left: calc(2vh + 2vw); - top: calc(14.1vh + 14.1vw); -} - -.notAMem{ - position: absolute; - text-align: left; - top: calc(15.85vh + 15.85vw); - left: calc(2.2vh + 2.2vw); - display: block; - font-size: calc(0.45vh + 0.45vw); -} - -.errLogIn{ - font-size: calc(0.75vh + 0.75vw); - position: absolute; - top: calc(5.8vh + 5.8vw); - color: red; - margin: auto; - width: calc(13vh + 13vw); -} + /* Attributes for Middle Container: */ + + .midContainer + { + float: right; + width: 60vmax; + height: 90vh; + overflow: auto; + } + + form + { + margin-bottom: 0; + } + + /* Attributes for Right Side:*/ + + .portIndex + { + background-color: rgb(227,227,227); + width: 71%; + height: 100vh; + margin-top: 25%; + margin-left: 1%; + } + + .rightContainer + { + font-family: 'Roboto', Sans-Serif; + width: calc(20vh + 20vw); + height: 100vh; + transition: all 0.3s; + background-color: #E3E3E3; + top: 0px; + overflow-y: auto; + display: inline-block; + margin-left: 0; + } + + .searchform + { + position: relative; + margin: 0; + padding: 0; + font-size: 0px; + } + + .search + { + margin-top: calc(1.9vh + 1.9vw); + margin-left: calc(1.3vh + 1.3vw); + font-family: 'Roboto', Sans-Serif; + font-size: calc(0.6vh + 0.6vw); + padding: calc(0.5vh + 0.5vw); + color: black; + border-radius: calc(0.15vh + 0.15vw); + border-width: calc(0.05vh + 0.05vw); + border-style: solid; + border-color: rgb(192,192,192); + border-image: none; + width: 83%; + } + + .search::placeholder + { + color: black !important; + } + + .viewPortIndex + { + font-family: 'Roboto', sans-serif; + padding: calc(0.5vh + 0.5vw); + font-size: calc(0.65vh + 0.65vw); + font-weight: bold; + margin: auto; + width: 65%; + background-color: rgb(222, 211, 215); + color: #7B2240; /* maroon */ + text-align: center; + letter-spacing: calc(0.05vh + 0.05vw); + border: 0; + border-bottom: solid 1px; + border-bottom-color: #7B2240; /* maroon */ + border-bottom-width: calc(0.08vh + 0.08vw); + display: flex; + justify-content: center; + margin-top: 12%; + word-spacing: calc(0.1vh + 0.1vw); + } + + .viewPortIndex:hover + { + background-color: lightgray !important; + cursor: pointer !important; + -webkit-transition: all 0.25s !important; /* Safari */ + transition: all 0.25s !important; + } + + .trending + { + font-size: calc(0.65vh + 0.65vw); + margin: auto; + width: 65%; + background-color: rgb(222, 211, 215); + border: 0; + border-radius: calc(0.2vh + 0.2vw); + box-shadow: 1px 1px 2px lightgray; + margin-top: 2.5%; + overflow-x: hidden; + overflow-y: auto; + } + + .trendingTitle + { + font-weight: bold; + padding-top: calc(0.65vh + 0.65vw); + padding-left: calc(0.8vh + 0.8vw); + color: #7B2240; /* maroon */ + margin-bottom: calc(0.5vh + 0.5vw); + margin-top: 0px; + } + + .trendingName, .trendingMem + { + color: rgb(80, 80, 80); + margin-top: 0px; + margin-bottom: 0px; + margin-left: calc(1.2vh + 1.2vw); + } + + .trendingName + { + font-size: calc(0.56vh + 0.56vw); + } + + .trendingMem + { + font-size: calc(0.45vh + 0.45vw); + margin-top: 0%; + margin-bottom: 8%; + } + + .membersTrending5 + { + margin-bottom: 0px; + padding-bottom: 0px; + } + + .subscribe + { + float: right; + position: relative; + top: calc(-2.0vh - 2.0vw); + left: calc(-1.2vh - 1.2vw); + border-radius: calc(0.15vh + 0.15vw); + border: 0; + background-color: rgb(117, 117, 117); + color: white; + font-size: calc(0.45vh + 0.45vw); + width: 34%; + padding-top: calc(0.3vh + 0.3vw); + padding-bottom: calc(0.3vh + 0.3vw); + padding-left: calc(0.4vh + 0.4vw); + padding-right: calc(0.4vh + 0.4vw); + letter-spacing: calc(0.03vh + 0.03vw); + cursor: pointer; + overflow: hidden; + text-align: center; + } + + .theAdYouCantRemoveThis + { + display: block; + background-color: white; + margin: auto; + width: 18vw; + font-size: 12px; + border: 0; + box-shadow: 0.5px 0px 2px lightgray, -0.5px 0px 2px lightgray, 0px 8px 8px 0px rgb(175, 175, 175); + margin-top: 16%; + margin-bottom: calc(2.5vh + 2.5vw); + overflow-x: auto; + overflow-y: auto; + border-top-right-radius: calc(0.1vh + 0.1vw); + border-bottom-right-radius: calc(0.1vh + 0.1vw); + } + + .ad + { + background-color: white; + margin: auto; + width: 96%; + height: auto; + border: solid gray 0.5px; + border-width: calc(0.05vh + 0.05vw); + margin-top: 1%; + margin-bottom: 1%; + } + + .theAdYouCantRemoveThis p + { + color: black; + font-size: calc(0.5vh + 0.5vw); + letter-spacing: calc(0.06vh + 0.06vw); + margin-left: 3%; + margin-top: 2%; + margin-bottom: 0; + } + + /* Attributes for Copyrights Div: */ + + .copyrightParag + { + font-size: calc(0.65vh + 0.65vw); + text-align: center; + margin: 0; + padding: 0; + } + + .copyright + { + position: absolute; + bottom: calc(1vh + 1vw); + width: 58vw; + display: inline-block; + margin: 0; + padding: 0; + } + + /* Attributes for General Links: */ + + .bottomLinks + { + margin-top: 10px; + } + + .termsConds, .ourTeam, .contactUs + { + text-decoration: none; + color: #7B2240; + font-size: calc(0.45vh + 0.45vw); + display: block; + text-align: center; + } + + @keyframes blinker { + 50% { + text-shadow: 0 0 8px #FFFF00; /* Make notifications button's text glow */ + font-weight: bold; + } + } + +} /* Close Media Query */ + /* --------------------------------------------------- - MEDIAQUERIES + MEDIA QUERY: Portrait ----------------------------------------------------- */ -/*@media (max-width: 768px) { - .sidebar { - min-width: 80px; - max-width: 80px; +@media screen and (max-aspect-ratio: 13/9) { + + body { + font-family: 'Roboto', sans-serif; + background-color: #ECECEC; + display: inline-block; + margin: 0; + padding: 0; + border: 0; + display: flex; + flex-direction: column; + } + + html { + scroll-behavior: smooth; + } + + #myBtn { + display: none; + position: fixed; + bottom: 5vw; + right: 5vw; + z-index: 99; + border: solid 0.3vw white; + background-color: #7B2240; + color: white; + padding: 2vw; + border-radius: 1vw; + font-size: 5vw; + } + + a.skip{ + left:-999px; + position:absolute; + top:auto; + width:1px; + height:1px; + overflow:hidden; + z-index:-999; + } + + a.skip-to-content{ + position: relative; + text-align: center; + font-size: 4vw; + color: #7B2240; + background-color: rgb(222, 211, 215); + margin-top: 3vw; + margin-bottom: 3vw; + border: 0.3vw solid #7B2240; + } + + html{ + padding: 0; + margin: 0; + } + + .leftContainer{ + display: inline-block; + margin: 0; + padding: 0; + font-size: 0px; + } + + .siteLogo{ + margin: auto; + display: block; + margin-bottom: 3vh; + position: relative; + padding: 0; + font-size: 0px; + transition: all 0.3s; + text-align: center; + } + + .siteLogo a{ + text-decoration: none; + } + + .a{ + font-family: "Times New Roman", Times, serif; + font-weight: bold; + font-size: 10vw; + color: #7B2240; + } + + .logo{ + display: block; + margin: 0; + margin-left: auto; + margin-right: auto; + width: 10vw; + height: 10vw; + padding-top: 5vw; + padding-bottom: 5vw; + border-radius: 100%; + } + + a, a:hover, a:focus { + color: inherit; + text-decoration: none; + transition: all 0.3s; + } + + .button1, .button2{ + text-align: center; + display: block; + border-radius: 1vw; + border: 0; + background-color: #757575; + color: white; + font-size: 2vw; + width: 20%; + margin: auto; + margin-top: 2vw; + margin-bottom: 2vw; + padding-top: 2vw; + padding-bottom: 2vw; + letter-spacing: 0.2vw; + cursor: pointer; + overflow: hidden; + transition: all 1s; + } + + .text{ + border: 0; + width: 70%; + border-radius: 1vw; + padding: 3vw; + color: black; + background: #fcfcfc; + font-size: 3vw; + margin: 2vw; + transition: all 1s; + } + + .text::placeholder { + color: black; !important + } + + .sidebarCollapse{ + background-color: #7B2240; + padding: 0; + border: none; + } + + span, a{ + padding: 0; + } + + .username{ + font-size: 5vw; + text-align: center; + text-decoration: none; + color: white; + position: relative; + top: -2.5vw; + } + + .profile, .dash, .settings, .notifications{ + text-align: center; + display: block; + font-size: 3vw; + color: #ECECEC; + border: 0; + border-bottom: solid 0.5vw; + border-bottom-color: #ECECEC; /* gray */ + border-bottom-width: 0.5vw; + background-color: #863550; + padding: 3%; + margin: auto; + width: 40%; + margin-bottom: 3vw; + border-top-left-radius: 1vw; + border-top-right-radius: 1vw; + cursor: pointer; + overflow: hidden; + } + + .signOut{ + text-align: center; + font-size: 3.5vw; + color: #ECECEC; + margin: auto; + position: relative; + top: 1vw; + text-decoration: none; + } + + /* --------------------------------------------------- + SIDEBAR STYLE + ----------------------------------------------------- */ + + .hamMenu{ + width: 7vw; + height: 5vw; + display: block; + padding: 0; + margin: 0; + user-drag: none; + user-select: none; + -moz-user-select: none; + -webkit-user-drag: none; + -webkit-user-select: none; + -ms-user-select: none; + outline: inherit; + font-size: 0; + } + + .outerShellForMenuLinks{ + display: flex; + justify-content: space-evenly; text-align: center; - margin-left: -80px !important ; + padding-top: 3vh; + padding-bottom: 3vh; + } + + .w2{ + font-size: 3vw; } - a[aria-expanded="false"]::before, a[aria-expanded="true"]::before { - top: auto; - bottom: 5px; - right: 50%; - -webkit-transform: translateX(50%); - -ms-transform: translateX(50%); - transform: translateX(50%); + + .w1{ + font-size: 3vw; } + + .sidebar { + padding: 0; + padding-top: 3vh; + margin: 0; + width: 100%; + height: auto; + background: #7B2240; + color: #fff; + transition: all 0.3s !important; + -webkit-transition: all 0.3s !important; + text-align: center; + border-radius: 0; + position: relative; + display: block; + + } + .sidebar.active { - margin-left: 0 !important; + width: 100%; + height: auto; + text-align: center; } - .sidebar .sidebar-header h3, .sidebar .CTAs { + .sidebar.active form, .sidebar.active .passAndRegistr, .sidebar.active .moreInfo, .sidebar.active p, .sidebar.active a, + .sidebar.active .outerShellForMenuLinks{ display: none; } - .sidebar .sidebar-header strong { + .forgotPass{ + text-decoration: none; display: block; + text-align: center; + font-size: 3vw; } - .sidebar ul li a { - padding: 20px 10px; + .notAMem{ + text-align: center; + display: block; + font-size: 3vw; } - .sidebar ul li a span { - font-size: 0.85em; + .errLogIn{ + font-size: 3vw; + position: relative; + text-align: center; + color: red; + margin: auto; + width: 95%; + } + + /* Attributes for Middle Container: */ + + .midContainer + { + width: 100%; + height: auto; + display: inline-block; + margin: 0; + overflow: auto; + transition: all 0.3s; + -webkit-transition: all 0.3s; } - .sidebar ul li a i { - margin-right: 0; + + /* Attributes for Right Side:*/ + + .portIndex + { + background-color: rgb(227,227,227); + width: 71%; + height: 100vh; + margin-top: 25%; + margin-left: 1%; + } + + .rightContainer + { + font-family: 'Roboto', Sans-Serif; + width: 100%; + height: auto; + transition: all 0.3s; + -webkit-transition: all 0.3s; + background-color: #E3E3E3; + top: 0px; + overflow-y: auto; + display: inline-block; + margin-left: 0; + } + + .searchform + { + margin: auto; + margin-block-end: 0px; display: block; + text-align: center; } - .sidebar ul ul a { - padding: 10px !important; + .search + { + margin: auto; + margin-top: 4vh; + margin-bottom: 4vh; + font-family: 'Roboto', Sans-Serif; + font-size: 3vw; + padding: 3vw; + color: black; + border-radius: 1vw; + border-width: 0.5px; + border-style: solid; + border-color: rgb(192,192,192); + border-image: none; + width: 83%; } - .sidebar ul li a i { - font-size: 1.3em; + .search::placeholder + { + color: black; !important } - .sidebar { - margin-right: 0; + + .viewPortIndex + { + font-family: 'Roboto', sans-serif; + padding: 3vw; + font-size: 3vw; + font-weight: bold; + margin: auto; + width: 65%; + background-color: rgb(222, 211, 215); + color: #7B2240; /* maroon */ + text-align: center; + letter-spacing: 0.5vw; + border: 0; + border-bottom: solid 0.5vw; + border-bottom-color: #7B2240; /* maroon */ + border-bottom-width: 0.5vw; + display: flex; + justify-content: center; + word-spacing: 1vw; } - .sidebarCollapse span { - display: none; + + .viewPortIndex:hover + { + background-color: lightgray; !important + cursor: pointer; !important + -webkit-transition: all 0.25s; !important /* Safari */ + transition: all 0.25s; !important + } + + .trending + { + font-size: 3vw; + margin: auto; + width: 65%; + background-color: rgb(222, 211, 215); + border: 0; + border-radius: 1vw; + box-shadow: 0.5vw 0.5vw 1vw lightgray; + margin-top: 2.5%; + overflow-x: hidden; + overflow-y: auto; + } + + .trendingTitle + { + font-weight: bold; + padding-top: 3vw; + padding-left: 2vw; + color: #7B2240; /* maroon */ + margin-bottom: 3vw; + margin-top: 0; + } + + .trendingName, .trendingMem + { + color: rgb(80, 80, 80); + margin-top: 0; + margin-bottom: 0; + margin-left: 3.4vw; + } + + .trendingName + { + font-size: 3vw; + } + + .trendingMem + { + font-size: 2.5vw; + margin-top: 0%; + margin-bottom: 8%; + } + + .membersTrending5 + { + margin-bottom: 0px; + padding-bottom: 0px; + } + + .subscribe + { + float: right; + position: relative; + top: -12vw; + left: calc(-1.2vh - 1.2vw); + border-radius: 1vw; + border: 0; + background-color: rgb(117, 117, 117); + color: white; + font-size: 2vw; + width: 34%; + padding-top: 2vw; + padding-bottom: 2vw; + padding-left: 3vw; + padding-right: 3vw; + letter-spacing: 0.5vw; + cursor: pointer; + overflow: hidden; + text-align: center; + } + + .theAdYouCantRemoveThis + { + display: block; + background-color: white; + margin: auto; + width: 80%; + border: 0; + box-shadow: 0.25vw 0px 1vw lightgray, -0.25vw 0px 1vw lightgray, 0px 4vw 4vw 0px rgb(175, 175, 175); + margin-top: 3vh; + margin-bottom: 2vh; + overflow-x: auto; + overflow-y: auto; + border-top-right-radius: 1vw; + border-bottom-right-radius: 1vw; + } + + .ad + { + background-color: white; + margin: auto; + width: 96%; + height: auto; + border: solid gray 0.25vw; + border-width: 0.5px; + margin-top: 1%; + margin-bottom: 1%; + } + + .theAdYouCantRemoveThis p + { + color: black; + font-size: 3vw; + letter-spacing: 0.2vw; + margin-left: 3%; + margin-top: 2%; + margin-bottom: 0; + } + + /* Attributes for Copyrights Div: */ + + .copyrightParag + { + font-size: 3vw; + text-align: center; + margin: 0; + padding: 0; + } + + .copyright + { + margin: auto; + width: 100%; + display: block; + margin: 0; + padding: 0; + padding-bottom: 2vw; + } + + /* Attributes for General Links: */ + + .bottomLinks + { + margin-top: 2vh; + margin-bottom: 2vh; } -*/ -} /*Close the Media Query*/ -/* Attributes for Right Side:*/ - -.middleContainer -{ - position: absolute; - left: 21vw; - width: 53vw; - height: 100vh; - display: inline-block; - margin-right: 0; -} - -.portIndex -{ - background-color: rgb(227,227,227); - width: 71%; - height: 100vh; - margin-top: 25%; - margin-left: 1%; -} - -.rightContainer -{ - font-family: 'Roboto', Sans-Serif; - width: calc(17vh + 17vw); - height: 100vh; - transition: all 0.3s; - background-color: #E3E3E3; - top: 0px; - overflow-y: auto; - display: inline-block; - margin-left: 0; -} - -.searchform -{ - position: relative; - margin: 0; - padding: 0; - font-size: 0px; -} - -.search -{ - margin-top: calc(1.9vh + 1.9vw); - margin-left: calc(1.3vh + 1.3vw); - font-family: 'Roboto', Sans-Serif; - font-size: calc(0.6vh + 0.6vw); - padding: calc(0.5vh + 0.5vw); - color: black; - border-radius: calc(0.15vh + 0.15vw); - border-width: calc(0.05vh + 0.05vw); - border-style: solid; - border-color: rgb(192,192,192); - border-image: none; - width: 83%; -} - -.search::placeholder -{ - color: black !important; -} - -.viewPortIndex -{ - font-family: 'Roboto', sans-serif; - padding: calc(0.5vh + 0.5vw); - font-size: calc(0.65vh + 0.65vw); - font-weight: bold; - margin: auto; - width: 65%; - background-color: rgb(222, 211, 215); - color: #7B2240; /* maroon */ - text-align: center; - letter-spacing: calc(0.05vh + 0.05vw); - border: 0; - border-bottom: solid 1px; - border-bottom-color: #7B2240; /* maroon */ - border-bottom-width: calc(0.08vh + 0.08vw); - display: flex; - justify-content: center; - margin-top: 12%; - word-spacing: calc(0.1vh + 0.1vw); -} - -.viewPortIndex:hover -{ - background-color: lightgray !important; - cursor: pointer !important; - -webkit-transition: all 0.25s !important; /* Safari */ - transition: all 0.25s !important; -} - -.trending -{ - font-size: calc(0.65vh + 0.65vw); - margin: auto; - width: 65%; - background-color: rgb(222, 211, 215); - border: 0; - border-radius: calc(0.2vh + 0.2vw); - box-shadow: 1px 1px 2px lightgray; - margin-top: 2.5%; - overflow-x: hidden; - overflow-y: auto; -} - -.trendingTitle -{ - font-weight: bold; - padding-top: calc(0.65vh + 0.65vw); - padding-left: calc(0.8vh + 0.8vw); - color: #7B2240; /* maroon */ - margin-bottom: calc(0.5vh + 0.5vw); - margin-top: 0px; -} - -.trendingName, .trendingMem -{ - color: rgb(80, 80, 80); - margin-top: 0px; - margin-bottom: 0px; - margin-left: calc(1.2vh + 1.2vw); -} - -.trendingName -{ - font-size: calc(0.56vh + 0.56vw); -} - -.trendingMem -{ - font-size: calc(0.45vh + 0.45vw); - margin-top: 0%; - margin-bottom: 8%; -} - -.membersTrending5 -{ - margin-bottom: 0px; - padding-bottom: 0px; -} - -.subscribe -{ - float: right; - position: relative; - top: calc(-2.0vh - 2.0vw); - left: calc(-1.2vh - 1.2vw); - border-radius: calc(0.15vh + 0.15vw); - border: 0; - background-color: rgb(117, 117, 117); - color: white; - font-size: calc(0.45vh + 0.45vw); - width: 34%; - padding-top: calc(0.3vh + 0.3vw); - padding-bottom: calc(0.3vh + 0.3vw); - padding-left: calc(0.4vh + 0.4vw); - padding-right: calc(0.4vh + 0.4vw); - letter-spacing: calc(0.03vh + 0.03vw); - cursor: pointer; - overflow: hidden; - text-align: center; -} - -.theAdYouCantRemoveThis -{ - display: block; - background-color: white; - margin: auto; - width: 18vw; - font-size: 12px; - border: 0; - box-shadow: 0.5px 0px 2px lightgray, -0.5px 0px 2px lightgray, 0px 8px 8px 0px rgb(175, 175, 175); - margin-top: 16%; - margin-bottom: calc(2.5vh + 2.5vw); - overflow-x: auto; - overflow-y: auto; - border-top-right-radius: calc(0.1vh + 0.1vw); - border-bottom-right-radius: calc(0.1vh + 0.1vw); -} - -.ad -{ - background-color: white; - margin: auto; - width: 96%; - height: auto; - border: solid gray 0.5px; - border-width: calc(0.05vh + 0.05vw); - margin-top: 1%; - margin-bottom: 1%; -} - -.theAdYouCantRemoveThis p -{ - color: black; - font-size: calc(0.5vh + 0.5vw); - letter-spacing: calc(0.06vh + 0.06vw); - margin-left: 3%; - margin-top: 2%; - margin-bottom: 0; -} - -/* Attributes for Copyrights Div: */ - -.copyrightParag -{ - font-size: calc(0.65vh + 0.65vw); - text-align: center; - margin: 0; - padding: 0; -} - -.copyright -{ - position: absolute; - bottom: calc(1vh + 1vw); - width: 58vw; - display: inline-block; - margin: 0; - padding: 0; -} - -/* Attributes for General Links: */ - -.bottomLinks -{ - margin-top: 10px; -} - -.termsConds, .ourTeam, .contactUs -{ - text-decoration: none; - color: #7B2240; - font-size: calc(0.45vh + 0.45vw); - display: block; - text-align: center; -} - -/* Attributes for Middle Container: */ - -.midContainer -{ - float: right; - width: 60vmax; - height: 90vh; - overflow: auto; -} - -form -{ - margin-bottom: 0; -} + .termsConds, .ourTeam, .contactUs + { + text-decoration: none; + color: #7B2240; + font-size: 3vw; + display: block; + text-align: center; + } + + form + { + margin-bottom: 0; + } + + @keyframes blinker { + 50% { + text-shadow: 0 0 1vw #FFFF00; /* Make notifications button's text glow */ + font-weight: bold; + } + } + +} /*Close the Media Query*/ diff --git a/app/static/css/stylesGenTemplates.css b/app/static/css/stylesGenTemplates.css index 8eb7203..ece5814 100644 --- a/app/static/css/stylesGenTemplates.css +++ b/app/static/css/stylesGenTemplates.css @@ -1,54 +1,113 @@ /* CSS Styles for the template: 'genLinks.html' Version 1.0 - + 08.04.2019 - + Description: Creation of file - Front End Team */ -.page -{ - background-color: #d2bdc5; /* Slightly Dark Pink */ - margin-top: calc(4.5vh + 4.5vw); - margin-left: 7vmin; - border-bottom: solid #7B2240; - border-bottom-width: calc(0.08vh + 0.08vw); - text-align: center; - padding: calc(0.05vh + 0.05vw); - width: calc(8vh + 8vw); - font-family: inherit; - font-size: calc(0.5vh + 0.5vw); - font-weight: bold; - color: #7B2240; - letter-spacing: calc(0.05vh + 0.05vw); -} - -.divText -{ - margin-top: calc(0.5vh + 0.5vw); - margin-bottom: calc(1vh + 1vw); - margin-left: 7vmin; - padding: 20px; - padding-top: 10px; - padding-bottom: 10px; - width: 63%; - height: auto; - background-color: #E3E3E3; - border-radius: calc(0.2vh + 0.2vw); - box-shadow: 1px 1px 1px lightgray, -1px -1px 1px lightgray; -} - -.theText -{ - font-family: 'Libre Baskerville', serif; - font-size: 12px; - text-align: left; -} - -.theText a -{ - text-decoration-line: underline; - color: blue; -} \ No newline at end of file +/* Landscape Media Query */ +@media screen and (min-aspect-ratio: 13/9) { + + .page + { + background-color: #d2bdc5; /* Slightly Dark Pink */ + margin-top: calc(4.5vh + 4.5vw); + margin-left: 7vmin; + border-bottom: solid #7B2240; + border-bottom-width: calc(0.08vh + 0.08vw); + text-align: center; + padding: calc(0.05vh + 0.05vw); + width: calc(8vh + 8vw); + font-family: inherit; + font-size: calc(0.5vh + 0.5vw); + font-weight: bold; + color: #7B2240; + letter-spacing: calc(0.05vh + 0.05vw); + } + + .divText + { + margin-top: calc(0.5vh + 0.5vw); + margin-bottom: calc(1vh + 1vw); + margin-left: 7vmin; + padding: 20px; + padding-top: 10px; + padding-bottom: 10px; + width: 63%; + height: auto; + background-color: #E3E3E3; + border-radius: calc(0.2vh + 0.2vw); + box-shadow: 1px 1px 1px lightgray, -1px -1px 1px lightgray; + } + + .theText + { + font-family: 'Libre Baskerville', serif; + font-size: 12px; + text-align: left; + } + + .theText a + { + text-decoration-line: underline; + color: blue; + } + +} /* Close Media Query */ + +/* Portrait Media Query */ +@media screen and (max-aspect-ratio: 13/9) { + + .page + { + background-color: #d2bdc5; + margin: auto; + margin-top: 4vh; + border-bottom: solid #7B2240; + border-bottom-width: 0.5vw; + text-align: center; + padding: 3vw; + width: 50%; + font-family: inherit; + font-size: 3vw; + font-weight: bold; + color: #7B2240; + letter-spacing: 0.5vw; + } + + .pageTitle{ + margin: 0; + } + + .divText + { + margin: auto; + margin-top: 2vw; + margin-bottom: 2vw; + padding: 4vw; + padding-top: 2vw; + padding-bottom: 2vw; + width: 90%; + height: auto; + background-color: #E3E3E3; + border-radius: 1vw; + box-shadow: 0.3vw 0.3vw 0.3vw lightgrey, -0.3vw -0.3vw 0.3vw lightgrey; + } + + .theText + { + font-family: 'Libre Baskerville', serif; + font-size: 3vw; + text-align: left; + } + + .theText a + { + text-decoration-line: underline; + color: blue; + } + +} /* Close Media Query */ diff --git a/app/static/css/stylesNotifications.css b/app/static/css/stylesNotifications.css new file mode 100644 index 0000000..df7e3f2 --- /dev/null +++ b/app/static/css/stylesNotifications.css @@ -0,0 +1,239 @@ +/* CSS file for: 'notifications.html' + version 1.0 + 09.01.2019 + Description: Creation of File +- Front End Team +*/ + +/* Landscape Media Query */ +@media screen and (min-aspect-ratio: 13/9) { + + .flexTitle{ + display: flex; + position: relative; + margin-bottom: 15px; + margin-left: 7vmin; + } + + .page + { + background-color: rgb(210, 189, 197); /* Slight Maroon */ + margin-top: calc(6vh + 6vw); + border-bottom: solid #7B2240; + border-bottom-width: 1px; + text-align: center; + padding: 9px; + padding-left: 25px; + padding-right: 25px; + width: auto; + height: auto; + font-family: inherit; + font-size: 0; + font-weight: bold; + color: #7B2240; + display: inline-block; + } + + .pageTitle{ + margin: 0; + font-size: 11.5px; + letter-spacing: 1.5px; + } + + .welcomeDiv{ + position: relative; + margin-bottom: 15px; + margin-left: 7vmin; + background-color: #90EE90; + padding: 15px; + border: dashed 1px green; + width: 87%; + } + + .welcomeDiv p{ + font-size: 15px; + letter-spacing: 0.5px; + } + + .welcomeToNotifications{ + font-weight: bold; + text-align: center; + font-size: 20px !important; + } + + .notifications-section{ + margin: 0; + width: 87%; + height: auto; + border-radius: 5px; + position: relative; + margin-left: 7vmin; + box-shadow: 1px 1px 1px gray; + display: flex; + flex-direction: column; + padding: 15px; + margin-bottom: 15px; + font-size: 13px; + } + + .whoCommented{ + margin: 0; + padding: 0; + padding-bottom: 10px; + } + + .usernameOfAuthor{ + color: #7b2240; + margin: 0; + padding: 0; + overflow-y: auto; + } + + .nameOfPostOrComment{ + margin: 0; + padding: 0; + padding-bottom: 10px; + letter-spacing: 0.5px; + color: black; + font-weight: bold; + } + + .theNoteDate{ + margin: 0; + padding: 0; + padding-bottom: 10px; + color: black; + } + + .theNoteContent{ + margin: 0; + padding: 0; + letter-spacing: 0.5px; + color: rgb(80, 80, 80); + } + + .noteSecondPart { + margin-bottom: 10px; + text-align: center; + } + + .noteFourthPart { + text-align: center; + } + +} /* Close Media Query */ + +/* Portrait Media Query */ +@media screen and (max-aspect-ratio: 13/9) { + + .flexTitle{ + display: flex; + position: relative; + margin-bottom: 3vw; + } + + .page + { + background-color: rgb(210, 189, 197); + margin: auto; + margin-top: 4vh; + border-bottom: solid #7B2240; + border-bottom-width: 0.5vw; + text-align: center; + padding: 3vw; + padding-left: 12vw; + padding-right: 12vw; + font-family: inherit; + font-size: 0; + font-weight: bold; + color: #7B2240; + display: inline-block; + } + + .pageTitle{ + margin: 0; + font-size: 3vw; + letter-spacing: 0.75vw; + } + + .welcomeDiv{ + position: relative; + background-color: #90EE90; + padding: 3vw; + border: dashed 0.3vw green; + width: 87%; + margin: auto; + margin-bottom: 3vw; + } + + .welcomeDiv p{ + font-size: 3vw; + letter-spacing: 0.2vw; + } + + .welcomeToNotifications{ + font-weight: bold; + text-align: center; + font-size: 4vw !important; + } + + .notifications-section{ + margin: 0; + margin: auto; + width: 87%; + border-radius: 1vw; + position: relative; + box-shadow: 0.3vw 0.3vw 0.3vw grey; + display: flex; + flex-direction: column; + padding: 3vw; + margin-bottom: 3vw; + font-size: 3vw; + } + + .whoCommented{ + margin: 0; + padding: 0; + padding-bottom: 2.5vw; + } + + .usernameOfAuthor{ + color: #7b2240; + margin: 0; + padding: 0; + overflow-y: auto; + } + + .nameOfPostOrComment{ + margin: 0; + padding: 0; + padding-bottom: 2.5vw; + letter-spacing: 0.3vw; + color: black; + font-weight: bold; + } + + .theNoteDate{ + margin: 0; + padding: 0; + padding-bottom: 2.5vw; + color: black; + } + + .theNoteContent{ + margin: 0; + padding: 0; + letter-spacing: 0.3vw; + color: rgb(80, 80, 80); + } + + .noteSecondPart { + margin-bottom: 2.5vw; + text-align: center; + } + + .noteFourthPart { + text-align: center; + } + +} /* Close Media Query */ diff --git a/app/static/css/stylesPortIndex.css b/app/static/css/stylesPortIndex.css index 1a23ec8..6e06a6f 100644 --- a/app/static/css/stylesPortIndex.css +++ b/app/static/css/stylesPortIndex.css @@ -5,108 +5,220 @@ - Front End Team */ -.flexTitle{ - display: flex; - position: relative; - margin-bottom: 15px; - margin-left: 7vmin; -} - -.page -{ - background-color: #ded3d7; /* Slight Maroon */ - margin-top: calc(6vh + 6vw); - border-bottom: solid #7B2240; - border-bottom-width: 1px; - text-align: center; - padding: 9px; - padding-left: 65px; - padding-right: 65px; - width: auto; - height: auto; - font-family: inherit; - font-size: 0; - font-weight: bold; - color: #7B2240; - display: inline-block; -} - -.pageTitle{ - margin: 0; - font-size: 11.5px; - letter-spacing: 1.5px; -} - -.port-section{ - margin: 0; - width: 450px; - height: auto; - border-radius: 5px; - position: relative; - margin-left: 7vmin; - box-shadow: 1px 1px 1px gray; - display: flex; - padding: 20px; - padding-left: 20px; - margin-bottom: 15px; -} - -.portFirstPart, .portSecondPart, .portThirdPart{ - display: flex; - flex-direction: column; - text-align: left; - justify-content: space-around; -} - -.portFirstPart, .portSecondPart{ - margin: 0; - margin-right: 15px; -} - -.portThirdPart{ - margin-left: auto; - margin-right: 0; - order: 2; -} - -.portName{ - margin: 0; - padding: 0; - padding-bottom: 10px; - font-size: 15px; - color: rgb(80, 80, 80); -} - -.portMembersNumber{ - margin: 0; - padding: 0; - font-size: 8.5px; - color: rgb(80, 80, 80); -} - -.portDescription{ - margin: 0; - padding: 0; - font-size: 9.5px; - letter-spacing: 0.5px; - color: rgb(80, 80, 80); -} - -.indexForm{ - margin: 0; - padding: 0; - font-size: 0; -} - -.subscribeIndex{ - text-align: center; - border-radius: 3px; - border: 0; - color: white; - font-size: 8.5px; - width: 70px; - height: auto; - padding: 6px; - letter-spacing: 0.5px; - cursor: pointer; -} \ No newline at end of file +/* Landscape Media Query */ +@media screen and (min-aspect-ratio: 13/9) { + + .flexTitle{ + display: flex; + position: relative; + margin-bottom: 15px; + margin-left: 7vmin; + } + + .page + { + background-color: #ded3d7; /* Slight Maroon */ + margin-top: calc(6vh + 6vw); + border-bottom: solid #7B2240; + border-bottom-width: 1px; + text-align: center; + padding: 9px; + padding-left: 65px; + padding-right: 65px; + width: auto; + height: auto; + font-family: inherit; + font-size: 0; + font-weight: bold; + color: #7B2240; + display: inline-block; + } + + .pageTitle{ + margin: 0; + font-size: 11.5px; + letter-spacing: 1.5px; + } + + .port-section{ + margin: 0; + width: 450px; + height: auto; + border-radius: 5px; + position: relative; + margin-left: 7vmin; + box-shadow: 1px 1px 1px gray; + display: flex; + padding: 20px; + padding-left: 20px; + margin-bottom: 15px; + } + + .portFirstPart, .portSecondPart, .portThirdPart{ + display: flex; + flex-direction: column; + text-align: left; + justify-content: space-around; + } + + .portFirstPart, .portSecondPart{ + margin: 0; + margin-right: 15px; + } + + .portThirdPart{ + margin-left: auto; + margin-right: 0; + order: 2; + } + + .portName{ + margin: 0; + padding: 0; + padding-bottom: 10px; + font-size: 15px; + color: rgb(80, 80, 80); + } + + .portMembersNumber{ + margin: 0; + padding: 0; + font-size: 8.5px; + color: rgb(80, 80, 80); + } + + .portDescription{ + margin: 0; + padding: 0; + font-size: 9.5px; + letter-spacing: 0.5px; + color: rgb(80, 80, 80); + } + + .indexForm{ + margin: 0; + padding: 0; + font-size: 0; + } + + .subscribeIndex{ + text-align: center; + border-radius: 3px; + border: 0; + color: white; + font-size: 8.5px; + width: 70px; + height: auto; + padding: 6px; + letter-spacing: 0.5px; + cursor: pointer; + } + +} /* Close Media Query */ + +/* Portrait Media Query */ +@media screen and (max-aspect-ratio: 13/9) { + + .flexTitle{ + display: flex; + position: relative; + margin-bottom: 3vw; + } + + .page + { + background-color: #ded3d7; + margin: auto; + margin-top: 4vh; + border-bottom: solid #7B2240; + border-bottom-width: 0.5vw; + text-align: center; + padding: 3vw; + padding-left: 12vw; + padding-right: 12vw; + font-family: inherit; + font-size: 0; + font-weight: bold; + color: #7B2240; + display: inline-block; + } + + .pageTitle{ + margin: 0; + font-size: 3vw; + letter-spacing: 0.75vw; + } + + .port-section{ + margin: 0; + margin: auto; + width: 87%; + border-radius: 1vw; + position: relative; + box-shadow: 0.3vw 0.3vw 0.3vw grey; + display: flex; + padding: 3vw; + margin-bottom: 3vw; + } + + .portFirstPart, .portSecondPart, .portThirdPart{ + display: flex; + flex-direction: column; + text-align: left; + justify-content: space-around; + } + + .portFirstPart, .portSecondPart{ + margin: 0; + margin-right: 3vw; + } + + .portThirdPart{ + margin-left: auto; + margin-right: 0; + order: 2; + } + + .portName{ + margin: 0; + padding: 0; + padding-bottom: 2vw; + font-size: 4vw; + color: rgb(80, 80, 80); + } + + .portMembersNumber{ + margin: 0; + padding: 0; + font-size: 2vw; + color: rgb(80, 80, 80); + } + + .portDescription{ + margin: 0; + padding: 0; + font-size: 2.5vw; + letter-spacing: 0.25vw; + color: rgb(80, 80, 80); + } + + .indexForm{ + margin: 0; + padding: 0; + font-size: 0; + } + + .subscribeIndex{ + text-align: center; + border-radius: 1vw; + border: 0; + color: white; + font-size: 2vw; + width: 20vw; + height: auto; + padding: 2vw; + letter-spacing: 0.5vw; + cursor: pointer; + } + +} /* Close Media Query */ diff --git a/app/static/css/stylesPostDetails.css b/app/static/css/stylesPostDetails.css index 5417308..6570f9b 100644 --- a/app/static/css/stylesPostDetails.css +++ b/app/static/css/stylesPostDetails.css @@ -5,334 +5,669 @@ - Front End Team */ -.commentSubmittedMessage{ - margin: 0; - font-size: 14px; - color: green; - margin-left: 7vmin; - padding-left: 70px; - margin-bottom: 15px; -} - -.flexTitle{ - display: flex; - position: relative; - margin-bottom: 15px; - margin-left: 7vmin; - margin-top: calc(4.5vh + 4.5vw); -} - -.savePost{ - background-repeat: no-repeat; - background-position: 7px 6px; - border-radius: 3px; - border: none; - cursor: pointer; - color: white; - font-size: 8.5px; - font-weight: normal; - letter-spacing: 0.5px; - padding: 7px; - padding-left: 20px; - padding-right: 5px; - width: 85; - position: absolute; - bottom: 0; - left: 455px; - font-family: 'Roboto', Sans-Serif; - text-align: center; -} - -.mainScreen{ - display: flex; - flex-direction: column; - width: 550px; - margin-bottom: 15px; - margin-left: 7vmin; -} - -.votes{ - display: flex; - flex-direction: column; - text-align: center; - margin: 0; - width: 80px; -} - -.numOfVotes{ - padding: 0; - margin: 0; - font-size: 15px; -} - -.upvote, .downvote{ - margin: 0; - padding: 0; - font-size: 0; - display: inline-block; -} - -.upvoteBtn, .downvoteBtn{ - letter-spacing: 1px; - margin: 0; - padding: 0; - font-size: 12px; - border: 0; - background-color: transparent; - cursor: pointer; -} - -.postData{ - display: flex; - flex-direction: row; - position: relative; - margin-bottom: 15px; -} - -.description{ - display: flex; - flex-direction: column; - text-align: left; - margin-left: 5px; -} - -.portOfPostName{ - margin: 0; - padding: 0; - font-size: 12px; - font-weight: normal; - color: black; -} - -.nameOfPost{ - margin: 0; - font-size: 18px; - color: black; - padding: 0; - padding-bottom: 20px; - padding-top: 10px; -} - -.timeAndAuthor{ - display: flex; - flex-direction: column; - width: auto; - margin-left: auto; - margin-right: 10px; - order: 2; -} - -.dateOfWriting{ - font-size: 9px; - color: black; - margin: 0; - padding: 0; - margin-left: auto; - width: 86px; -} - -.postedBy{ - margin: 0; - padding: 0; - margin-top: 30px; - font-size: 7px; - color: black; -} - -.authorDetails{ - display: flex; -} - -.roundImage{ - margin: 0; - padding: 0; - margin-top: 3px; - margin-bottom: 15px; - font-size: 0; - border: 0; - border-radius: 100%; - width: 25px; - height: 25px; -} - -.usernameOfAuthor{ - color: #7b2240; - font-size: 9px; - margin: 0; - padding: 0; - margin-left: 5px; - overflow-y: auto; - margin-top: 9px; -} - -.postDescription{ - margin: 0; - color: black; - text-align: left; - font-size: 12px; - letter-spacing: 0.5px; - border-left: solid 1px black; - padding-left: 10px; - margin-bottom: 15px; - margin-left: 80px; -} - -.postImageDiv{ - width: auto; - background-color: #e3e3e3; - border-radius: 3px; - box-shadow: 1px 1px 1px gray; - margin-left: 80px; - margin-bottom: 10px; -} - -.squareImage{ - width: 300px; - height: 300px; - border: 0; - padding: 0; - display: block; - margin: auto; - margin-top: 7px; - margin-bottom: 7px; -} - -.writeCommentToPost{ - margin-left: 80px; -} - -.commentToPostText{ - margin: 0; - margin-top: 10px; - margin-bottom: 10px; - border: 0.5px solid LightGray; - padding-left: 10px; - padding-top: 5px; - padding-right: 10px; - padding-bottom: 5px; - width: 100%; - border-radius: 3px; - font-family: 'Roboto', Sans-Serif; - font-size: 12px; -} - -.commentToPostText::placeholder{ - color: black; important! -} - -.commentToPostDiv{ - display: flex; - justify-content: flex-end; - margin: 0; - margin-bottom: 10px; -} - -.CommentToPostBtn{ - text-align: center; - background-color: #757575; - border-radius: 3px; - border: 0; - color: white; - font-size: 8.5px; - width: auto; - height: auto; - padding: 6px; - letter-spacing: 0.5px; - cursor: pointer; -} - -.comments{ - display: flex; - flex-direction: column; - text-align: left; - margin-left: 80px; -} - -.numberOfComments{ - padding: 0; - margin: 0; - margin-bottom: 15px; - color: black; - font-size: 14px; -} - -.commentTree{ - width: auto; - background-color: #e3e3e3; - border-radius: 3px; - box-shadow: 1px 1px 1px gray; - padding: 10px; -} - -.firstLevelComment, .secondLevelComment{ - display: flex; - margin: 0; - margin-bottom: 10px; -} - -.votesComments{ - text-align: center; -} - -.commentsImage{ - margin-left: 10px; -} - -.commentUsernameOfAuthor{ - margin: 0; - margin-top: 5px; -} - -.upvoteBtnComments, .upvoteBtnComments{ - font-size: 10px; -} - -.numOfVotesComments{ - font-size: 12px; -} - -.commentUserNameTextAndReply{ - margin-left: 10px; -} - -.commentText{ - margin: 0; - font-size: 11px; - color: black; - margin-top: 5px; - margin-right: 10px; -} - -.commentReply{ - letter-spacing: 1px; - margin: 0; - padding: 0; - font-size: 9px; - border: 0; - background-color: transparent; - color: #7b2240; - cursor: pointer; - margin-top: 5px; -} - -.commentDate{ - margin: 0; - order: 2; - margin-left: auto; - margin-right: 0; - width: 83px; -} - -.commentDateOfWriting{ - margin: 0; - font-size:9px; - width: 83px; -} - -.blackline{ - margin-left: 6px; - width: 0px; - border-left: 1px solid black; - height: auto; - margin-right: 25px; -} \ No newline at end of file +/* Landscape Media Query */ +@media screen and (min-aspect-ratio: 13/9) +{ + .commentSubmittedMessage{ + margin: 0; + font-size: 14px; + color: green; + margin-left: 7vmin; + padding-left: 70px; + margin-bottom: 15px; + } + + .flexTitle{ + display: flex; + position: relative; + margin-bottom: 15px; + margin-left: 7vmin; + margin-top: calc(4.5vh + 4.5vw); + } + + .savePost{ + background-repeat: no-repeat; + background-position: 7px 6px; + border-radius: 3px; + border: none; + cursor: pointer; + color: white; + font-size: 8.5px; + font-weight: normal; + letter-spacing: 0.5px; + padding: 7px; + padding-left: 20px; + padding-right: 5px; + width: 85; + position: absolute; + bottom: 0; + left: 455px; + font-family: 'Roboto', Sans-Serif; + text-align: center; + } + + .mainScreen{ + display: flex; + flex-direction: column; + width: 550px; + margin-bottom: 15px; + margin-left: 7vmin; + } + + .votes{ + display: flex; + flex-direction: column; + text-align: center; + margin: 0; + width: 80px; + } + + .numOfVotes{ + padding: 0; + margin: 0; + font-size: 15px; + } + + .upvote, .downvote{ + margin: 0; + padding: 0; + font-size: 0; + display: inline-block; + } + + .upvoteBtn, .downvoteBtn{ + letter-spacing: 1px; + margin: 0; + padding: 0; + font-size: 12px; + border: 0; + background-color: transparent; + cursor: pointer; + } + + .postData{ + display: flex; + flex-direction: row; + position: relative; + margin-bottom: 15px; + } + + .description{ + display: flex; + flex-direction: column; + text-align: left; + margin-left: 5px; + } + + .portOfPostName{ + margin: 0; + padding: 0; + font-size: 12px; + font-weight: normal; + color: black; + } + + .nameOfPost{ + margin: 0; + font-size: 18px; + color: black; + padding: 0; + padding-bottom: 20px; + padding-top: 10px; + } + + .timeAndAuthor{ + display: flex; + flex-direction: column; + width: auto; + margin-left: auto; + margin-right: 10px; + order: 2; + } + + .dateOfWriting{ + font-size: 9px; + color: black; + margin: 0; + padding: 0; + margin-left: auto; + width: 86px; + } + + .postedBy{ + margin: 0; + padding: 0; + margin-top: 30px; + font-size: 7px; + color: black; + } + + .authorDetails{ + display: flex; + } + + .roundImage{ + margin: 0; + padding: 0; + margin-top: 3px; + margin-bottom: 15px; + font-size: 0; + border: 0; + border-radius: 100%; + width: 25px; + height: 25px; + } + + .usernameOfAuthor{ + color: #7b2240; + font-size: 9px; + margin: 0; + padding: 0; + margin-left: 5px; + overflow-y: auto; + margin-top: 9px; + } + + .postDescription{ + margin: 0; + color: black; + text-align: left; + font-size: 12px; + letter-spacing: 0.5px; + border-left: solid 1px black; + padding-left: 10px; + margin-bottom: 15px; + margin-left: 80px; + } + + .postImageDiv{ + width: auto; + background-color: #e3e3e3; + border-radius: 3px; + box-shadow: 1px 1px 1px gray; + margin-left: 80px; + margin-bottom: 10px; + } + + .squareImage{ + width: 300px; + height: 300px; + border: 0; + padding: 0; + display: block; + margin: auto; + margin-top: 7px; + margin-bottom: 7px; + } + + .writeCommentToPost{ + margin-left: 80px; + } + + .commentToPostText{ + margin: 0; + margin-top: 10px; + margin-bottom: 10px; + border: 0.5px solid LightGray; + padding-left: 10px; + padding-top: 5px; + padding-right: 10px; + padding-bottom: 5px; + width: 100%; + border-radius: 3px; + font-family: 'Roboto', Sans-Serif; + font-size: 12px; + } + + .commentToPostText::placeholder{ + color: black; important! + } + + .commentToPostDiv, .commentToCommentDiv{ + display: flex; + justify-content: flex-end; + margin: 0; + margin-bottom: 10px; + } + + .CommentToPostBtn, .commentToCommentBtn{ + text-align: center; + background-color: #757575; + border-radius: 3px; + border: 0; + color: white; + font-size: 8.5px; + width: auto; + height: auto; + padding: 6px; + letter-spacing: 0.5px; + cursor: pointer; + } + + .comments{ + display: flex; + flex-direction: column; + text-align: left; + margin-left: 80px; + } + + .numberOfComments{ + padding: 0; + margin: 0; + margin-bottom: 15px; + color: black; + font-size: 14px; + } + + .commentTree{ + width: auto; + background-color: #e3e3e3; + border-radius: 3px; + box-shadow: 1px 1px 1px gray; + padding: 10px; + } + + .firstLevelComment, .secondLevelComment{ + display: flex; + margin: 0; + margin-bottom: 10px; + } + + .votesComments{ + text-align: center; + } + + .commentsImage{ + margin-left: 10px; + } + + .commentUsernameOfAuthor{ + margin: 0; + margin-top: 5px; + } + + .upvoteBtnComments, .upvoteBtnComments{ + font-size: 10px; + } + + .numOfVotesComments{ + font-size: 12px; + } + + .commentUserNameTextAndReply{ + margin-left: 10px; + } + + .commentText{ + margin: 0; + font-size: 11px; + color: black; + margin-top: 5px; + margin-right: 10px; + } + + .commentReply{ + letter-spacing: 1px; + margin: 0; + padding: 0; + font-size: 9px; + border: 0; + background-color: transparent; + color: #7b2240; + cursor: pointer; + margin-top: 5px; + } + + .commentDate{ + margin: 0; + order: 2; + margin-left: auto; + margin-right: 0; + width: 83px; + } + + .commentDateOfWriting{ + margin: 0; + font-size:9px; + width: 83px; + } + + .blackline{ + margin-left: 6px; + width: 0px; + border-left: 1px solid black; + height: auto; + margin-right: 25px; + } + +} /* Close Media Query */ + +/* Portrait Media Query */ +@media screen and (max-aspect-ratio: 13/9) +{ + .commentSubmittedMessage{ + margin: 0; + font-size: 5vw; + color: green; + text-align: center; + margin-bottom: 3vw; + } + + .flexTitle{ + position: relative; + float: right; + margin-right: 3vw; + margin-top: 3vw; + margin-bottom: 5vw; + } + + .savePost{ + background-repeat: no-repeat; + background-position: 2vw 2.5vw; + background-size: 3.2vw 2.6vw; + border-radius: 0.5vw; + border: none; + cursor: pointer; + color: white; + font-size: 2.5vw; + font-weight: normal; + letter-spacing: 0.2vw; + padding: 2.5vw; + padding-left: 6vw; + width: 22vw; + font-family: 'Roboto', Sans-Serif; + text-align: center; + } + + .mainScreen{ + display: flex; + flex-direction: column; + clear: both; + } + + .votes{ + display: flex; + flex-direction: column; + text-align: center; + margin: 0; + margin-top: 7vw; + } + + .numOfVotes{ + padding: 0; + margin: 0; + font-size: 4vw; + } + + .upvote, .downvote{ + margin: 0; + padding: 0; + font-size: 0; + display: inline-block; + } + + .upvoteBtn, .downvoteBtn{ + letter-spacing: 0.5vw; + margin: 0; + padding: 0; + font-size: 3vw; + border: 0; + background-color: transparent; + cursor: pointer; + } + + .postData{ + display: flex; + flex-direction: row; + justify-content: space-evenly; + flex-wrap: wrap; + margin-top: 3vw; + } + + .description{ + display: flex; + flex-direction: column; + text-align: left; + order: 2; + flex-shrink: 0; + width: 95%; + margin-top: 3vw; + } + + .portOfPostName{ + margin: 0; + padding: 0; + font-size: 3vw; + font-weight: normal; + color: black; + } + + .nameOfPost{ + margin: 0; + font-size: 6vw; + color: black; + padding: 0; + padding-bottom: 3vw; + padding-top: 2vw; + } + + .timeAndAuthor{ + display: flex; + flex-direction: column; + width: max-content; + } + + .dateOfWriting{ + font-size: 3vw; + color: black; + margin: 0; + padding: 0; + margin-left: auto; + } + + .postedBy{ + margin: 0; + padding: 0; + margin-top: 10vw; + font-size: 3vw; + color: black; + } + + .authorDetails{ + display: flex; + } + + .roundImage{ + margin: 0; + padding: 0; + margin-top: 1vw; + font-size: 0; + border: 0; + border-radius: 100%; + width: 8.5vw; + height: 8.5vw; + } + + .usernameOfAuthor{ + color: #7b2240; + font-size: 3vw; + margin: 0; + padding: 0; + margin-left: 1vw; + overflow-y: auto; + margin-top: 3vw; + } + + .postDescription{ + margin: 0; + color: black; + text-align: left; + font-size: 3.5vw; + letter-spacing: 0.2vw; + border-left: solid 0.3vw black; + padding-left: 2vw; + margin-bottom: 3vw; + margin-left: 2vw; + } + + .postImageDiv{ + width: 96%; + background-color: #e3e3e3; + border-radius: 1vw; + box-shadow: 0.3vw 0.3vw 0.3vw gray; + margin: auto; + margin-bottom: 2vw; + } + + .squareImage{ + width: 60vw; + height: 60vw; + border: 0; + padding: 0; + display: block; + margin: auto; + margin-top: 2vw; + margin-bottom: 2vw; + } + + .writeCommentToPost{ + margin: auto; + width: 96%; + } + + .commentToPostText{ + margin: auto; + margin-bottom: 2vw; + border: 0.2vw solid LightGray; + padding-left: 3vw; + padding-top: 2vw; + padding-right: 3vw; + padding-bottom: 2vw; + width: 100%; + border-radius: 1vw; + font-family: 'Roboto', Sans-Serif; + font-size: 3vw; + height: 30vw; + } + + .commentToPostText::placeholder{ + color: black; important! + } + + .commentToPostDiv, .commentToCommentDiv{ + display: flex; + justify-content: flex-end; + margin: 0; + margin-bottom: 2vw; + } + + .CommentToPostBtn, .commentToCommentBtn{ + text-align: center; + background-color: #757575; + border-radius: 0.5vw; + border: 0; + color: white; + font-size: 2.5vw; + width: auto; + height: auto; + padding: 2vw; + letter-spacing: 0.2vw; + cursor: pointer; + } + + .comments{ + display: flex; + flex-direction: column; + text-align: left; + width: 96%; + margin: auto; + } + + .numberOfComments{ + padding: 0; + margin: 0; + margin-bottom: 3vw; + color: black; + font-size: 3.5vw; + } + + .commentTree{ + width: auto; + background-color: #e3e3e3; + border-radius: 1vw; + box-shadow: 0.3vw 0.3vw 0.3vw gray; + padding: 2vw; + } + + .firstLevelComment, .secondLevelComment{ + display: flex; + margin: 0; + margin-bottom: 2vw; + } + + .votesComments{ + text-align: center; + } + + .commentsImage{ + margin-left: 2vw; + } + + .commentUsernameOfAuthor{ + margin: 0; + } + + /* .upvoteBtnComments, .upvoteBtnComments{ + font-size: 10px; + } + + .numOfVotesComments{ + font-size: 12px; + }*/ + + .commentUserNameTextAndReply{ + margin-left: 2vw; + } + + .commentText{ + margin: 0; + font-size: 2.5vw; + color: black; + margin-top: 1vw; + margin-right: 2vw; + } + + .commentReply{ + letter-spacing: 0.2vw; + margin: 0; + padding: 0; + font-size: 2.5vw; + border: 0; + background-color: transparent; + color: #7b2240; + cursor: pointer; + margin-top: 1vw; + } + + .commentDate{ + margin: 0; + order: 2; + margin-left: auto; + margin-right: 0; + } + + .commentDateOfWriting{ + margin: 0; + font-size: 2.5vw; + width: max-content; + } + + .blackline{ + margin-left: 2vw; + width: 0px; + border-left: 0.5vw solid black; + height: auto; + margin-right: 6vw; + } + +} /* Close Media Query */ diff --git a/app/static/css/stylesPostSubmitted.css b/app/static/css/stylesPostSubmitted.css index 54c4576..46c469f 100644 --- a/app/static/css/stylesPostSubmitted.css +++ b/app/static/css/stylesPostSubmitted.css @@ -1,50 +1,103 @@ /* CSS Styles for the template: 'postSubmitted.html' Version 1.0 - 08.06.2019 - Description: Creation of file - Front End Team */ -.page -{ - width: 70%; - margin-top: 23vmin; - margin-left: 15vmin; -} - -.welcome -{ - font-size: 24px; - text-align: left; - margin-bottom: 15px; - margin-top: 5px; -} - -.viewPost, .homepage -{ - text-align: center; - display: block; - margin-bottom: 15px; - border-radius: 3px; - border: 0; - background-color: #757575; - color: white; - font-size: 8px; - padding-top: 6px; - padding-bottom: 6px; - padding-left: 10px; - padding-right: 10px; - letter-spacing: 0.5px; - cursor: pointer; - overflow: hidden; - transition: all 1s; -} - -form -{ - padding: 0; - margin: 0; -} \ No newline at end of file +/* Landscape Media Query */ +@media screen and (min-aspect-ratio: 13/9) { + + .page + { + width: 70%; + margin-top: 23vmin; + margin-left: 15vmin; + } + + .welcome + { + font-size: 24px; + text-align: left; + margin-bottom: 15px; + margin-top: 5px; + } + + .viewPost, .homepage + { + text-align: center; + display: block; + margin-bottom: 15px; + border-radius: 3px; + border: 0; + background-color: #757575; + color: white; + font-size: 8px; + padding-top: 6px; + padding-bottom: 6px; + padding-left: 10px; + padding-right: 10px; + letter-spacing: 0.5px; + cursor: pointer; + overflow: hidden; + transition: all 1s; + } + + form + { + padding: 0; + margin: 0; + } + +} /* Close Media Query */ + +/* Portrait Media Query */ +@media screen and (max-aspect-ratio: 13/9) { + + .page + { + margin-top: 3vw; + } + + .welcome + { + font-size: 6vw; + text-align: center; + margin: auto; + margin-bottom: 3vw; + width: 80%; + } + + .viewPost, .homepage + { + text-align: center; + margin-bottom: 3vw; + border-radius: 0.5vw; + border: 0; + background-color: #757575; + color: white; + font-size: 2vw; + padding-top: 2vw; + padding-bottom: 2vw; + padding-left: 3vw; + padding-right: 3vw; + letter-spacing: 0.25vw; + cursor: pointer; + overflow: hidden; + transition: all 1s; + } + + .specform { + margin: auto; + width: 80%; + text-align: center; + } + + form + { + padding: 0; + margin: 0; + } + +} /* Close Media Query */ diff --git a/app/static/css/stylesPosts.css b/app/static/css/stylesPosts.css index e34c9e7..e6a708d 100644 --- a/app/static/css/stylesPosts.css +++ b/app/static/css/stylesPosts.css @@ -1,239 +1,454 @@ +/* CSS for `posts.html` + Version 2.0 + 08.22.2019 + Description: media queries added! +*/ + /* Middle Part---------------Johnny */ -.flexTitle{ - display: flex; - position: relative; - margin-bottom: 15px; - margin-left: 7vmin; -} - -.page -{ - background-color: #d2bdc5; /* Slight Maroon */ - margin-top: calc(4.5vh + 4.5vw); - border-bottom: solid #7B2240; - border-bottom-width: 1px; - text-align: center; - padding: 9px; - padding-left: 15px; - padding-right: 15px; - width: auto; - height: auto; - font-family: inherit; - font-size: 0; - font-weight: bold; - color: #7B2240; - display: inline-block; -} - -.pageTitle{ - margin: 0; - font-size: 9px; - letter-spacing: 1px; -} - -.searchResultsMessage{ - margin: 0; - margin-bottom: 10px; - padding: 0; - text-align: center; - color: black; - font-size: 15px; -} - -.createPostBtn{ - font-family: 'Roboto', Sans-Serif; - margin-top: calc(4.8vh + 4.8vw); - text-align: center; - border-radius: 3px; - border: 0; - background-color: #757575; - color: #ececec; - font-size: 9px; - font-weight: normal; - letter-spacing: 0.5px; - padding: 8.5px; - padding-left: 20px; - padding-right: 20px; - cursor: pointer; - overflow: hidden; - width: auto; - position: absolute; - bottom: 0; - left: 260px; -} - -.sortByForm{ - margin-top: calc(4.8vh + 4.8vw); - position: absolute; - bottom: 0; - left: 380px; -} - -select{ - font-family: 'Roboto', Sans-Serif; - background-color: #dbdbdb; - color: black; - margin: 0; - padding: 7px; - border: 0; - border-radius: 3px; - box-shadow: 1px 1px 1px gray; - width: auto; - font-size: 12px; -} - -.btn{ - height: 40px; - width: 150px; -} - -.right-btn{ - background-color: #e5e3e3; - width: 250px; - height: 60px; - border-bottom-color: red; - border-bottom-style: groove; - text-align: center; - padding-top: 16px; -} - -.post-section{ - margin: 0; - width: 500px; - height: auto; - background-color: #ded3d7; - border-radius: 5px; - position: relative; - margin-left: 7vmin; - box-shadow: 1px 1px 1px gray; - display: flex; - padding-left: 20px; - padding-right: 20px; - margin-bottom: 15px; -} - -.votes{ - display: flex; - flex-direction: column; - text-align: center; - margin-top: 25px; - margin-right: 20px; -} - -.numOfVotes{ - padding: 0; - margin: 0; - font-size: 15px; -} - -.upvote, .downvote{ - margin: 0; - padding: 0; - font-size: 0; - display: inline-block; -} - -.upvoteBtn, .downvoteBtn{ - letter-spacing: 1px; - margin: 0; - padding: 0; - font-size: 12px; - border: 0; - background-color: transparent; - cursor: pointer; -} - -.squareImage{ - width: 80px; - height: 80px; - border: 0; - border-radius: 3px; - margin: 10px; - margin-right: 20px; - margin-left: 0; - padding: 0; -} - -.description{ - display: flex; - flex-direction: column; - text-align: left; -} - -.portOfPostName, .postDescription, .numberOfComments{ - margin: 0; - font-size: 9px; - color: rgb(80, 80, 80); - padding-right: 20px; - margin-top: 9px; - overflow-y: auto; -} - -.numberOfComments{ - margin-bottom: 15px; -} - -.portOfPostName{ - margin: 0; - margin-top: 11px; -} - -.nameOfPost{ - font-size: 14px; - color: black; - padding-right: 20px; - margin-top: 9px; - overflow-y: auto; -} - -.timeAndAuthor{ - display: flex; - flex-direction: column; - width: auto; - margin-left: auto; - order: 2; -} - -.dateOfWriting{ - font-size: 7px; - color: rgb(80, 80, 80); - margin: 0; - padding: 0; - margin-top: 15px; - margin-left: auto; -} - -.postedBy{ - margin: 0; - padding: 0; - margin-top: 30px; - font-size: 7px; - color: rgb(80, 80, 80); -} - -.authorDetails{ - display: flex; -} - -.roundImage{ - margin: 0; - padding: 0; - margin-top: 3px; - margin-bottom: 15px; - font-size: 0; - border: 0; - border-radius: 100%; - width: 25px; - height: 25px; -} - -.usernameOfAuthor{ - color: #7b2240; - font-size: 9px; - margin: 0; - padding: 0; - margin-left: 5px; - overflow-y: auto; - margin-top: 9px; -} +@media screen and (min-aspect-ratio: 13/9) { + + .flexTitle{ + display: flex; + position: relative; + margin-bottom: 15px; + margin-left: 7vmin; + } + + .page + { + background-color: #d2bdc5; /* Slight Maroon */ + margin-top: calc(4.5vh + 4.5vw); + border-bottom: solid #7B2240; + border-bottom-width: 1px; + text-align: center; + padding: 9px; + padding-left: 15px; + padding-right: 15px; + width: auto; + height: auto; + font-family: inherit; + font-size: 0; + font-weight: bold; + color: #7B2240; + display: inline-block; + } + + .pageTitle{ + margin: 0; + font-size: 9px; + letter-spacing: 1px; + } + + .searchResultsMessage{ + margin: 0; + margin-bottom: 10px; + padding: 0; + text-align: center; + color: black; + font-size: 15px; + } + + .createPostBtn{ + font-family: 'Roboto', Sans-Serif; + margin-top: calc(4.8vh + 4.8vw); + text-align: center; + border-radius: 3px; + border: 0; + background-color: #757575; + color: #ececec; + font-size: 9px; + font-weight: normal; + letter-spacing: 0.5px; + padding: 8.5px; + padding-left: 20px; + padding-right: 20px; + cursor: pointer; + overflow: hidden; + width: auto; + position: absolute; + bottom: 0; + left: 260px; + } + + .sortByForm{ + margin-top: calc(4.8vh + 4.8vw); + position: absolute; + bottom: 0; + left: 380px; + } + + select{ + font-family: 'Roboto', Sans-Serif; + background-color: #dbdbdb; + color: black; + margin: 0; + padding: 7px; + border: 0; + border-radius: 3px; + box-shadow: 1px 1px 1px gray; + width: auto; + font-size: 12px; + } + + .post-section{ + margin: 0; + width: 500px; + height: auto; + background-color: #ded3d7; + border-radius: 5px; + position: relative; + margin-left: 7vmin; + box-shadow: 1px 1px 1px gray; + display: flex; + padding-left: 20px; + padding-right: 20px; + margin-bottom: 15px; + } + + .votes{ + display: flex; + flex-direction: column; + text-align: center; + margin-top: 25px; + margin-right: 20px; + } + + .numOfVotes{ + padding: 0; + margin: 0; + font-size: 15px; + } + + .upvote, .downvote{ + margin: 0; + padding: 0; + font-size: 0; + display: inline-block; + } + + .upvoteBtn, .downvoteBtn{ + letter-spacing: 1px; + margin: 0; + padding: 0; + font-size: 12px; + border: 0; + background-color: transparent; + cursor: pointer; + } + + .squareImage{ + width: 80px; + height: 80px; + border: 0; + border-radius: 3px; + margin: 10px; + margin-right: 20px; + margin-left: 0; + padding: 0; + } + + .description{ + display: flex; + flex-direction: column; + text-align: left; + } + + .portOfPostName, .postDescription, .numberOfComments{ + margin: 0; + font-size: 9px; + color: rgb(80, 80, 80); + padding-right: 20px; + margin-top: 9px; + overflow-y: auto; + } + + .numberOfComments{ + margin-bottom: 15px; + } + + .portOfPostName{ + margin: 0; + margin-top: 11px; + } + + .nameOfPost{ + font-size: 14px; + color: black; + padding-right: 20px; + margin-top: 9px; + overflow-y: auto; + } + + .timeAndAuthor{ + display: flex; + flex-direction: column; + width: auto; + margin-left: auto; + order: 2; + } + + .dateOfWriting{ + font-size: 7px; + color: rgb(80, 80, 80); + margin: 0; + padding: 0; + margin-top: 15px; + margin-left: auto; + } + + .postedBy{ + margin: 0; + padding: 0; + margin-top: 30px; + font-size: 7px; + color: rgb(80, 80, 80); + } + + .authorDetails{ + display: flex; + } + + .roundImage{ + margin: 0; + padding: 0; + margin-top: 3px; + margin-bottom: 15px; + font-size: 0; + border: 0; + border-radius: 100%; + width: 25px; + height: 25px; + } + + .usernameOfAuthor{ + color: #7b2240; + font-size: 9px; + margin: 0; + padding: 0; + margin-left: 5px; + overflow-y: auto; + margin-top: 9px; + } + +} /* Close Media Query */ + +@media screen and (max-aspect-ratio: 13/9) { + + .flexTitle{ + display: flex; + flex-direction: column; + position: relative; + margin: auto; + margin-bottom: 4vh; + text-align: center; + } + + .page + { + margin: auto; + background-color: #d2bdc5; /* Slight Maroon */ + margin-top: 4vh; + border-bottom: solid #7B2240; + border-bottom-width: 0.5vw; + text-align: center; + padding: 2.5vw; + padding-left: 3vw; + padding-right: 3vw; + width: 50%; + height: auto; + font-family: inherit; + font-size: 0; + font-weight: bold; + color: #7B2240; + display: inline-block; + } + + .pageTitle{ + margin: 0; + font-size: 3vw; + letter-spacing: 0.25vw; + } + + .searchResultsMessage{ + margin: 0; + margin-bottom: 2.5vw; + padding: 0; + text-align: center; + color: black; + font-size: 3vw; + } + + .createPostBtn{ + font-family: 'Roboto', Sans-Serif; + margin-top: 3vh; + text-align: center; + border-radius: 1vw; + border: 0; + background-color: #757575; + color: #ececec; + font-size: 3vw; + font-weight: normal; + letter-spacing: 0.2vw; + padding: 2.5vw; + cursor: pointer; + overflow: hidden; + width: 30%; + box-shadow: 0.3vw 0.3vw 0.3vw grey; + } + + .sortByForm{ + margin-top: 3vh; + } + + select{ + font-family: 'Roboto', Sans-Serif; + background-color: #dbdbdb; + color: black; + margin: 0; + padding: 2vw; + border: 0; + border-radius: 1vw; + box-shadow: 0.3vw 0.3vw 0.3vw gray; + width: 40%; + font-size: 4vw; + text-align-last: center; + } + + .post-section{ + margin: auto; + width: 85%; + height: auto; + background-color: #ded3d7; + border-radius: 1vw; + position: relative; + box-shadow: 0.3vw 0.3vw 0.3vw gray; + display: flex; + padding-left: 5%; + padding-right: 5%; + margin-bottom: 5vw; + justify-content: space-evenly; + flex-wrap: wrap; + } + + .votes{ + display: flex; + flex-direction: column; + text-align: center; + margin-top: 10vw; + } + + .numOfVotes{ + padding: 0; + margin: 0; + font-size: 4vw; + } + + .upvote, .downvote{ + margin: 0; + padding: 0; + font-size: 0; + display: inline-block; + } + + .upvoteBtn, .downvoteBtn{ + letter-spacing: 0.2vw; + margin: 0; + padding: 0; + font-size: 3vw; + border: 0; + background-color: transparent; + cursor: pointer; + } + + .squareImage{ + width: 30vw; + height: 30vw; + border: 0; + border-radius: 1vw; + margin: 3vw; + margin-left: 0; + margin-right: 0; + padding: 0; + } + + .description{ + display: flex; + flex-direction: column; + text-align: left; + order: 2; + flex-shrink: 0; + width: 100%; + } + + .portOfPostName, .postDescription, .numberOfComments{ + margin: 0; + font-size: 3vw; + color: rgb(80, 80, 80); + margin-top: 2vw; + overflow-y: auto; + } + + .numberOfComments{ + margin-bottom: 2vw; + } + + .portOfPostName{ + margin: 0; + } + + .nameOfPost{ + font-size: 4.5vw; + color: black; + margin-top: 2vw; + overflow-y: auto; + } + + .timeAndAuthor{ + display: flex; + flex-direction: column; + width: max-content; + } + + .dateOfWriting{ + font-size: 3vw; + color: rgb(80, 80, 80); + margin: 0; + padding: 0; + margin-top: 3vw; + } + + .postedBy{ + margin: 0; + padding: 0; + margin-top: 13vw; + font-size: 3vw; + color: rgb(80, 80, 80); + } + + .authorDetails{ + display: flex; + } + + .roundImage{ + margin: 0; + padding: 0; + margin-top: 1vw; + font-size: 0; + border: 0; + border-radius: 100%; + width: 8.5vw; + height: 8.5vw; + } + + .usernameOfAuthor{ + color: #7b2240; + font-size: 3vw; + margin: 0; + padding: 0; + margin-left: 1vw; + overflow-y: auto; + margin-top: 4vw; + } + +} /* Close Media Query */ diff --git a/app/static/css/stylesRegistPending.css b/app/static/css/stylesRegistPending.css index 83520db..79405b1 100644 --- a/app/static/css/stylesRegistPending.css +++ b/app/static/css/stylesRegistPending.css @@ -1,29 +1,59 @@ /* CSS Styles for the template: 'registPending.html' Version 1.0 - 08.05.2019 - Description: Creation of file - Front End Team */ -.page -{ - width: 70%; - margin-top: 23vmin; - margin-left: 21.5vmin; -} - -.welcome -{ - font-size: 24px; - text-align: left; - padding-bottom: 5px; -} - -.parag -{ - font-size: 12px; - text-align: left; -} \ No newline at end of file +/* Landscape Media Query */ +@media screen and (min-aspect-ratio: 13/9) { + + .page + { + width: 70%; + margin-top: 23vmin; + margin-left: 21.5vmin; + } + + .welcome + { + font-size: 24px; + text-align: left; + padding-bottom: 5px; + } + + .parag + { + font-size: 12px; + text-align: left; + } + +} /* Close Media Query */ + +/* Portrait Media Query */ +@media screen and (max-aspect-ratio: 13/9) { + + .page + { + margin: auto; + margin-top: 3vw; + width: 96%; + } + + .welcome + { + margin-top: 0.5vw; + margin-bottom: 2vw; + font-size: 6vw; + text-align: left; + padding-bottom: 1vw; + } + + .parag + { + font-size: 3vw; + text-align: left; + } + +} /* Close Media Query */ diff --git a/app/static/css/stylesRegister.css b/app/static/css/stylesRegister.css index bd9e684..746de50 100644 --- a/app/static/css/stylesRegister.css +++ b/app/static/css/stylesRegister.css @@ -1,107 +1,167 @@ /* CSS Styles for the template: 'register.html' -Version 1.0 +Version 1.1 + 08.12.2019 + Description: `errorMessages` class styling + smaller font size. +Version 1.0 08.09.2019 - Description: Creation of file - Front End Team */ - -.signup-wrap{ - margin: 2em auto 2em; - width: 70%; -} - -.panel-frame{ - width: auto; - height: auto; - margin-top: 100px; - padding: 0; - border: 0; - text-align: center; -} - -.header-wrapper{ - margin-top: 12px; - margin-bottom: 12px; -} - -.panel-content{ - text-align: left; -} - -h1{ - margin-bottom: -10px; - font-size: 25px; - font-weight: normal; -} - -.required{ - color: red; - font-size: 9px; - font-weight: bold; - letter-spacing: 1px; - margin-top: 15px; -} - -.first_name, .last_name, .usernameForm, .email, .password, .confirm_password, .addimage{ - width: 200px; - padding: 12px 11px 11px 11px; - margin-top: 7.5px; - margin-bottom: 12px; - margin-right: 10px; - border: 0.5px solid #8c918d; - border-radius: 3px; - font-size: 11px; -} - -.registFormButton{ - margin-left: 0.5em; - margin-top: 20px; - padding: 7px; - border: 1px solid #8c918d; - border-radius: 3px; - text-align: center; - display: block; - border: 0; - background-color: #757575; - color: white; - font-size: 8px; - width: 80px; - letter-spacing: 0.5px; - cursor: pointer; -} - -::placeholder{ - color: black; -} - -.space{ - margin-left: 1em; -} - -.bottom{ - text-align: center; -} - -.errUsernameInUse{ - color: red; -} - -.imageLabel{ - background-color: #757575; - color: white; - cursor: pointer; - font-size: 8px; - font-weight: normal; - border: 0; - border-radius: 3px; - letter-spacing: 0.55px; - padding-top: 7px; - padding-bottom: 7px; - padding-left: 17px; - padding-right: 17px; - text-align: center; - margin-left: 0.5em; -} +/* Landscape Media Query */ +@media screen and (min-aspect-ratio: 13/9) +{ + + .signup-wrap{ + margin: 2em auto 2em; + width: 70%; + } + + .panel-frame{ + width: auto; + height: auto; + margin-top: 100px; + padding: 0; + border: 0; + text-align: center; + } + + .header-wrapper{ + margin-top: 12px; + margin-bottom: 12px; + } + + .panel-content{ + text-align: left; + } + + h1{ + margin-bottom: -10px; + font-size: 25px; + font-weight: normal; + } + + .required{ + color: red; + font-size: 9px; + font-weight: bold; + letter-spacing: 1px; + margin-top: 15px; + } + + .first_name, .last_name, .usernameForm, .email, .password, .confirm_password, .addimage{ + width: 200px; + padding: 12px 11px 11px 11px; + margin-top: 7.5px; + margin-bottom: 12px; + margin-right: 10px; + border: 0.5px solid #8c918d; + border-radius: 3px; + font-size: 11px; + } + + .registFormButton{ + margin-left: 0.5em; + margin-top: 20px; + padding: 7px; + border: 1px solid #8c918d; + border-radius: 3px; + text-align: center; + display: block; + border: 0; + background-color: #757575; + color: white; + font-size: 8px; + width: 80px; + letter-spacing: 0.5px; + cursor: pointer; + } + + ::placeholder{ + color: black; + } + + .errorMessages{ + color: red; + font-size: 12px; + } + +} /* Close Media Query */ + +/* Portrait Media Query */ +@media screen and (max-aspect-ratio: 13/9) +{ + + .signup-wrap{ + margin: auto; + } + + .panel-frame{ + width: auto; + height: auto; + margin-top: 5vw; + padding: 0; + border: 0; + text-align: center; + } + + .header-wrapper{ + margin-bottom: 3vw; + } + + .panel-content{ + text-align: center; + margin: auto; + } + + h1{ + margin-bottom: -2vw; + font-size: 8vw; + font-weight: normal; + } + + .required{ + color: red; + font-size: 3vw; + font-weight: bold; + letter-spacing: 0.2vw; + } + + .first_name, .last_name, .usernameForm, .email, .password, .confirm_password, .addimage{ + width: 80%; + padding: 3vw; + margin-top: 2.5vw; + margin-bottom: 2.5vw; + border: 0.5px solid #8c918d; + border-radius: 1vw; + font-size: 4vw; + } + + .registFormButton{ + margin-top: 4vw; + margin-bottom: 4vw; + padding: 3vw; + border: 1px solid #8c918d; + border-radius: 1vw; + text-align: center; + border: 0; + background-color: #757575; + color: white; + font-size: 4vw; + width: 30%; + letter-spacing: 0.2vw; + cursor: pointer; + box-shadow: 1px 1px 1px lightgrey; + } + + ::placeholder{ + color: black; + } + + .errorMessages{ + color: red; + font-size: 4vw; + } + +} /* Close Media Query */ diff --git a/app/static/css/stylesUserInfo.css b/app/static/css/stylesUserInfo.css index 42d3803..52f5349 100644 --- a/app/static/css/stylesUserInfo.css +++ b/app/static/css/stylesUserInfo.css @@ -1,388 +1,1209 @@ /* CSS Styles for the template: 'userInfo.html' Version 1.0 - 08.12.2019 - Description: Creation of file - Front End Team */ -.middleScreen{ - display: flex; - width: 63%; - flex-direction: column; - margin-top: calc(6vh + 6vw); - margin-left: 14vmin; -} - -.page -{ - background-color: #d2bdc5; /* Slightly Dark Pink */ - border-bottom: solid #7B2240; - border-bottom-width: 1px; - text-align: center; - padding: 10px; - padding-left: 25px; - padding-right: 25px; - max-width: 110px; - width: auto; - font-family: inherit; - font-size: 9px; - font-weight: bold; - color: #7B2240; - letter-spacing: 1px; -} - -.pageTitle{ - padding: 0; - margin: 0; -} - -.divText -{ - margin: 0; - margin-top: 10px; - margin-bottom: 15px; - padding: 25px; - padding-bottom: 0; - width: auto; - height: auto; - background-color: #E3E3E3; - border-radius: 5px; - box-shadow: 1px 1px 1px lightgray, -1px -1px 1px lightgray; - display: flex; - flex-direction: column; -} - -.maroonButtons{ - margin: 0; - margin-top: -25px; - margin-left: -25px; - margin-right: -25px; - padding: 3px; - padding-left: 15px; - padding-right: 15px; - display: flex; - justify-content: space-between; - background-color: #7B2240; - border-top-left-radius: 5px; - border-top-right-radius: 5px; - width: auto; - margin-bottom: 25px; -} - -.userProfileTitle, .emailAndPasswordDiv, .notificationsDiv{ - margin: 0; - padding: 0; - background-color: #863550; - width: 210px; - height: 25px; - border-bottom: 1px solid #d2c4c9; - text-align: center; - border-top-left-radius: 3px; - border-top-right-radius: 3px; - margin-bottom: -3px; -} - -.userProfileTitleText, .emailAndPasswordText, .notificationsText{ - border: 0; - background-color: #863550; - margin: 0; - padding: 0; - font-size: 11px; - padding-top: 4px; - color: #d2c4c9; - display: inline-block; - vertical-align: middle; - line-height: normal; - letter-spacing: 0.5px; -} - -.emailAndPasswordText, .notificationsText{ - cursor: pointer; -} - -.editProfile{ - margin: 0; - padding: 0; - order: 2; - margin-left: auto; - margin-right: 0; -} - -.editProfileBtn, .descriptionFormSubmitBtn, .changeEmailBtn, .changePasswordBtn{ - text-align: center; - background-color: #757575; - border-radius: 3px; - border: 0; - color: white; - font-size: 8.5px; - width: auto; - height: auto; - padding: 6px; - padding-left: 10px; - padding-right: 10px; - letter-spacing: 0.5px; - cursor: pointer; - margin-left: auto; - margin-right: 0; -} - -.descriptionFormSubmitBtn{ - margin-top: 15px; -} - -.changeEmailBtn, .changePasswordBtn{ - margin-bottom: 30px; -} - -.profileContent{ - margin: 0; - display: flex; -} - -.roundImage{ - margin: 0; - padding: 0; - font-size: 0; - border: 0; - border-radius: 100%; - width: 35px; - height: 35px; -} - -.usernameAndEmailFlex{ - display: flex; - flex-direction: column; - margin-left: 7px; -} - -.viewedUserUsername{ - color: #b78296; - font-size: 14px; - margin: 0; - padding: 0; - margin-left: 5px; - margin-bottom: 7px; - overflow-y: auto; -} - -.viewedUserEmail{ - margin: 0; - color: black; - font-size: 9px; - margin-left: 5px; - overflow-y: auto; -} - -.viewedUserDescription{ - margin: 0; - width: auto; - padding-top: 20px; - padding-bottom: 20px; - padding-left: 55px; - padding-right: 55px; -} - -.descriptionText{ - letter-spacing: 0.5px; - color: black; - font-size: 13px; -} - -.descriptionForm{ - display: none; -} - -.descriptionTextArea, .avatarURL{ - margin: 0; - margin-top: 10px; - margin-bottom: 10px; - border: 0.5px solid LightGray; - padding-left: 10px; - padding-top: 5px; - padding-right: 10px; - padding-bottom: 5px; - width: 100%; - border-radius: 3px; - font-family: 'Roboto', Sans-Serif; - font-size: 13px; -} - -.descriptionTextArea::placeholder{ - color: black; important! -} - -.descriptionFormSubmitDiv{ - display: flex; - flex-direction: column; - justify-content: flex-end; -} - -.settingsContent{ - display: flex; - flex-direction: column; -} - -.privateEmail, .privateEmailFlex{ - display: flex; - flex-direction: row; -} - -.privateEmailLabel{ - display: flex; - flex-direction: column; -} - -.requiredFieldsMessage{ - /*order: 2;*/ - margin-left: auto; - margin-right: 0; -} - -.requiredFieldsMessageText{ - margin: 0; - margin-top: 10px; - font-size: 9px; - letter-spacing: 0.5px; - font-weight: bold; - color: red; -} - -.emailChangeTitle, .passwordChangeTitle{ - margin: 0; - border: 0; - border-bottom: 0.5px solid black; - font-size: 9px; - font-weight: bold; - letter-spacing: 0.5px; -} - -.privateEmailLabelTextUpperLabel, .privateEmailLabelTextLowerLabel{ - margin: 0; - padding: 0; - margin-left: 10px; -} - -.privateEmailLabelTextUpperLabel{ - font-size: 13px; - margin-bottom: 3px; - margin-top: -3px; - letter-spacing: 0.5px; -} - -.privateEmailLabelTextLowerLabel{ - font-size: 9px; - letter-spacing: 0.5px; -} - -.privateEmailCheckbox{ - position: relative; -} - -/* The container */ -.container { - display: block; - position: relative; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.container input[type="checkbox"]{ - opacity: 0; - cursor: pointer; -} - -/* Create a custom checkbox */ -.checkmark { - position: absolute; - top: 0; - left: 0; - height: 15px; - width: 15px; - border: 2px solid #7B2240; -} - -/* When the checkbox is checked, add a blue background */ -.container input[type="checkbox"]:checked ~ .checkmark { - background-color: transparent; -} - -/* Create the checkmark/indicator (hidden when not checked) */ -.container .checkmark:after { - content: ""; - position: absolute; - display: none; -} - -/* Show the checkmark when checked */ -.container input[type="checkbox"]:checked ~ .checkmark:after { - display: block; -} - -/* Style the checkmark/indicator */ -.checkmark:after { - left: 4px; - top: 1px; - width: 4px; - height: 8px; - color: #7B2240; - border: solid #7B2240;; - border-width: 0 3px 3px 0; - -webkit-transform: rotate(45deg); - -ms-transform: rotate(45deg); - transform: rotate(45deg); -} - -.changeEmailInnerDiV, .changePasswordInnerDiv{ - display: flex; - flex-direction: column; -} - -.emailsDiv, .passwordsDiv{ - display: flex; - justify-content: space-between; -} - -.buttonDiv{ - order: 2; - margin-left: auto; - margin-right: 0; -} - -.emailSetting, .passwordSetting, .currentPassword{ - width: calc(15.5vmax - 4vmin); - padding: 12px 11px 11px 11px; - margin-top: 7.5px; - margin-bottom: 12px; - margin-right: 10px; - border: 0.5px solid #8c918d; - border-radius: 3px; - font-size: 11px; -} - -::placeholder{ - color: black; important! -} - -.red{ - color: red; - font-size: 9px; - font-weight: bold; -} - -.notify{ - margin-bottom: 20px; -} - -.errIncorrectPassword{ - color: red; - font-size: 12px; - margin: 0; - padding: 0; - margin-left: 15px; -} +/* Landscape Media Query */ +@media screen and (min-aspect-ratio: 13/9) { + + .middleScreen{ + display: flex; + width: 63%; + flex-direction: column; + margin-top: calc(6vh + 6vw); + margin-left: 14vmin; + } + + .page + { + background-color: #d2bdc5; /* Slightly Dark Pink */ + border-bottom: solid #7B2240; + border-bottom-width: 1px; + text-align: center; + padding: 10px; + padding-left: 25px; + padding-right: 25px; + max-width: 110px; + width: auto; + font-family: inherit; + font-size: 9px; + font-weight: bold; + color: #7B2240; + letter-spacing: 1px; + } + + .pageTitle{ + padding: 0; + margin: 0; + } + + .divText, .divText1 + { + margin: 0; + margin-top: 10px; + margin-bottom: 15px; + padding: 25px; + padding-bottom: 0; + width: auto; + height: auto; + background-color: #E3E3E3; + border-radius: 5px; + box-shadow: 1px 1px 1px lightgray, -1px -1px 1px lightgray; + display: flex; + flex-direction: column; + } + + .divText1{ + height: 400px; + overflow-y: auto; + } + + .maroonButtons{ + margin: 0; + margin-top: -25px; + margin-left: -25px; + margin-right: -25px; + padding: 3px; + padding-left: 15px; + padding-right: 15px; + display: flex; + justify-content: space-between; + background-color: #7B2240; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + width: auto; + margin-bottom: 25px; + overflow-y: auto; + } + + .userProfileTitle, .emailAndPasswordDiv, .notificationsDiv, .subscriptionsDiv, .commentsDiv, .savedDiv, .postsDiv{ + margin: 0; + padding: 0; + background-color: #863550; + width: 210px; + height: 25px; + border-bottom: 1px solid #d2c4c9; + text-align: center; + border-top-left-radius: 3px; + border-top-right-radius: 3px; + margin-bottom: -3px; + } + + .userProfileTitleText, .emailAndPasswordText, .notificationsText, .subscriptionsText, .commentsText, .savedText, .postsText{ + border: 0; + background-color: #863550; + margin: 0; + padding: 0; + font-size: 11px; + padding-top: 4px; + color: #d2c4c9; + display: inline-block; + vertical-align: middle; + line-height: normal; + letter-spacing: 0.5px; + } + + .emailAndPasswordText, .notificationsText, .subscriptionsText, .commentsText, .savedText, .postsText{ + cursor: pointer; + } + + .subscriptionsDiv, .commentsDiv, .savedDiv, .postsDiv{ + width: auto; + padding-left: 15px; + padding-right: 15px; + } + + .editProfile{ + margin: 0; + padding: 0; + order: 2; + margin-left: auto; + margin-right: 0; + } + + .editProfileBtn, .descriptionFormSubmitBtn, .changeEmailBtn, .changePasswordBtn{ + text-align: center; + background-color: #757575; + border-radius: 3px; + border: 0; + color: white; + font-size: 8.5px; + width: auto; + height: auto; + padding: 6px; + padding-left: 10px; + padding-right: 10px; + letter-spacing: 0.5px; + cursor: pointer; + margin-left: auto; + margin-right: 0; + } + + .descriptionFormSubmitBtn{ + margin-top: 15px; + } + + .changeEmailBtn, .changePasswordBtn{ + margin-bottom: 30px; + } + + .profileContent{ + margin: 0; + display: flex; + } + + .roundImage{ + margin: 0; + padding: 0; + font-size: 0; + border: 0; + border-radius: 100%; + width: 35px; + height: 35px; + } + + .usernameAndEmailFlex{ + display: flex; + flex-direction: column; + margin-left: 7px; + } + + .viewedUserUsername{ + color: #b78296; + font-size: 14px; + margin: 0; + padding: 0; + margin-left: 5px; + margin-bottom: 7px; + overflow-y: auto; + } + + .viewedUserEmail{ + margin: 0; + color: black; + font-size: 9px; + margin-left: 5px; + overflow-y: auto; + } + + .viewedUserDescription{ + margin: 0; + width: auto; + padding-top: 20px; + padding-bottom: 20px; + padding-left: 55px; + padding-right: 55px; + } + + .descriptionText{ + letter-spacing: 0.5px; + color: black; + font-size: 13px; + overflow-x: auto; + } + + .descriptionForm{ + display: none; + } + + .descriptionTextArea, .avatarURL{ + margin: 0; + margin-top: 10px; + margin-bottom: 10px; + border: 0.5px solid LightGray; + padding-left: 10px; + padding-top: 5px; + padding-right: 10px; + padding-bottom: 5px; + width: 100%; + border-radius: 3px; + font-family: 'Roboto', Sans-Serif; + font-size: 13px; + } + + .descriptionTextArea::placeholder{ + color: black; important! + } + + .descriptionFormSubmitDiv{ + display: flex; + flex-direction: column; + justify-content: flex-end; + } + + .settingsContent{ + display: flex; + flex-direction: column; + } + + .privateEmail, .privateEmailFlex{ + display: flex; + flex-direction: row; + } + + .privateEmailLabel{ + display: flex; + flex-direction: column; + } + + .requiredFieldsMessage{ + /*order: 2;*/ + margin-left: auto; + margin-right: 0; + } + + .requiredFieldsMessageText{ + margin: 0; + margin-top: 10px; + font-size: 9px; + letter-spacing: 0.5px; + font-weight: bold; + color: red; + } + + .emailChangeTitle, .passwordChangeTitle{ + margin: 0; + border: 0; + border-bottom: 0.5px solid black; + font-size: 9px; + font-weight: bold; + letter-spacing: 0.5px; + } + + .privateEmailLabelTextUpperLabel, .privateEmailLabelTextLowerLabel{ + margin: 0; + padding: 0; + margin-left: 10px; + } + + .privateEmailLabelTextUpperLabel{ + font-size: 13px; + margin-bottom: 3px; + margin-top: -3px; + letter-spacing: 0.5px; + } + + .privateEmailLabelTextLowerLabel{ + font-size: 9px; + letter-spacing: 0.5px; + } + + .privateEmailCheckbox{ + position: relative; + } + + /* The container */ + .container { + display: block; + position: relative; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + + .container input[type="checkbox"]{ + opacity: 0; + cursor: pointer; + } + + /* Create a custom checkbox */ + .checkmark { + position: absolute; + top: 0; + left: 0; + height: 15px; + width: 15px; + border: 2px solid #7B2240; + } + + /* When the checkbox is checked, add a blue background */ + .container input[type="checkbox"]:checked ~ .checkmark { + background-color: transparent; + } + + /* Create the checkmark/indicator (hidden when not checked) */ + .container .checkmark:after { + content: ""; + position: absolute; + display: none; + } + + /* Show the checkmark when checked */ + .container input[type="checkbox"]:checked ~ .checkmark:after { + display: block; + } + + /* Style the checkmark/indicator */ + .checkmark:after { + left: 4px; + top: 1px; + width: 4px; + height: 8px; + color: #7B2240; + border: solid #7B2240;; + border-width: 0 3px 3px 0; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); + } + + .changeEmailInnerDiV, .changePasswordInnerDiv{ + display: flex; + flex-direction: column; + overflow-x: auto; + } + + .emailsDiv, .passwordsDiv{ + display: flex; + justify-content: space-between; + } + + .buttonDiv{ + order: 2; + margin-left: auto; + margin-right: 0; + } + + .emailSetting, .passwordSetting, .currentPassword{ + width: 180px; + padding: 12px 11px 11px 11px; + margin-top: 7.5px; + margin-bottom: 12px; + margin-right: 10px; + border: 0.5px solid #8c918d; + border-radius: 3px; + font-size: 11px; + } + + ::placeholder{ + color: black; important! + } + + .red{ + color: red; + font-size: 9px; + font-weight: bold; + } + + .notify{ + margin-bottom: 20px; + } + + .errIncorrectPassword{ + color: red; + font-size: 12px; + margin: 0; + padding: 0; + margin-left: 15px; + } + + .portMembersNumber{ + margin: 0; + } + + .port-section, .comment-section, .post-section{ + margin: 0; + padding: 10px; + padding-left: 25px; + padding-right: 25px; + border-radius: 3px; + box-shadow: 1px 1px 1px gray; + margin-bottom: 10px; + overflow-y: auto; + display: flex; + justify-content: flex-start; + min-height: 30px; + } + + .comment-section, .post-section{ + padding: 5px; + padding-left: 10px; + padding-right: 10px; + } + + .portName{ + margin: 0; + padding: 0; + margin-top: 2px; + padding-bottom: 10px; + font-size: 16px; + color: rgb(80, 80, 80); + overflow-y: auto; + } + + .portMembersNumber{ + margin: 0; + padding: 0; + margin-top: 7px; + font-size: 8.5px; + color: rgb(80, 80, 80); + overflow-y: auto; + } + + .indexForm{ + margin: 0; + padding: 0; + font-size: 0; + } + + .subscribeIndex{ + text-align: center; + border-radius: 3px; + border: 0; + color: white; + font-size: 8.5px; + width: 70px; + height: auto; + padding: 6px; + letter-spacing: 0.5px; + cursor: pointer; + } + + .portFirstPart{ + width: 150px; + } + + .portThirdPart{ + margin-left: auto; + margin-right: 0; + } + + .commentSecondPart, .postSecondPart{ + display:flex; + flex-direction:column; + width: 80%; + } + + .votes{ + margin: 0; + font-size: 12px; + color: rgb(77, 208, 191); + margin-top: 5px; + } + + .thePortName{ + color: rgb(80, 80, 80); + font-size: 7px; + margin-right: 10px; + margin-top: 8px; + } + + .thePostName{ + margin: 0; + color: black; + font-size: 11px; + } + + .commentText, .postText{ + margin: 0; + color: black; + font-size: 8px; + overflow-y: auto; + padding-top: 5px; + } + + + .dateAndTime{ + margin: 0; + color: rgb(80, 80, 80); + font-size: 8px; + min-width: max-content; + } + + .commentFirstPart, .postFirstPart{ + text-align: center; + width: 30px; + margin-left: -8px; + } + + .commentThirdPart, .postThirdPart{ + margin-left: auto; + margin-right: 0; + order: 2; + } + + .postThirdPart{ + display:flex; + flex-direction:column; + } + + .authorDetails{ + display: flex; + } + + .roundImage{ + margin: 0; + padding: 0; + margin-top: 3px; + font-size: 0; + border: 0; + border-radius: 100%; + width: 25px; + height: 25px; + } + + .usernameOfAuthor{ + color: #7b2240; + font-size: 9px; + margin: 0; + padding: 0; + margin-left: 5px; + margin-top: 9px; + } + + .numOfComments{ + margin: 0; + color: rgb(80, 80, 80); + font-size: 7px; + margin-right: 10px; + margin-top: 8px; + } + + .squareImage{ + width: 30px; + height: 30px; + border: 0; + border-radius: 3px; + margin-right: 10px; + margin-left: 0; + padding: 0; + } + + .postFourthPart{ + display:flex; + flex-direction:column; + } + + .postFifthPart{ + margin-left: auto; + margin-right: 0; + order: 2; + } + + .thePortNameDiv{ + margin-top: 3px; + } + + .postDescription{ + margin: 0; + font-size: 8px; + color: black; + margin-left: 5px; + margin-top: 6px; + } + +} /* Close Media Query */ + +/* Portrait Media Query */ +@media screen and (max-aspect-ratio: 13/9) { + + .middleScreen{ + display: flex; + width: 96%; + margin: auto; + flex-direction: column; + margin-top: 3vw; + } + + .page + { + margin: auto; + background-color: #d2bdc5; + border-bottom: solid #7B2240; + border-bottom-width: 0.5vw; + text-align: center; + padding: 2.5vw; + padding-left: 3vw; + padding-right: 3vw; + width: 50%; + font-family: inherit; + font-size: 3vw; + font-weight: bold; + color: #7B2240; + letter-spacing: 0.3vw; + } + + .pageTitle{ + padding: 0; + margin: 0; + } + + .divText, .divText1 + { + margin: 0; + margin-top: 3vw; + margin-bottom: 3vw; + padding: 3vw; + padding-bottom: 0; + width: auto; + height: auto; + background-color: #E3E3E3; + border-radius: 1vw; + box-shadow: 0.3vw 0.3vw 0.3vw lightgrey, -0.3vw -0.3vw 0.3vw lightgrey; + display: flex; + flex-direction: column; + } + + .divText1{ + overflow-y: auto; + } + + .maroonButtons{ + margin: 0; + margin-top: -3vw; + margin-left: -3vw; + margin-right: -3vw; + padding: 1vw; + padding-left: 3vw; + padding-right: 3vw; + display: flex; + justify-content: space-between; + background-color: #7B2240; + border-top-left-radius: 1vw; + border-top-right-radius: 1vw; + width: auto; + margin-bottom: 3vw; + overflow-y: auto; + height: 7.5vw; + } + + .userProfileTitle, .emailAndPasswordDiv, .notificationsDiv, .subscriptionsDiv, .commentsDiv, .savedDiv, .postsDiv{ + margin: 0; + padding: 0; + background-color: #863550; + width: 42vw; + border-bottom: 0.5vw solid #d2c4c9; + text-align: center; + border-top-left-radius: 0.5vw; + border-top-right-radius: 0.5vw; + margin-bottom: -1vw; + } + + .userProfileTitleText, .emailAndPasswordText, .notificationsText, .subscriptionsText, .commentsText, .savedText, .postsText{ + border: 0; + background-color: #863550; + margin: 0; + padding: 0; + font-size: 3.5vw; + height: 6vw; + padding-top: 2vw; + color: #d2c4c9; + display: inline-block; + vertical-align: middle; + line-height: normal; + letter-spacing: 0.25vw; + } + + .subscriptionsText, .commentsText, .savedText, .postsText{ + font-size: 2.5vw; + } + + .emailAndPasswordText, .notificationsText, .subscriptionsText, .commentsText, .savedText, .postsText{ + cursor: pointer; + } + + .subscriptionsDiv, .commentsDiv, .savedDiv, .postsDiv{ + width: auto; + padding-left: 2.5vw; + padding-right: 2.5vw; + } + + .editProfile{ + margin: 0; + padding: 0; + order: 2; + margin-left: auto; + margin-right: 0; + } + + .editProfileBtn, .descriptionFormSubmitBtn, .changeEmailBtn, .changePasswordBtn{ + text-align: center; + background-color: #757575; + border-radius: 1vw; + border: 0; + color: white; + font-size: 3vw; + width: auto; + height: auto; + padding: 2vw; + padding-left: 3vw; + padding-right: 3vw; + letter-spacing: 0.1vw; + cursor: pointer; + margin-left: auto; + margin-right: 0; + } + + .descriptionFormSubmitBtn{ + margin-top: 3vw; + } + + .changeEmailBtn, .changePasswordBtn{ + margin-bottom: 4vw; + } + + .profileContent{ + margin: 0; + display: flex; + } + + .roundImage{ + margin: 0; + padding: 0; + margin-top: 1vw; + font-size: 0; + border: 0; + border-radius: 100%; + width: 6vw; + height: 6vw; + } + + .usernameAndEmailFlex{ + display: flex; + flex-direction: column; + margin-left: 1vw; + } + + .viewedUserUsername{ + color: #b78296; + font-size: 4vw; + margin: 0; + padding: 0; + margin-left: 1vw; + margin-bottom: 1.5vw; + overflow-y: auto; + } + + .viewedUserEmail{ + margin: 0; + color: black; + font-size: 2.5vw; + margin-left: 1vw; + overflow-y: auto; + } + + .viewedUserDescription{ + margin: 0; + width: auto; + padding-top: 5vw; + padding-bottom: 5vw; + padding-left: 12.5vw; + padding-right: 12.5vw; + } + + .descriptionText{ + letter-spacing: 0.2vw; + color: black; + font-size: 3.5vw; + overflow-x: auto; + } + + .descriptionForm{ + display: none; + } + + .descriptionTextArea, .avatarURL{ + margin: 0; + margin-top: 2.5vw; + margin-bottom: 2.5vw; + border: 0.15vw solid LightGray; + padding-left: 2.5vw; + padding-top: 1.75vw; + padding-right: 2.5vw; + padding-bottom: 1.75vw; + width: 100%; + border-radius: 1vw; + font-family: 'Roboto', Sans-Serif; + font-size: 3.5vw; + letter-spacing: 0.2vw; + } + + .descriptionTextArea::placeholder{ + color: black; important! + } + + .descriptionFormSubmitDiv{ + display: flex; + flex-direction: column; + justify-content: flex-end; + } + + .settingsContent{ + display: flex; + flex-direction: column; + } + + .privateEmail, .privateEmailFlex{ + display: flex; + flex-direction: row; + } + + .privateEmailLabel{ + display: flex; + flex-direction: column; + margin-left: 3vw; + } + + .requiredFieldsMessage{ + margin-left: auto; + margin-right: 0; + } + + .requiredFieldsMessageText{ + margin: 0; + margin-top: 3vw; + font-size: 2.5vw; + letter-spacing: 0.2vw; + font-weight: bold; + color: red; + } + + .emailChangeTitle, .passwordChangeTitle{ + margin: 0; + margin-top: 2vw; + border: 0; + border-bottom: 0.3vw solid black; + font-size: 3vw; + font-weight: bold; + letter-spacing: 0.1vw; + } + + .privateEmailLabelTextUpperLabel, .privateEmailLabelTextLowerLabel{ + margin: 0; + padding: 0; + margin-left: 2.5vw; + } + + .privateEmailLabelTextUpperLabel{ + font-size: 4vw; + margin-bottom: 0.8vw; + margin-top: -0.9vw; + letter-spacing: 0.2vw; + } + + .privateEmailLabelTextLowerLabel{ + font-size: 3vw; + letter-spacing: 0.2vw; + } + + .privateEmailCheckbox{ + position: relative; + } + + /* The container */ + .container { + display: block; + position: relative; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + + .container input[type="checkbox"]{ + opacity: 0; + cursor: pointer; + } + + /* Create a custom checkbox */ + .checkmark { + position: absolute; + top: 0; + left: 0; + height: 6vw; + width: 6vw; + border: 0.8vw solid #7B2240; + } + + /* When the checkbox is checked, add a blue background */ + .container input[type="checkbox"]:checked ~ .checkmark { + background-color: transparent; + } + + /* Create the checkmark/indicator (hidden when not checked) */ + .container .checkmark:after { + content: ""; + position: absolute; + display: none; + } + + /* Show the checkmark when checked */ + .container input[type="checkbox"]:checked ~ .checkmark:after { + display: block; + } + + /* Style the checkmark/indicator */ + .checkmark:after { + left: 1.5vw; + width: 2vw; + height: 4vw; + color: #7B2240; + border: solid #7B2240; + border-width: 0 0.8vw 0.8vw 0; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); + } + + .changeEmailInnerDiV, .changePasswordInnerDiv{ + display: flex; + flex-direction: column; + overflow-x: auto; + } + + .emailsDiv, .passwordsDiv{ + display: flex; + flex-direction: column; + justify-content: space-between; + margin: auto; + margin-top: 2.5vw; + margin-bottom: 2.5vw; + width: 96%; + text-align: center; + } + + .currentPasswordDiv { + margin: auto; + margin-top: 3vw; + margin-bottom: -1.5vw; + width: 96%; + text-align: center; + } + + .buttonDiv{ + order: 2; + margin: auto; + } + + .emailSetting, .passwordSetting, .currentPassword{ + width: 95%; + padding: 3vw; + margin-right: 2vw; + margin-bottom: 3vw; + border: 0.5px solid #8c918d; + border-radius: 1vw; + font-size: 3.5vw; + } + + ::placeholder{ + color: black; important! + } + + .red{ + color: red; + font-size: 2.5vw; + font-weight: bold; + } + + .notify{ + margin-bottom: 5vw; + } + + .errIncorrectPassword{ + color: red; + font-size: 3vw; + margin: 0; + padding: 0; + } + + .portMembersNumber{ + margin: 0; + } + + .port-section, .comment-section, .post-section{ + margin: 0; + padding: 2vw; + padding-left: 5vw; + padding-right: 5vw; + border-radius: 1vw; + box-shadow: 0.3vw 0.3vw 0.3vw grey; + margin-bottom: 3vw; + overflow-y: auto; + display: flex; + justify-content: flex-start; + min-height: 5vw; + flex-wrap: wrap; + } + + .comment-section, .post-section{ + padding: 1vw; + padding-left: 2vw; + padding-right: 2vw; + } + + .portName{ + margin: 0; + padding: 0; + font-size: 3.5vw; + color: rgb(80, 80, 80); + overflow-y: auto; + } + + .portMembersNumber{ + margin: 0; + padding: 0; + margin-top: 1.2vw; + font-size: 2.5vw; + color: rgb(80, 80, 80); + overflow-y: auto; + } + + .indexForm{ + margin: 0; + padding: 0; + font-size: 0; + } + + .subscribeIndex{ + text-align: center; + border-radius: 1vw; + border: 0; + color: white; + font-size: 2vw; + height: auto; + padding: 4vw; + padding-top: 1.5vw; + padding-bottom: 1.5vw; + letter-spacing: 0.3vw; + cursor: pointer; + } + + .portFirstPart{ + width: 40%; + } + + .portThirdPart{ + margin-left: auto; + margin-right: 0; + } + + .commentSecondPart, .postSecondPart{ + display: flex; + flex-direction: column; + width: 80%; + } + + .second{ + width: auto; + } + + .votes{ + margin: 0; + font-size: 3vw; + color: rgb(77, 208, 191); + margin-top: 0.8vw; + margin-right: 2vw; + } + + .thePortName{ + color: rgb(80, 80, 80); + font-size: 2vw; + margin-right: 2vw; + min-width: max-content; + } + + .thePostName{ + margin: 0; + color: black; + font-size: 3vw; + min-width: max-content; + } + + .commentText, .postText{ + margin: 0; + color: black; + font-size: 2vw; + margin-left: 3vw; + overflow-y: auto; + padding-top: 1vw; + min-width: max-content; + } + + + .dateAndTime{ + margin: 0; + color: rgb(80, 80, 80); + font-size: 2vw; + min-width: max-content; + } + + .commentFirstPart, .postFirstPart{ + text-align: center; + } + + .commentThirdPart, .postThirdPart{ + margin-left: auto; + margin-right: 0; + order: 2; + } + + .postThirdPart{ + display: flex; + flex-direction: column; + } + + .authorDetails{ + display: flex; + } + + .usernameOfAuthor{ + color: #7b2240; + font-size: 2vw; + margin: 0; + padding: 0; + margin-left: 1vw; + margin-top: 2vw; + } + + .numOfComments{ + margin: 0; + color: rgb(80, 80, 80); + font-size: 2vw; + margin-right: 2vw; + margin-top: 2vw; + min-width: max-content; + } + + .squareImage{ + width: 8vw; + height: 8vw; + border: 0; + border-radius: 1vw; + margin-right: 2vw; + margin-left: 0; + padding: 0; + } + + .postFourthPart{ + display: flex; + flex-direction: column; + order: 2; + flex-shrink: 0; + width: 100%; + margin-top: 2vw; + } + + .postFifthPart{ + margin-left: auto; + margin-right: 0; + } + + .thePortNameDiv{ + margin-top: 0.7vw; + } + + .postDescription{ + margin: 0; + font-size: 2.5vw; + letter-spacing: 0.1vw; + color: black; + margin-top: 1vw; + } + +} /* Close Media Query */ diff --git a/app/static/css/stylesWritePost.css b/app/static/css/stylesWritePost.css index 9418e07..6a41423 100644 --- a/app/static/css/stylesWritePost.css +++ b/app/static/css/stylesWritePost.css @@ -1,115 +1,185 @@ /* CSS Styles for the template: 'writePost.html' Version 1.0 - 08.08.2019 - Description: Creation of file - Front End Team */ -.container -{ - margin-top: 25vmin; - margin-bottom: calc(1vh + 1vw); - margin-left: 11vmin; - padding: 40px; - padding-top: 25px; - padding-bottom: 10px; - width: 55%; - height: auto; - background-color: #E3E3E3; - border-radius: calc(0.2vh + 0.2vw); - box-shadow: 1px 1px 1px lightgray, -1px -1px 1px lightgray; -} - -input, textarea{ - font-size: 8px; - font-weight: normal; - border-width: 0.5px; - border-radius: 3px; - border-style: solid; - border-color: rgb(192,192,192); - font-family: 'Roboto'; - position: relative; - margin: 0; - padding: 10px 10px; - margin-bottom: 10px; - width: 98%; -} - -.header { - display: flex; - flex-direction: row; - justify-content: space-around; -} - -.header h1 { - font-weight: normal; - font-size: 20px; - text-align: center; - margin: 0; -} - -.header input { - width: 200px; - height: 30px; - margin-left: 10px; - padding-left: 10px; -} - -.btn { - margin-bottom: 5px; - background-color: grey; - color: white; - width: 74.45px; - padding: 10px; - padding-top: 7px; - padding-bottom: 7px; - letter-spacing: 0.55px; - margin-left:auto; - margin-right:0; - text-align: center; -} - -.btncontainer{ - display: flex; - flex-direction: column; - justify-content: flex end; -} - -label{ - background-color: grey; - color: white; - cursor: pointer; - font-size: 8px; - font-weight: normal; - border-width: 0.5px; - border-radius: 3px; - border-style: solid; - border-color: rgb(192,192,192); - letter-spacing: 0.55px; - padding-top: 7px; - padding-bottom: 7px; - padding-left: 15px; - padding-right: 15px; - width: auto; - margin-left:auto; - margin-right:0; - text-align: center; -} - -.red{ - color: red; - font-size: 8px; - font-weight: bold; - letter-spacing: 0.5px; - display: inline; - padding: 0; - margin: 0; - margin-top: 10px; -} - -input::placeholder, textarea::placeholder{ - color: black; important! -} \ No newline at end of file +/* Landscape Media Query */ +@media screen and (min-aspect-ratio: 13/9) { + + .container + { + margin-top: 25vmin; + margin-bottom: calc(1vh + 1vw); + margin-left: 11vmin; + padding: 40px; + padding-top: 25px; + padding-bottom: 10px; + width: 55%; + height: auto; + background-color: #E3E3E3; + border-radius: calc(0.2vh + 0.2vw); + box-shadow: 1px 1px 1px lightgray, -1px -1px 1px lightgray; + } + + input, textarea{ + font-size: 8px; + font-weight: normal; + border-width: 0.5px; + border-radius: 3px; + border-style: solid; + border-color: rgb(192,192,192); + font-family: 'Roboto'; + position: relative; + margin: 0; + padding: 10px 10px; + margin-bottom: 10px; + width: 98%; + } + + .header { + display: flex; + flex-direction: row; + justify-content: space-around; + } + + .header h1 { + font-weight: normal; + font-size: 20px; + text-align: center; + margin: 0; + } + + .communities { + font-family: 'Roboto', sans-serif; + } + + .btn { + margin-bottom: 5px; + background-color: grey; + color: white; + width: 74.45px; + padding: 10px; + padding-top: 7px; + padding-bottom: 7px; + letter-spacing: 0.55px; + margin-left:auto; + margin-right:0; + text-align: center; + } + + .btncontainer{ + display: flex; + flex-direction: column; + justify-content: flex end; + } + + .red{ + color: red; + font-size: 8px; + font-weight: bold; + letter-spacing: 0.5px; + display: inline; + padding: 0; + margin: 0; + margin-top: 10px; + } + + input::placeholder, textarea::placeholder{ + color: black; important! + } + +} /* Close Media Query */ + +/* Portrait Media Query */ +@media screen and (max-aspect-ratio: 13/9) { + + .container + { + margin: auto; + margin-top: 3vw; + margin-bottom: 3vw; + padding: 3vw; + width: 90%; + height: auto; + background-color: #E3E3E3; + border-radius: 1vw; + box-shadow: 0.3vw 0.3vw 0.3vw lightgrey, -0.3vw -0.3vw 0.3vw lightgrey; + } + + input, textarea{ + font-size: 3vw; + font-weight: normal; + border-width: 0.1vw; + border-radius: 1vw; + border-style: solid; + border-color: rgb(192,192,192); + font-family: 'Roboto'; + position: relative; + margin: 0; + padding: 2vw; + margin-bottom: 3vw; + width: 97.5%; + } + + .header { + display: flex; + flex-direction: row; + justify-content: space-between; + } + + .header h1 { + font-weight: normal; + font-size: 6vw; + text-align: center; + margin: 0; + } + + .communities { + width: 30vw; + font-size: 2.5vw; + font-family: 'Roboto', sans-serif; + } + + .posttitle { + margin-top: 3vw; + } + + .btn { + margin-bottom: 1vw; + background-color: grey; + color: white; + width: auto; + padding: 2vw; + padding-top: 2vw; + padding-bottom: 2vw; + letter-spacing: 0.24vw; + margin-left: auto; + margin-right: 0; + text-align: center; + } + + .btncontainer{ + display: flex; + flex-direction: column; + justify-content: flex-end; + } + + .red{ + color: red; + font-size: 2vw; + font-weight: bold; + letter-spacing: 0.3vw; + display: inline; + padding: 0; + margin: 0; + margin-top: 2.3vw; + } + + input::placeholder, textarea::placeholder{ + color: black; important! + } + +} /* Close Media Query */ diff --git a/app/static/img/App-on-UnderDogs-Ad.gif b/app/static/img/App-on-UnderDogs-Ad.gif new file mode 100644 index 0000000..19c45a2 Binary files /dev/null and b/app/static/img/App-on-UnderDogs-Ad.gif differ diff --git a/app/static/img/bully.png b/app/static/img/bully.png new file mode 100644 index 0000000..5123688 Binary files /dev/null and b/app/static/img/bully.png differ diff --git a/app/static/img/catGif.gif b/app/static/img/catGif.gif new file mode 100644 index 0000000..92bf61e Binary files /dev/null and b/app/static/img/catGif.gif differ diff --git a/app/static/img/favicon.ico b/app/static/img/favicon.ico index a2fd8b4..b2e808d 100644 Binary files a/app/static/img/favicon.ico and b/app/static/img/favicon.ico differ diff --git a/app/static/js/scripts.js b/app/static/js/scripts.js index 53c70b8..cf95fd3 100644 --- a/app/static/js/scripts.js +++ b/app/static/js/scripts.js @@ -1,4 +1,8 @@ /* JavaScript file +version 1.1 + 08.13.2019 + Description: Clicking on subscribe buttons changes colors of other subscribe buttons for the corresponding port. + version 1.0 08.02.2019 Description: These are functions operating on the 2 base templates 'baseLoggedIn.html' and 'baseLoggedOut.html' @@ -28,17 +32,38 @@ function submitSearch () // Change the color of the subscription button and what is written on it if it is pressed. Then, submit the form: function subscribe(x) { - var temp = x.id.substr(x.id.length - 1); // Fetch the last char. of the id of the calling button. This is its serial number given as a string. + var temp = x.className.substr(x.className.length - 1); // Fetch the last char of the class name of the calling button. This is its serial number given as a string. if (x.value == 'Subscribe') { x.style.backgroundColor = 'rgb(123, 34, 64)'; // It means the user is subscribed to the particular port. Color the calling button maroon, and x.value = 'Joined'; // Change the text on the button to 'joined'. + x.title = 'Joined'; } else // Otherwise, if the user clicked again (to unsubscribe): { x.style.backgroundColor = 'rgb(117, 117, 117)'; // Turn the color back to gray, x.value = 'Subscribe'; // Change the text on the button to 'Subscribe'. + x.title = 'Subscribe'; } + + // Now, change the style of the parallel button (if it exists) on the Port Index section ('portIndex.html') or the Subscribed Ports section ('userInfo.html'): + // Retrieve the name of the port to which `x` is a button (notice the '-1' that is due to the enumeration of the buttons starting from 1): + temp = parseInt(temp)-1; + temp *= 2; // Get only the even numbers since another element has the class 'trendingName' in 'base.html'. + var portName = document.getElementsByClassName("trendingName")[temp].innerHTML; + // Now we loop through existing port info: + for (i = 0; i < document.getElementsByClassName("portName").length; i++) + { + if (document.getElementsByClassName("portName")[i].innerHTML == portName) + { + // Note that the index below is 'i-1'. The reason is that we enumerate the 'trending ports' starting from 1 and not from , + // which is why here we have to subtract 1 to get to the right button! + document.getElementsByClassName("subscribeIndex")[i].style.backgroundColor = x.style.backgroundColor; + document.getElementsByClassName("subscribeIndex")[i].value = x.value; + document.getElementsByClassName("subscribeIndex")[i].title = x.title; + } + } + document.getElementsByClassName("trendingForm")[0].submit(); // Now submit this information } @@ -64,4 +89,22 @@ function ifLoggedOutGlowSignIn () function displayYear() { document.getElementsByClassName("year")[0].innerHTML = (new Date()).getFullYear(); -} \ No newline at end of file +} + +// When the user scrolls down 100px from the top of the document, show the button +window.onscroll = function() {scrollFunction()}; + +function scrollFunction() { + if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 100) { + document.getElementById("myBtn").style.display = "block"; + } else { + document.getElementById("myBtn").style.display = "none"; + } +} + +// When the user clicks on the button, scroll to the top of the document +function topFunction() { + document.body.scrollTop = 0; // For Safari + document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera +} + diff --git a/app/static/js/scriptsAppOfTheMonthRegister.js b/app/static/js/scriptsAppOfTheMonthRegister.js new file mode 100644 index 0000000..5477157 --- /dev/null +++ b/app/static/js/scriptsAppOfTheMonthRegister.js @@ -0,0 +1,33 @@ +// 'validateEmail' checks if the email is of the form: what@email.com +function validateEmail() +{ + var email = document.getElementsByClassName("email")[0]; + //alert(email.value); + if(!email.value.match(/(.*)@(.*)\.(.+)(.+)(.+)/)) + email.setCustomValidity("Email is not of the form what@email.com"); + else + email.setCustomValidity(""); +} + +// 'validateNames' checks if the first name and the last name are only of alphabetic chatacters. +function validateNames(object) +{ + object.value = object.value.replace(/[^a-zA-Z]+/g,""); // Erase all the non-alphabetic chars. +} + + +// Make Received URLs no longer than 300 chars: +function URLLength () +{ + if (document.getElementsByClassName("addimage")[0].value.length > 0) + { + document.getElementsByClassName("addimage")[0].required = true; + if (document.getElementsByClassName("addimage")[0].value.length > 300) + document.getElementsByClassName("addimage")[0].setCustomValidity("URL must be no longer than 300 chars!"); + else + document.getElementsByClassName("addimage")[0].setCustomValidity(""); + } + else + document.getElementsByClassName("addimage")[0].required = false; +} + diff --git a/app/static/js/scriptsNotifications.js b/app/static/js/scriptsNotifications.js new file mode 100644 index 0000000..aa6d328 --- /dev/null +++ b/app/static/js/scriptsNotifications.js @@ -0,0 +1,13 @@ +// A function that shortens the length of the post title and comment content if they are longer than 50 chars: +function cutIt () +{ + for (i = 0; i < document.getElementsByClassName("nameOfPost").length; i++) + { + if (document.getElementsByClassName("nameOfPostOrComment")[i].innerHTML.length > 50) + document.getElementsByClassName("nameOfPostOrComment")[i].innerHTML + = document.getElementsByClassName("nameOfPostOrComment")[i].innerHTML.substr(0, 49) + "..."; + if (document.getElementsByClassName("theNoteContent")[i].innerHTML.length > 50) + document.getElementsByClassName("theNoteContent")[i].innerHTML + = document.getElementsByClassName("theNoteContent")[i].innerHTML.substr(0, 49) + "..."; + } +} \ No newline at end of file diff --git a/app/static/js/scriptsPortIndex.js b/app/static/js/scriptsPortIndex.js index 2a7c521..d4ede8c 100644 --- a/app/static/js/scriptsPortIndex.js +++ b/app/static/js/scriptsPortIndex.js @@ -1,4 +1,12 @@ /* JavaScript file + version 1.1.1 + 08.13.2019 + Description: `subscribePortIndex` was modified to fix the button coordination bug. Bug fixed! + + version 1.1 + 08.13.2019 + Description: Pressing 'subscribe' on the port index will change the color of the corresponding button in 'Trending Ports'. Bug fixed! + version 1.0 08.11.2019 Description: Creation of File @@ -25,5 +33,19 @@ function subscribePortIndex(object) subscribeButton.value = 'Subscribe'; // Change the text on the button to 'Subscribe'. subscribeButton.title = 'Subscribe'; // Change the title text on the button to 'Subscribe'. } + + // Now check if this port is also in the 'trending ports' section, and change the color of the button accordingly: + for (i = 0; i < document.getElementsByClassName("trendingName").length; i+=2) + { + if (document.getElementsByClassName("trendingName")[i].innerHTML == document.getElementsByClassName("portName" + id)[0].innerHTML) + { + // Note that the index below is 'i/2'. The reason is that another element has the classname "trendingName", which is + // why we need to skip over the odd numbers to get to the corresponding button! + document.getElementsByClassName("subscribe")[i/2].style.backgroundColor = subscribeButton.style.backgroundColor; + document.getElementsByClassName("subscribe")[i/2].value = subscribeButton.value; + document.getElementsByClassName("subscribe")[i/2].title = subscribeButton.title; + } + } + document.getElementsByClassName("subscriptionForm" + id)[0].submit(); // Now submit this information -} \ No newline at end of file +} diff --git a/app/static/js/scriptsPostDetails.js b/app/static/js/scriptsPostDetails.js index eaf13af..91e52ab 100644 --- a/app/static/js/scriptsPostDetails.js +++ b/app/static/js/scriptsPostDetails.js @@ -1,4 +1,8 @@ /* JavaScript file for: 'portIndex.html' + version 1.1 + 08.13.2019 + Description: correction of folder location of static images + version 1.0 08.11.2019 Description: Creation of File @@ -14,7 +18,7 @@ function saveOrUnsavePost () if (savePostButton.value == "Save Post") { savePostButton.style.backgroundColor = "#7B2240"; - savePostButton.style.backgroundImage = "url('static/img/grayFolder.png')"; + savePostButton.style.backgroundImage = "url('../static/img/grayFolder.png')"; savePostButton.value = "Post Saved"; savePostButton.title = "Post Saved"; } @@ -22,7 +26,7 @@ function saveOrUnsavePost () else { savePostButton.style.backgroundColor = "#757575"; - savePostButton.style.backgroundImage = "url('static/img/maroonFolder.png')"; + savePostButton.style.backgroundImage = "url('../static/img/maroonFolder.png')"; savePostButton.value = "Save Post"; savePostButton.title = "Save Post"; } @@ -124,28 +128,163 @@ function unvealArea (comment) if (theTextAreaDiv.style.display == "none") theTextAreaDiv.style.display = "inherit"; else - theTextAreaDiv.style.display = "none"; -} - -// Submit a comment to comment if ENTER was pressed and if the comment is nonempty: -function submitComment (comment) -{ - if ((event.which == 13 || event.keyCode == 13) - && document.getElementsByClassName("commentToCommentText" + comment)[0].value.trim().length != 0) - document.getElementsByClassName("writeCommentToComment" + comment)[0].submit(); + theTextAreaDiv.style.display = "none"; } // Enable the "submit comment" button if the comment to the post is nonempty, and disable it otherwise: function enableDisableSubmission(theTextArea) { - if (theTextArea.value.trim().length != 0) + if (theTextArea.className.length == 17) { - document.getElementsByClassName("CommentToPostBtn")[0].disabled = false; - document.getElementsByClassName("CommentToPostBtn")[0].value = "✔ Submit Comment"; + if (theTextArea.value.trim().length != 0) + { + document.getElementsByClassName("CommentToPostBtn")[0].disabled = false; + document.getElementsByClassName("CommentToPostBtn")[0].value = "✔ Submit Comment"; + } + else + { + document.getElementsByClassName("CommentToPostBtn")[0].disabled = true; + document.getElementsByClassName("CommentToPostBtn")[0].value = "✖ Submit Comment"; + } } else { - document.getElementsByClassName("CommentToPostBtn")[0].true = false; - document.getElementsByClassName("CommentToPostBtn")[0].value = "✖ Submit Comment"; + // Extract the 'id' of the comment; + var id = theTextArea.className.substr(38); + // Check if area is non empty: + if (theTextArea.value.trim().length != 0) + { + document.getElementsByClassName("buttonComment" + id)[0].disabled = false; + document.getElementsByClassName("buttonComment" + id)[0].value = "✔ Submit Comment"; + } + else + { + document.getElementsByClassName("buttonComment" + id)[0].disabled = true; + document.getElementsByClassName("buttonComment" + id)[0].value = "✖ Submit Comment"; + } + } +} + +// Escape the necessary characters: +function escapeChars (x) +{ + for (i = 0; i < x.value.length; i++) + { + if (x.value[i] == "\\") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\\" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\\"; + i++; + } + else if (x.value[i] == "\f") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\f" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\f"; + i++; + } + else if (x.value[i] == "\r") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\r" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\r"; + i++; + } + else if (x.value[i] == "\v") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\v" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\v"; + i++; + } + else if (x.value[i] == "\t") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\t" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\t"; + i++; + } + else if (x.value[i] == "\0") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\0" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\0"; + i++; + } + else if (x.value[i] == "\'") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\'" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\'"; + i++; + } + } +} + +// Submit the Comment to Post form w/ escaping: +function submitWithEscapeCommentToPost () +{ + escapeChars(document.getElementsByClassName("commentToPostText")[0]); +} + + +// Submit the Comment to Post form w/ escaping: +function submitWithEscapeCommentToComment (obj) +{ + var id = obj.className.substr(21); + escapeChars(document.getElementsByClassName("commentToCommentText" + id)[0]); +} + +// Display Post Text w/ line breaks +function displayWithLineBreaks() +{ + // For the Post Text: + var temp = document.getElementsByClassName("postDescription")[0].innerHTML; + var temp1; + document.getElementsByClassName("postDescription")[0].innerHTML = ""; // Clear the current paragraph + while (temp.indexOf("\n") != -1) + { + temp1 = document.createElement("P"); // Create a new paragraph element + if (temp.indexOf("\n") != 0) + temp1.innerHTML = temp.slice(0, temp.indexOf("\n")); // Place a whole line into the paragraph + else + temp1.innerHTML = " "; + temp1.style.margin = "0"; + document.getElementsByClassName("postDescription")[0].appendChild(temp1); // Put the paragraph into the page for display + temp = temp.slice(temp.indexOf("\n")+1); // Cut the string to continue to search for additional line breaks. + } + temp1 = document.createElement("P"); // Create a new paragraph element + temp1.innerHTML = temp // Place the last line into the paragraph + temp1.style.margin = "0"; + document.getElementsByClassName("postDescription")[0].appendChild(temp1); // Put the paragraph into the page for display + + // For all the Comments (whatever level) on the page: + for (i = 0; i < document.getElementsByClassName("commentText").length; i++) + { + temp = document.getElementsByClassName("commentText")[i].innerHTML; + document.getElementsByClassName("commentText")[i].innerHTML = ""; // Clear the current paragraph + while (temp.indexOf("\n") != -1) + { + temp1 = document.createElement("P"); // Create a new paragraph element + if (temp.indexOf("\n") != 0) + temp1.innerHTML = temp.slice(0, temp.indexOf("\n")); // Place a whole line into the paragraph + else + temp1.innerHTML = " "; + temp1.style.margin = "0"; + document.getElementsByClassName("commentText")[i].appendChild(temp1); // Put the paragraph into the page for display + temp = temp.slice(temp.indexOf("\n")+1); // Cut the string to continue to search for additional line breaks. + } + temp1 = document.createElement("P"); // Create a new paragraph element + temp1.innerHTML = temp // Place the last line into the paragraph + temp1.style.margin = "0"; + document.getElementsByClassName("commentText")[i].appendChild(temp1); // Put the paragraph into the page for display } } diff --git a/app/static/js/scriptsRegister.js b/app/static/js/scriptsRegister.js index e93b094..f30c142 100644 --- a/app/static/js/scriptsRegister.js +++ b/app/static/js/scriptsRegister.js @@ -4,14 +4,14 @@ function validatePassword() var password = document.getElementsByClassName("password")[0]; var confirm_password = document.getElementsByClassName("confirm_password")[0]; - if (password.value.length < 7) + if (password.value.length < 7 || password.value.length > 128) { - password.setCustomValidity("Passwords must be of at least 7 characters!"); + password.setCustomValidity("Passwords must be between 7 and 128 characters!"); } - else if (confirm_password.value.length < 7) + else if (confirm_password.value.length < 7 || confirm_password.value.length > 128) { password.setCustomValidity(""); - confirm_password.setCustomValidity("Passwords must be of at least 7 characters!"); + confirm_password.setCustomValidity("Passwords must be between 7 and 128 characters!"); } else if(password.value != confirm_password.value) { @@ -32,10 +32,22 @@ function validateUserNameLength() if(username.value.length < 7) username.setCustomValidity("Username must be of at least 7 characters!"); + else if (username.value.length > 30) + username.setCustomValidity("Username must be of at most 30 characters!"); else username.setCustomValidity(""); } +// 'validateNames' checks if the first name and the last name are at most 30 chars. +function validateNames(object) +{ + object.value = object.value.replace(/[^a-zA-Z]+/g,""); // Erase all the non-alphabetic chars. + if(object.value.length > 30) + object.setCustomValidity("A name must be of at most 30 characters!"); + else + object.setCustomValidity(""); +} + // 'validateEmail' checks if the email is of the form: what@email.com function validateEmail() { @@ -43,6 +55,8 @@ function validateEmail() //alert(email.value); if(!email.value.match(/(.*)@(.*)\.(.+)(.+)(.+)/)) email.setCustomValidity("Email is not of the form what@email.com"); + else if (email.value.length > 128) + email.setCustomValidity("Email must be of at most 128 characters!"); else email.setCustomValidity(""); } @@ -54,4 +68,19 @@ function changeVal () document.getElementsByClassName("imageLabel")[0].innerHTML = document.getElementsByClassName("imageUpload")[0].value; else document.getElementsByClassName("imageLabel")[0].innerHTML = "Your Image"; -} \ No newline at end of file +} + +// Make Received URLs no longer than 300 chars: +function URLLength () +{ + if (document.getElementsByClassName("addimage")[0].value.length > 0) + { + document.getElementsByClassName("addimage")[0].required = true; + if (document.getElementsByClassName("addimage")[0].value.length > 300) + document.getElementsByClassName("addimage")[0].setCustomValidity("URL must be no longer than 300 chars!"); + else + document.getElementsByClassName("addimage")[0].setCustomValidity(""); + } + else + document.getElementsByClassName("addimage")[0].required = false; +} diff --git a/app/static/js/scriptsUserInfo.js b/app/static/js/scriptsUserInfo.js index 1e1a00d..5e1dbcc 100644 --- a/app/static/js/scriptsUserInfo.js +++ b/app/static/js/scriptsUserInfo.js @@ -1,4 +1,12 @@ /* JavaScript file for: 'userInfo.html' + version 1.1.1 + 08.13.2019 + Description: `subscribePortIndex` was modified to fix the button coordination bug. Bug fixed! + + version 1.1 + 08.13.2019 + Description: `subscribePortIndex` function added + version 1.0 08.12.2019 Description: Creation of File @@ -33,14 +41,6 @@ function openEdit() } } -// Submit the Bio form -function submitBio() -{ - if (document.getElementsByClassName("descriptionTextArea")[0].innerHTML != document.getElementsByClassName("descriptionText")[0].innerHTML - || document.getElementsByClassName("imageUpload")[0].value != "") - document.getElementsByClassName("descriptionForm")[0].submit(); // Submit the form -} - // Submit a 'checkbox' form function submitCheckboxForm (theForm) { @@ -63,6 +63,11 @@ function validateEmail(email) email.setCustomValidity("Email is not of the form what@email.com"); email.required = true; } + else if (email.value.length > 128) + { + email.setCustomValidity("Email must be of at most 128 characters!"); + email.required = true; + } else if (document.getElementsByClassName("emailSetting")[0].value != document.getElementsByClassName("emailSetting")[1].value) { document.getElementsByClassName("emailSetting")[0].setCustomValidity(""); @@ -82,20 +87,20 @@ function validatePassword() var password = document.getElementsByClassName("passwordSetting")[0]; var confirm_password = document.getElementsByClassName("passwordSetting")[1]; - if (current_password.value.length < 7) + if (current_password.value.length < 7 || current_password.value.length > 128) { - password.setCustomValidity("Passwords must be of at least 7 characters!"); + current_password.setCustomValidity("Passwords must be between 7 and 128 characters!"); } - else if (password.value.length < 7) + else if (password.value.length < 7 || password.value.length > 128) { current_password.setCustomValidity(""); - password.setCustomValidity("Passwords must be of at least 7 characters!"); + password.setCustomValidity("Passwords must be between 7 and 128 characters!"); } - else if (confirm_password.value.length < 7) + else if (confirm_password.value.length < 7 || confirm_password.value.length > 128) { current_password.setCustomValidity(""); password.setCustomValidity(""); - confirm_password.setCustomValidity("Passwords must be of at least 7 characters!"); + confirm_password.setCustomValidity("Passwords must be between 7 and 128 characters!"); } else if(password.value != confirm_password.value) { @@ -109,4 +114,176 @@ function validatePassword() confirm_password.setCustomValidity(""); password.setCustomValidity(""); } -} \ No newline at end of file +} + +// Change the color of the subscription button and what is written on it if it is pressed. Then, submit the form: +function subscribePortIndex(object) +{ + // Extraction of the 'id' of the port: + var id = object.className.substr(24); + + var subscribeButton = document.getElementsByClassName("subscribe" + id)[0]; + + if (subscribeButton.value == 'Subscribe') + { + subscribeButton.style.backgroundColor = '#7B2240'; // It means the user is subscribed to the particular port. Color the calling button maroon, and + subscribeButton.value = 'Joined'; // Change the text on the button to 'Joined'. + subscribeButton.title = 'Joined'; // Change the title text on the button to 'Joined'. + } + else // Otherwise, if the user clicked again (to unsubscribe): + { + subscribeButton.style.backgroundColor = 'rgb(117, 117, 117)'; // Turn the color back to gray, + subscribeButton.value = 'Subscribe'; // Change the text on the button to 'Subscribe'. + subscribeButton.title = 'Subscribe'; // Change the title text on the button to 'Subscribe'. + } + + // Now check if this port is also in the 'trending ports' section, and change the color of the button accordingly: + for (i = 0; i < document.getElementsByClassName("trendingName").length; i+=2) + { + if (document.getElementsByClassName("trendingName")[i].innerHTML == document.getElementsByClassName("portName" + id)[0].innerHTML) + { + // Note that the index below is 'i/2'. The reason is that there are two types of objects with the 'trendingName + // classname, so we 'jump over' the other one. + document.getElementsByClassName("subscribe")[i/2].style.backgroundColor = subscribeButton.style.backgroundColor; + document.getElementsByClassName("subscribe")[i/2].value = subscribeButton.value; + document.getElementsByClassName("subscribe")[i/2].title = subscribeButton.title; + } + } + + document.getElementsByClassName("subscriptionForm" + id)[0].submit(); // Now submit this information +} + +// Make Received URLs no longer than 300 chars: +function URLLength () +{ + if (document.getElementsByClassName("avatarURL")[0].value.length > 0) + { + document.getElementsByClassName("avatarURL")[0].required = true; + if (document.getElementsByClassName("avatarURL")[0].value.length > 300) + document.getElementsByClassName("avatarURL")[0].setCustomValidity("URL must be no longer than 300 chars!"); + else + document.getElementsByClassName("avatarURL")[0].setCustomValidity(""); + } + else + document.getElementsByClassName("avatarURL")[0].required = false; +} + +// Submit the Bio form +function submitBio() +{ + URLLength (); // Check this again, just in case the user deleted the field with mouse instead of keyboard. + if (document.getElementsByClassName("descriptionTextArea")[0].value == document.getElementsByClassName("descriptionText")[0].innerHTML && + document.getElementsByClassName("avatarURL")[0].value.length == 0) + { + document.getElementsByClassName("descriptionTextArea")[0].required = true; + document.getElementsByClassName("descriptionTextArea")[0].setCustomValidity("Please fill out this field!"); + } + else if (document.getElementsByClassName("descriptionTextArea")[0].value.length > 1000) + { + document.getElementsByClassName("descriptionTextArea")[0].required = true; + document.getElementsByClassName("descriptionTextArea")[0].setCustomValidity("Bio can contain at most 1000 chars!"); + } + else + { + document.getElementsByClassName("descriptionTextArea")[0].required = false; + submitWithEscape (); + document.getElementsByClassName("descriptionTextArea")[0].setCustomValidity(""); + } +} + +// Escape the necessary characters: +function escapeChars (x) +{ + for (i = 0; i < x.value.length; i++) + { + if (x.value[i] == "\\") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\\" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\\"; + i++; + } + else if (x.value[i] == "\f") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\f" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\f"; + i++; + } + else if (x.value[i] == "\r") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\r" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\r"; + i++; + } + else if (x.value[i] == "\v") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\v" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\v"; + i++; + } + else if (x.value[i] == "\t") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\t" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\t"; + i++; + } + else if (x.value[i] == "\0") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\0" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\0"; + i++; + } + else if (x.value[i] == "\'") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\'" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\'"; + i++; + } + } +} + +// Submit the form w/ escaping: +function submitWithEscape () +{ + //escapeChars(document.getElementsByClassName("descriptionTextArea")[0]); +} + +// Display Description Text w/ line breaks +function displayWithLineBreaks() +{ + if (document.getElementsByClassName("descriptionText").length != 0) + { + // For the Description Text: + var temp = document.getElementsByClassName("descriptionText")[0].innerHTML; + var temp1; + document.getElementsByClassName("descriptionText")[0].innerHTML = ""; // Clear the current paragraph + while (temp.indexOf("\n") != -1) + { + temp1 = document.createElement("P"); // Create a new paragraph element + if (temp.indexOf("\n") != 0) + temp1.innerHTML = temp.slice(0, temp.indexOf("\n")); // Place a whole line into the paragraph + else + temp1.innerHTML = " "; + temp1.style.margin = "0"; + document.getElementsByClassName("descriptionText")[0].appendChild(temp1); // Put the paragraph into the page for display + temp = temp.slice(temp.indexOf("\n")+1); // Cut the string to continue to search for additional line breaks. + } + temp1 = document.createElement("P"); // Create a new paragraph element + temp1.innerHTML = temp // Place the last line into the paragraph + temp1.style.margin = "0"; + document.getElementsByClassName("descriptionText")[0].appendChild(temp1); // Put the paragraph into the page for display + } +} diff --git a/app/static/js/scriptsWritePost.js b/app/static/js/scriptsWritePost.js index c3faf35..7084612 100644 --- a/app/static/js/scriptsWritePost.js +++ b/app/static/js/scriptsWritePost.js @@ -12,4 +12,101 @@ function changeVal () document.getElementsByClassName("imageLabel")[0].innerHTML = document.getElementsByClassName("imageUpload")[0].value; else document.getElementsByClassName("imageLabel")[0].innerHTML = "Add Image"; -} \ No newline at end of file +} + +// Make Received URLs no longer than 300 chars: +function URLLength () +{ + if (document.getElementsByClassName("addimage")[0].value.length > 0) + { + document.getElementsByClassName("addimage")[0].required = true; + if (document.getElementsByClassName("addimage")[0].value.length > 300) + document.getElementsByClassName("addimage")[0].setCustomValidity("URL must be no longer than 300 chars!"); + else + document.getElementsByClassName("addimage")[0].setCustomValidity(""); + } + else + document.getElementsByClassName("addimage")[0].required = false; +} + +// Ensure the Post Title is at most 100 chars +function validateTitle () +{ + if (document.getElementsByClassName("postTitle")[0].value.length > 100) + document.getElementsByClassName("postTitle")[0].setCustomValidity("Title must be of at most 100 chars!"); + else + document.getElementsByClassName("postTitle")[0].setCustomValidity(""); +} + +// Escape the necessary characters: +function escapeChars (x) +{ + for (i = 0; i < x.value.length; i++) + { + if (x.value[i] == "\\") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\\" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\\"; + i++; + } + else if (x.value[i] == "\f") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\f" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\f"; + i++; + } + else if (x.value[i] == "\r") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\r" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\r"; + i++; + } + else if (x.value[i] == "\v") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\v" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\v"; + i++; + } + else if (x.value[i] == "\t") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\t" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\t"; + i++; + } + else if (x.value[i] == "\0") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\0" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\0"; + i++; + } + else if (x.value[i] == "\'") + { + if (i != x.value.length-1) + x.value = x.value.slice(0, i) + "\\\'" + x.value.slice(i+1); + else + x.value = x.value.slice(0, i) + "\\\'"; + i++; + } + } +} + +// Submit the form w/ escaping: +function submitWithEscape () +{ + // Create "new line" breaks in actual post text: + document.getElementsByClassName("textOfPost")[0].innerHTML = document.getElementsByClassName("textOfPost")[0].value; + escapeChars(document.getElementsByClassName("postTitle")[0]); + escapeChars(document.getElementsByClassName("textOfPost")[0]); +} diff --git a/app/templates/_404Error.html b/app/templates/_404Error.html new file mode 100644 index 0000000..6564b05 --- /dev/null +++ b/app/templates/_404Error.html @@ -0,0 +1,14 @@ + + + + +{#- A Typical 404 Error Template #} + +{% extends "base.html" %} +{% block content %} +
+

Sorry ...

+

There's nothing here! (Well, what do you expect from a 404 Error?!?)

+

Back to Homepage

+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/_head.html b/app/templates/_head.html index df93f0e..8db5092 100644 --- a/app/templates/_head.html +++ b/app/templates/_head.html @@ -2,16 +2,16 @@ {% endblock meta -%} {%- block theTitle %} - {%- if name %}{{ name }} {% else %}logicPort{% endif -%} + {%- if name %}{{ name }} {% else %}Underdogs{% endif -%} {% endblock theTitle -%} {%- block linkedStatics %} - + - + - {% endblock linkedStatics -%} \ No newline at end of file + {% endblock linkedStatics -%} diff --git a/app/templates/appOfTheMonthRegister.html b/app/templates/appOfTheMonthRegister.html new file mode 100644 index 0000000..5e31c65 --- /dev/null +++ b/app/templates/appOfTheMonthRegister.html @@ -0,0 +1,105 @@ +{#- Version 1.0 - 08.25.2019, 00:00 #} {#- This is the 'appOfTheMonthRegister.html' template. +A user can register his or her app. Once a month, a winning app is chosen and displayed at that +bottom, right corner of the screen (or bottom part of the mobile devices.) The information submitted +through this form is written into a text file located in the static folder. #} + + + + + + + + +{%- extends "base.html" %} {#- Since this template inherits everything from a +base template, all we modify here is the 'content' block: #} {%- block content +%} + + + +{% endblock content -%} diff --git a/app/templates/appSubmitted.html b/app/templates/appSubmitted.html new file mode 100644 index 0000000..b9c7a85 --- /dev/null +++ b/app/templates/appSubmitted.html @@ -0,0 +1,21 @@ +{#- Version 1.0 - 08.25.2019, 03:00 #} +{#- This is the 'appSubmitted.html' template. When a user registers his or her app for the App of the Month, the user #} +{#- is redirected to this page. #} + + + + + + +{#- Assume that after the registration, the user is logged in automatically: #} +{%- extends "base.html" %} + +{#- Since this template inherits everything from a base template, all we modify here is the 'content' block: #} +{%- block content %} +
+

App Registration Form Submitted!

+
{#- Note: no info besides 'action' redirection is submitted by this form. Don't add 'method = post' here! #} + +
+
+{% endblock content -%} \ No newline at end of file diff --git a/app/templates/base.html b/app/templates/base.html index 44f6e3e..3a37f1e 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -1,3 +1,12 @@ +{#- Version 1.1.3 - 08.13.2019, 22:50 #} +{#- Description: Logo Change to Underdogs #} + +{#- Version 1.1.2 - 08.13.2019, 07:40 #} +{#- Description: Search input box does not submit on ENTER if it is empty, which it erroneously previously did. Bug fixed! #} + +{#- Version 1.1.1 - 08.13.2019, 06:15 #} +{#- Description: 'isSubscribed' attribute added to the 'trending ports' section and is recognized thereby. Bug fixed! #} + {#- Version 1.1 - 08.09.2019, 05:40 #} {#- Description: 'if' condition added to lines 22-26 to close menu if user is logged in. #} @@ -8,17 +17,19 @@ + + {% include '_head.html' %} - + {%- block leftContainer %} -
- - +
+ + {%- if user %} @@ -39,49 +50,62 @@ {% endif -%} {{ user['username'] }} - -
+ + + 0) %} + style = "animation: blinker 1s linear infinite;" + {%- endif -%} + name = "loggedIn" + class="notifications" + value = "Notifications: {%- if (notifiNum) and (notifiNum >= 0) and (notifiNum <= 100) %}{{ notifiNum }}{%- elif (notifiNum) and (notifiNum > 100) %}100+{%- else %}0{%- endif -%}" + title = "Go to your Notifications"> +
+
-
+ -
-
+
+
sign out {% else -%}{# If it wasn't: treat as though as the user is logged out. #} - + {%- if errLogIn %} {# Fires if 'errLogIn' is True; otherwise, does not fire. #}

! Invalid username or password !

{% endif -%} -
- +
+ - - +
+ - +
+ - - + +
- Forgot Password? + Forgot Password?

Not a member?

@@ -89,34 +113,26 @@
{% endif -%} -
- Our Team -
- +
- + Skip to Search Bar and Trending Ports {% endblock leftContainer -%} {#- All the content from the templates that will inherit this 'base.html' will go into the 'content' block: #} {%- block midContainer %} -
+
{%- block content %} {#- All the content will come here! #} - - {%- if user %} -

Current User{{user}}

- {%- else %} - -

YOURE NOT LOGGED IN!

- {% endif -%} - - {% endblock content -%} {%- block generalLinks %}
+
+ Corgi: Underdogs Logo +

The story of this application began one bright summer day when our Computer Science class was assigned a class project. The developers had to divide into teams and figure out what kind of project to implement. It was very hard at first to decide which developer would undertake which role, but after a few days all confussions were eliminated. Everybody began working on their task, so that at the end of the semester, the most beautiful project in the world would be created. All of this required huge efforts and time, and all teammates had to communicate with one another on a daily basis to resolve various conflict and misunderstandings and to notify each other about their progress. The website that you are using right now is the fruit of all this hard work.

Enjoy browsing!

< Some text by the Product team here ...>

Lorem Ipsum:

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

{%- elif contact %} @@ -51,4 +57,4 @@

Nothing to Display Here!

{% endif -%} -{% endblock content -%} \ No newline at end of file +{% endblock content -%} diff --git a/app/templates/noPasswordReminders.html b/app/templates/noPasswordReminders.html new file mode 100644 index 0000000..16131b5 --- /dev/null +++ b/app/templates/noPasswordReminders.html @@ -0,0 +1,15 @@ + + + + +{#- No-Passwords-Reminder-Funny-Cat-Giffy Template #} + +{% extends "base.html" %} +{% block content %} +
+

No Passwords Reminders at This Time ... !

+

Try to create a new account, or get your brain to finally remember simple passwords. Da!

+ Angry cat staring at a computer +

Back to Homepage

+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/notifications.html b/app/templates/notifications.html new file mode 100644 index 0000000..f18170d --- /dev/null +++ b/app/templates/notifications.html @@ -0,0 +1,67 @@ +{#- Version 1.0 - 09.01.2019 - Description: 'notifications.html' File Created #} + + {#- This Template accepts a List of `notifications` dictionary, in which each items has the mandatory keys: + (1) 'author': the username of the user who replied to the post / comment, + (2) 'postId': the id of the post in which this activity is going on, + (3) 'postTitle' or 'yourCommentsText': either the title of the post (if the comment is to the user's post) + or the content of the comment (if the comment is to the user's comment), + (4) 'dateCreated': the date when the other user replied to the post / comment, and + (5) 'commentText': the content of that comment. #} + + + + + + + + +{%- extends "base.html" %} + +{%- block content %} + +
+
+

NOTIFICATIONS

+
+
+ +
+

{{ user['username'] }}, welcome to your new notifications panel!

+

Here you can see who has commented to your posts and comments on UnderDogs, and visit these posts and comments by clicking on the corresponding links. You can always click on the "Notification" button on the menu to access this page. When you enter this page, all the new notifications will be marked as "read", and the button will display zero new notifications.

+

Currently, the panel displays example notifications, but once this feature is completely integrated, you would see your personal, up-to-date notifications.

+
+ + {%- for notific in notifications %} + {#- Display alternating colors for odd and even-numbered items: #} + {%- if loop.index % 2 != 0 %} +
+ {%- else %} +
+ {% endif -%} +
+

{{ notific['author'] }} + commented on your {%- if notific['postTitle'] %}post{%- else %}comment{%- endif %}

+
+
+ {%- if notific['postTitle'] %} {#- Either the title of the post or the text of the comment to which the comment was received: #} + {{ notific['postTitle'] | e }} + {%- else %} + {{ notific['yourCommentsText'] | e }} + {%- endif %} +
+
+

at {{ notific['dateCreated'] }}:

+
+ +
+ {% endfor -%} +{%- endblock content %} + diff --git a/app/templates/portIndex.html b/app/templates/portIndex.html index 1e3523e..737e30b 100644 --- a/app/templates/portIndex.html +++ b/app/templates/portIndex.html @@ -28,7 +28,7 @@ {% endif -%}
- p/{{ port['name'] }} + p/{{ port['name'] }}

{{ port['mem'] }} members

@@ -39,7 +39,7 @@
{%- if user %} {#- if the user is logged in, put the buttons in forms, and submit subscription info to server: #} -
+ {%- if port['isSubscribed'] == True %}
{% endfor -%} -{%- endblock content %} \ No newline at end of file +{%- endblock content %} diff --git a/app/templates/postDetails.html b/app/templates/postDetails.html index 647d8d4..9da1e8b 100644 --- a/app/templates/postDetails.html +++ b/app/templates/postDetails.html @@ -1,290 +1,303 @@ -{#- Version 1.0 - 08.12.2019 - Description: File Created #} - - - - - - -{%- extends "base.html" %} - -{%- block content %} - -
- {%- if user %} {#- Appears only if the user is logged in #} - - {%- if post['isSaved'] == True %} - - {%- else %} - - {% endif -%} - - - {% endif -%} -
- - {#- Optional argument, to display confirmation of comment submission to user: #} - {%- if commentSubmittedMessage %} -

✔ Comment Submitted & Posted!

- {% endif -%} - - {#- Each time a user upvotes or downvotes the post or a comment, or saves a post, a form will be submitted, but page #} - {#- won't reload, since the 'target' will be redirected into the frame 'frameForVotesAndPostSaving' below: #} - - -
-
- - {%- if user %} {#- Appears only if the user is logged in #} -
- -
- {% endif -%} -

{{ post['totalVotes'] }}

- {%- if user %} {#- Appears only if the user is logged in #} -
- -
- {% endif -%} -
-
- p/{{ post['portname'] }} -

{{ post['title'] | e }}

-
-
-

{{ post['dateCreated'] }}

-

Posted by:

-
- {#- Since 'post['avatarUrl']' is optional, we must have the following 'if' statement. #} - {%- if post['avatarUrl'] != None %} - the user {{ post['username'] }} - {%- else %} - the user {{ post['username'] }} - {% endif -%} - {{ post['username'] }} -
-
-
- - {#- Since 'post['text']' is optional, we must have the following 'if' statement. #} - {%- if post['text'] != None %} -

{{ post['text'] | e }}

- {% endif %} - - {#- Since 'post['image']' is optional, we must have the following 'if' statement. We put the whole div inside the 'if' statement. #} - {%- if post['image'] != None %} -
- the post {{ post['title'] | e }} -
- {% endif %} - - {%- if user %} -
- -
- -
-
- {% endif -%} - - {#- The following is perhaps the most intricate part of this template (and the whole project): the tree of comments. #} - {#- I asked Joe to permit only 2 levels of comments: comments to Post, and comments to these comments. #} - {#- Therefore, there is no 'reply' link to the second-level comments (Facebook, e.g., does this too.) #} - {#- Also: (1) 1-level comments are sorted by highest number of votes. #} - {#- (2) 2-level comments are sorted by time of writing (oldest first). All of this is an agreement with Joe. #} - -
- {#- A line that states how many total comments (both 1 and 2 level): #} - {%- if post['commentNum'] != 0 %} -

{{ post['commentNum'] }} comments:

- {%- else %} -

No comments yet!

- {% endif -%} - {#- The tree of comments: #} -
- {%- for comment1 in post['comments'] %} -
-
- {%- if user %} {#- Appears only if the user is logged in #} -
- -
- {% endif -%} -

{{ comment1['totalVotes'] }}

- {%- if user %} {#- Appears only if the user is logged in #} -
- -
- {% endif -%} -
-
- {%- if comment1['avatarUrl'] != None %} - the user {{ comment1['username'] }} - {%- else %} - the user {{ comment1['username'] }} - {% endif -%} -
-
- {{ comment1['username'] }} -

{{ comment1['text'] | e }}

- {%- if user %} - - {% endif -%} -
-
-

{{ comment1['dateCreated'] }}

-
-
- - {#- Below is the loop section for the second level comments: #} - {#- I could have used the recursive nature of Jinja intead of writing the code below, but there #} - {#- are a few significant changes between the 1st level and second level comments. #} - {%- for comment2 in comment1['comments'] %} -
-
{#- For decoration purposes #} -
-
- {%- if user %} {#- Appears only if the user is logged in #} -
- -
- {% endif -%} -

{{ comment2['totalVotes'] }}

- {%- if user %} {#- Appears only if the user is logged in #} -
- -
- {% endif -%} -
-
- {%- if comment2['avatarUrl'] != None %} - the user {{ comment2['username'] }} - {%- else %} - the user {{ comment2['username'] }} - {% endif -%} -
-
- {{ comment2['username'] }} -

{{ comment2['text'] | e }}

- {#- There is no reply button here, which was done with coordination with Joe #} -
-
-

{{ comment2['dateCreated'] }}

-
-
- {% endfor -%} {#- of the second level comments #} - {% endfor -%} {#- of the first level comments #} -
-
-
-{%- endblock content %} \ No newline at end of file +{#- Version 1.0 - 08.12.2019 - Description: File Created #} + + + + + + + +{%- extends "base.html" %} +{%- block content %} + +
+ {%- if user %} {#- Appears only if the user is logged in #} +
+ {%- if post['isSaved'] == True %} + + {%- else %} + + {% endif -%} + +
+ {% endif -%} +
+ + {#- Optional argument, to display confirmation of comment submission to user: #} + {%- if commentSubmittedMessage %} +

✔ Comment Submitted & Posted!

+ {% endif -%} + + {#- Each time a user upvotes or downvotes the post or a comment, or saves a post, a form will be submitted, but page #} + {#- won't reload, since the 'target' will be redirected into the frame 'frameForVotesAndPostSaving' below: #} + + +
+
+ + {%- if user %} {#- Appears only if the user is logged in #} +
+ + {% endif -%} + + + +

{{ post['votes'] }}

+ {%- if user %} {#- Appears only if the user is logged in #} + +
+ {% endif -%} +
+
+ p/{{ post['portName'] }} +

{{ post['postTitle'] | e }}

+
+
+

{{ post['dateCreated'] }}

+

Posted by:

+
+ {#- Since 'post['authorImg']' is optional, we must have the following 'if' statement. #} + {%- if (post['authorImg']) and (post['authorImg']|length > 5) %} + the user {{ post['author'] }} + {%- else %} + the user {{ post['author'] }} + {% endif -%} + {{ post['author'] }} +
+
+
+ + {#- Since 'post['text']' is optional, we must have the following 'if' statement. #} + {%- if post['text'] != None %} +

{{ post['postText'] | e }}

+ {% endif %} + + {#- Since 'post['image']' is optional, we must have the following 'if' statement. We put the whole div inside the 'if' statement. #} + {%- if post['image'] != None %} +
+ the post {{ post['postTitle'] | e }} +
+ {% endif %} + + {%- if user %} +
+ +
+ +
+
+ {% endif -%} + + {#- The following is perhaps the most intricate part of this template (and the whole project): the tree of comments. #} + {#- I asked Joe to permit only 2 levels of comments: comments to Post, and comments to these comments. #} + {#- Therefore, there is no 'reply' link to the second-level comments (Facebook, e.g., does this too.) #} + {#- Also: (1) 1-level comments are sorted by highest number of votes. #} + {#- (2) 2-level comments are sorted by time of writing (oldest first). All of this is an agreement with Joe. #} + +
+ {#- A line that states how many total comments (both 1 and 2 level): #} + {%- if post['numComments'] != '0' %} +

{{ post['numComments'] }} comments:

+ {%- else %} +

No comments yet!

+ {% endif -%} + {%- if post['numComments'] != '0' %} + {#- The tree of comments: #} +
+ + {%- for comment1 in comments['comments'] %} +
+
+ {%- if user %} {#- Appears only if the user is logged in #} +
+ + + + + {% endif -%} +

{{ comment1['votes'] }}

+ {%- if user %} {#- Appears only if the user is logged in #} + +
+ {% endif -%} +
+
+ {%- if (comment1['authorImg']) and (comment1['authorImg']|length > 5) %} + the user {{ comment1['author'] }} + {%- else %} + the user {{ comment1['author'] }} + {% endif -%} +
+
+ {{ comment1['author'] }} +

{{ comment1['commentText'] | e }}

+ {%- if user %} + + {% endif -%} +
+
+

{{ comment1['dateCreated'] }}

+
+
+ + {#- Below is the loop section for the second level comments: #} + {#- I could have used the recursive nature of Jinja intead of writing the code below, but there #} + {#- are a few significant changes between the 1st level and second level comments. #} + {%- for comment2 in comments['replies'] %} + {% if comment2["parentId"] == comment1['commentId']%} +
+
{#- For decoration purposes #} +
+
+ {%- if user %} {#- Appears only if the user is logged in #} +
+ + + + + {% endif -%} +

{{ comment2['votes'] }}

+ {%- if user %} {#- Appears only if the user is logged in #} + +
+ {% endif -%} +
+
+ {%- if (comment2['authorImg']) and (comment2['authorImg']|length > 5) %} + the user {{ comment2['author'] }} + {%- else %} + the user {{ comment2['author'] }} + {% endif -%} +
+
+ {{ comment2['author'] }} +

{{ comment2['commentText'] | e }}

+ {#- There is no reply button here, which was done with coordination with Joe #} +
+
+

{{ comment2['dateCreated'] }}

+
+
+ {% endif -%} + + {% endfor -%} {#- of the second level comments #} + {% endfor -%} {#- of the first level comments #} +
+ {% endif -%} +
+ +
+{%- endblock content %} + diff --git a/app/templates/postSubmitted.html b/app/templates/postSubmitted.html index e564bae..2576c00 100644 --- a/app/templates/postSubmitted.html +++ b/app/templates/postSubmitted.html @@ -1,28 +1,28 @@ -{#- Version 1.1 - 08.07.2019, 16:00 #} -{#- Modified according to re-factoring suggested by Professor Chuang #} - -{#- Version 1.0 - 08.06.2019, 16:00 #} -{#- This is the 'postSubmitted.html' template. When a user submits a post, he or she is redirected to this page. #} -{#- It, hence, extends only the 'baseLoggedIn.html' template #} -{#- The links below must have been included in the 'head' tag before 'extends'; otherwise, they won't be noticed by the application. #} - - - - - - -{#- Assume that after the registration, the user is logged in automatically: #} -{%- extends "base.html" %} - -{#- Since this template inherits everything from a base template, all we modify here is the 'content' block: #} -{%- block content %} -
-

Post submitted.

-
{#- Note: no info besides 'action' redirection is submitted by this form. Don't add 'method = post' here! #} - -
-
{#- Note: no info besides 'action' redirection is submitted by this form. Don't add 'method = post' here! #} - -
-
-{% endblock content -%} \ No newline at end of file +{#- Version 1.1 - 08.07.2019, 16:00 #} +{#- Modified according to re-factoring suggested by Professor Chuang #} + +{#- Version 1.0 - 08.06.2019, 16:00 #} +{#- This is the 'postSubmitted.html' template. When a user submits a post, he or she is redirected to this page. #} +{#- It, hence, extends only the 'baseLoggedIn.html' template #} +{#- The links below must have been included in the 'head' tag before 'extends'; otherwise, they won't be noticed by the application. #} + + + + + + +{#- Assume that after the registration, the user is logged in automatically: #} +{%- extends "base.html" %} + +{#- Since this template inherits everything from a base template, all we modify here is the 'content' block: #} +{%- block content %} +
+

Post submitted.

+
{#- Note: no info besides 'action' redirection is submitted by this form. Don't add 'method = post' here! #} + +
+
{#- Note: no info besides 'action' redirection is submitted by this form. Don't add 'method = post' here! #} + +
+
+{% endblock content -%} diff --git a/app/templates/posts.html b/app/templates/posts.html index 38becea..bde9416 100644 --- a/app/templates/posts.html +++ b/app/templates/posts.html @@ -18,7 +18,7 @@
{#- If user presses the button, he or she will be redirected to create a new post! #} {%- if user %} -
+
{% endif -%} @@ -27,8 +27,13 @@ {#- the posts in which port to sort! #}
@@ -54,7 +59,7 @@
{%- if user %} {#- Appears only if the user is logged in #} -
+ {% endif -%} - + + +

{#- Since 'post['image']' is optional, we must have the following 'if' statement. #} {%- if post['image'] != None %} - the post {{ post['postTitle'] | e }} + the post {{ post['postTitle'] | e }} {% endif %}

p/{{ post['portName'] }} - {{ post['postTitle'] | e }} + {{ post['postTitle'] | e }} {%- if post['postText'] != None %} -

{{ post['postText'] | e }}

+

{{ post['postText'] | e }}

{% endif -%}

{{ post['numComments'] }} comments

@@ -110,10 +117,11 @@

Posted by:

{#- Since 'post['avatarUrl']' is optional, we must have the following 'if' statement. #} - {%- if post['avatarUrl'] != None %} - the user {{ post['username'] }} - {%- else %} - the user {{ post['author'] }} + {%- if post['authorImg']|length > 10 %} + + {% else %} + {% endif -%} {{ post['author'] }}
diff --git a/app/templates/register.html b/app/templates/register.html index 119b9ad..e6d0d3f 100644 --- a/app/templates/register.html +++ b/app/templates/register.html @@ -43,13 +43,19 @@

Sign Up!

type="text" class="first_name" name="first" - placeholder="First Name" + placeholder="First Name (max. length 30)" + title = "First Name" + onkeyup = "validateNames(this)" + onmousemove = "validateNames(this)" />
@@ -57,12 +63,14 @@

Sign Up!

type="text" class="usernameForm" name="username" - placeholder="Username" + placeholder="Username (length 7-30)" + title = "Username (length 7-30)" required onkeyup="validateUserNameLength()" + onmousemove = "validateUserNameLength()" /> - {%- if errUsernameInUse %} - Username already in use! + {%- if username_error %} + Error: Username already in use! {%- endif %}
@@ -70,14 +78,14 @@

Sign Up!

type="email" class="email" name="email" - placeholder="Email Address" + placeholder="Email Address (max. length 128)" + title = "Email Address (max. length 128)" required onkeyup="validateEmail()" + onmousemove = "validateEmail()" /> - {%- if errUsernameInUse %} - Error: Have you signed up already? + {%- if email_error %} + Error: Email address already in use! {%- endif %}
@@ -85,8 +93,10 @@

Sign Up!

type="password" name="password" class="password" - placeholder="Password" + placeholder="Password (length 7 - 128)" + title = "Password (length 7 - 128)" onkeyup="validatePassword(this)" + onmousemove = "validatePassword(this)" required /> Sign Up! name="confirm_password" class="confirm_password" placeholder="Re-enter Password" + title = "Re-enter Password" onkeyup="validatePassword(this)" + onmousemove = "validatePassword(this)" required />
@@ -104,13 +116,16 @@

Sign Up!

name="addimage" class = "addimage" placeholder="Add URL to Your Image" + title = "Add URL to Your Image" + onkeyup = "URLLength ()" />
diff --git a/app/templates/scripts.js b/app/templates/scripts.js deleted file mode 100644 index 7cb1cc9..0000000 --- a/app/templates/scripts.js +++ /dev/null @@ -1,28 +0,0 @@ -// Submit the search if ENTER was pressed: -function submitSearch() { - if (event.which == 13 || event.keyCode == 13) - document.getElementsByClassName("searchform")[0].submit(); -} - -let testAPI = async () => { - const response = await fetch("http://127.0.0.1:5000/test/chalshaff12", {}); - const jsonData = await response.json(); - console.log(jsonData); - const thing = document.querySelector(".trendingTitle"); - thing.textContent = "HELLO"; -}; -testAPI(); - -// // Change the color of the subscription button and what is written on it if it is pressed. Then, submit the form: -// function subscribe(x) { -// var temp = x.id.substr(x.id.length - 1); // Fetch the last char. of the id of the calling button. This is its serial number given as a string. -// if (x.value == "Subscribe") { -// x.style.backgroundColor = "rgb(123, 34, 64)"; // It means the user is subscribed to the particular port. Color the calling button maroon, and -// x.value = "Joined"; // Change the text on the button to 'joined'. -// } // Otherwise, if the user clicked again (to unsubscribe): -// else { -// x.style.backgroundColor = "rgb(117, 117, 117)"; // Turn the color back to gray, -// x.value = "Subscribe"; // Change the text on the button to 'Subscribe'. -// } -// document.getElementById("trendingForm").submit(); // Now submit this information -// } diff --git a/app/templates/userInfo.html b/app/templates/userInfo.html index dd0efe4..543de0b 100644 --- a/app/templates/userInfo.html +++ b/app/templates/userInfo.html @@ -9,6 +9,7 @@ + {%- extends "base.html" %} {#- Since this template inherits everything from a base template, all we modify here is the 'content' block: #} @@ -36,7 +37,7 @@ {% endif -%}
{#- Since 'viewedUser['avatarUrl']' is optional, we must have the following 'if' statement. #} - {%- if viewedUser['avatarUrl'] != None %} + {%- if viewedUser['avatarUrl'] | length > 1 %} the user {{ viewedUser['username'] }} {%- else %} the user {{ viewedUser['username'] }} @@ -54,18 +55,32 @@ {%- else %}

(No description added)

{% endif -%} -
- - + + +
- +
-
+
@@ -78,17 +93,17 @@
-
-

@@ -129,18 +144,18 @@
- *
-
-
-
+

CHANGE PASSWORD

-
- *
-
-
@@ -260,5 +275,204 @@ {% endif -%}
+ {%- elif dashboard %} +
+
+

DASHBOARD

+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ + {%- if (subscrptions) and (user) %} + {%- for port in user['myPorts'] %} + {#- Display alternating colors for odd and even-numbered posts: #} + {%- if loop.index % 2 != 0 %} +
+ {%- else %} +
+ {% endif -%} + +
+

{{ port['mem'] }} members

+
+
+
+ + {%- if port['isSubscribed'] == True %} + + {%- else %} {#- if it is False: #} + + {% endif -%} {#- the one of 'port['isSubscribed']' #} +
+
+
+ {% endfor -%} + {%- elif (comments) and (user) %} + {%- for comment in user['myComments'] %} + {#- Display alternating colors for odd and even-numbered posts: #} + {%- if loop.index % 2 != 0 %} +
+ {%- else %} +
+ {% endif -%} +
+

{{ comment['totalVotes'] }}

+
+
+ +
+

{{ comment['text'] }}

+
+
+
+

{{ comment['dateCreated'] }}

+
+
+ {% endfor -%} + {%- elif (savedPosts) and (user) %} + {%- for post in user['savedPosts'] %} + {#- Display alternating colors for odd and even-numbered posts: #} + {%- if loop.index % 2 != 0 %} +
+ {%- else %} +
+ {% endif -%} +
+

{{ post['totalVotes'] }}

+
+
+ +
+ {%- if post['text'] %} +

{{ post['text'] }}

+ {% else %} +

(No text content)

+ {% endif -%} +
+
+
+
+

{{ post['dateCreated'] }}

+
+
+ {#- Since 'post['avatarUrl']' is optional, we must have the following 'if' statement. #} + {%- if post['avatarUrl'] | length > 1 %} + the user {{ post['username'] }} + {%- else %} + the user {{ post['username'] }} + {% endif -%} + {{ post['username'] }} +
+
+
+ {% endfor -%} + {%- elif (myPosts) and (user) %} + {%- for post in user['myPosts'] %} + {#- Display alternating colors for odd and even-numbered posts: #} + {%- if loop.index % 2 != 0 %} +
+ {%- else %} +
+ {% endif -%} +
+

{{ post['totalVotes'] }}

+
+
+ +
+

{{ post['commentNum'] }} comments

+
+
+
+ {#- Since 'post['imageUrl']' is optional, we must have the following 'if' statement. #} + {%- if post['imageUrl'] != None %} + {%- if post['imageUrl'] | length > 1 %} + the post {{ post['title'] | e }} + {% endif %} + {% endif %} +
+
+ +
+ {%- if post['text'] != None %} +

{{ post['text'] | e }}

+ {% endif -%} +
+
+
+

{{ post['dateCreated'] }}

+
+
+ {% endfor -%} + {% endif -%} +
+
{% endif -%} {% endblock content -%} + diff --git a/app/templates/writePost.html b/app/templates/writePost.html index cc1d8db..9f2c1b8 100644 --- a/app/templates/writePost.html +++ b/app/templates/writePost.html @@ -28,18 +28,22 @@ action="/new-post/" method="POST" enctype="multipart/form-data" + onsubmit = "submitWithEscape();" >

Create a post on p/

- - + + {#- Please pass here an array of dicts called 'ports' of all existing + ports, each of which dict has the attribute: 'name' #} {%- for port in + ports %} + + {% endfor -%}

*

@@ -49,17 +53,19 @@

Create a post on p/

*
- - +
- +
- +
diff --git a/app/test.py b/app/test.py index 09473d2..7fd232c 100644 --- a/app/test.py +++ b/app/test.py @@ -75,10 +75,11 @@ def hello7(): ) +# Two new optional agruments: `username_error` and `email_error` (08.12.2019) @app.route("/register/") def hello8(): return render_template( - "register.html", name="Bla", trendPorts=trendPorts, errUsernameInUse=True + "register.html", name="Bla", trendPorts=trendPorts, username_error = True, email_error = True ) @@ -214,12 +215,68 @@ def hello11(): # Examples of Post Details Template # Create a post dictionary. It will look like this: -postDict = {'id': 257, 'title': 'Want to Order Some Pizza on the Last Day of Classes?', 'portname': "CISCRocks", 'totalVotes': 1000, 'image': 'https://cdn.apartmenttherapy.info/image/fetch/f_auto,q_auto:eco/https%3A%2F%2Fstorage.googleapis.com%2Fgen-atmedia%2F3%2F2018%2F03%2F55cd28cae8ee78fe1e52ab1adc9eafff24c9af92.jpeg', 'text': "Why shouldn't we?", 'commentNum': 5, 'dateCreated': '2019-08-11 02:23:04', 'username': 'mary060196', 'avatarUrl': 'https://cdn.shopify.com/s/files/1/1061/1924/products/Thumbs_Up_Hand_Sign_Emoji_large.png?v=1480481047', 'upOrDownvoted': 1, - 'comments': [{'id': 1, 'totalVotes': 64, 'dateCreated': '2019-08-11 10:10:10', 'username': 'jtroia', 'avatarUrl': 'https://cdn.sandals.com/beaches/v12/images/general/destinations/home/beach.jpg', 'text': "How hadn't I thought of it myself? Great idea!", 'upOrDownvoted': 1, - 'comments' : [{'id': 4, 'totalVotes': 24, 'dateCreated': '2019-08-11 15:15:15', 'username': 'mary060196', 'avatarUrl': 'https://cdn.shopify.com/s/files/1/1061/1924/products/Thumbs_Up_Hand_Sign_Emoji_large.png?v=1480481047', 'text': "Yea! We'll just have to find a good pizzeria and notify the class.", 'upOrDownvoted': 0}, - {'id': 5, 'totalVotes': 15, 'dateCreated': '2019-08-11 15:20:15', 'username': 'jtroia', 'avatarUrl': 'https://cdn.sandals.com/beaches/v12/images/general/destinations/home/beach.jpg', 'text': "I will send everyone a message on Slack (if anybody even opens it.)", 'upOrDownvoted': 0}]}, - {'id': 2, 'totalVotes': 59, 'dateCreated': '2019-08-11 10:20:36', 'username': 'bla-bla', 'avatarUrl': 'https://www.designrepublic.com/27631-large_default/blabla-big-plexi.jpg', 'text': "Bla bla bla bla bla. Bla bla bla bla!", 'upOrDownvoted': -1, 'comments': {}}, - {'id': 3, 'totalVotes': 12, 'dateCreated': '2019-08-11 10:20:36', 'username': 'wowwow1', 'avatarUrl': None, 'text': "Wow wow wow wow wow. Wow wow wow wow!", 'upOrDownvoted': 0, 'comments': {}}]} +postDict = { + 'id': 257, + 'title': 'Want to Order Some Pizza on the Last Day of Classes?', + 'portname': "CISCRocks", + 'totalVotes': 1000, + 'image': 'https://cdn.apartmenttherapy.info/image/fetch/f_auto,q_auto:eco/https%3A%2F%2Fstorage.googleapis.com%2Fgen-atmedia%2F3%2F2018%2F03%2F55cd28cae8ee78fe1e52ab1adc9eafff24c9af92.jpeg', + 'text': "Why shouldn't we?", + 'commentNum': 5, + 'dateCreated': '2019-08-11 02:23:04', + 'username': 'mary060196', + 'avatarUrl': 'https://cdn.shopify.com/s/files/1/1061/1924/products/Thumbs_Up_Hand_Sign_Emoji_large.png?v=1480481047', + 'upOrDownvoted': 1, + 'comments': [ + { + 'id': 1, + 'totalVotes': 64, + 'dateCreated': '2019-08-11 10:10:10', + 'username': 'jtroia', + 'avatarUrl': 'https://cdn.sandals.com/beaches/v12/images/general/destinations/home/beach.jpg', + 'text': "How hadn't I thought of it myself? Great idea!", + 'upOrDownvoted': 1, + 'comments' : [ + { + 'id': 4, + 'totalVotes': 24, + 'dateCreated': '2019-08-11 15:15:15', + 'username': 'mary060196', + 'avatarUrl': 'https://cdn.shopify.com/s/files/1/1061/1924/products/Thumbs_Up_Hand_Sign_Emoji_large.png?v=1480481047', + 'text': "Yea! We'll just have to find a good pizzeria and notify the class.", + 'upOrDownvoted': 0 + }, + { + 'id': 5, + 'totalVotes': 15, + 'dateCreated': '2019-08-11 15:20:15', + 'username': 'jtroia', + 'avatarUrl': 'https://cdn.sandals.com/beaches/v12/images/general/destinations/home/beach.jpg', + 'text': "I will send everyone a message on Slack (if anybody even opens it.)", + 'upOrDownvoted': 0 + }] + }, + { + 'id': 2, + 'totalVotes': 59, + 'dateCreated': '2019-08-11 10:20:36', + 'username': 'bla-bla', + 'avatarUrl': 'https://www.designrepublic.com/27631-large_default/blabla-big-plexi.jpg', + 'text': "Bla bla bla bla bla. Bla bla bla bla!", + 'upOrDownvoted': -1, + 'comments': [] + }, + { + 'id': 3, + 'totalVotes': 12, + 'dateCreated': '2019-08-11 10:20:36', + 'username': 'wowwow1', + 'avatarUrl': None, + 'text': "Wow wow wow wow wow. Wow wow wow wow!", + 'upOrDownvoted': 0, + 'comments': [] + }] +} # 'user' is logged in, and optional argument 'commentSubmittedMessage' is passed: @app.route('/post-details1') @@ -234,7 +291,7 @@ def hello13(): #---------------------------------- User Info Template -------------------------- # What the 'viewedUser' object must have (this is other than the 'user' dict) -viewedUser1 = {'username': 'mary060196', 'email': 'mary060196@gmail.com', 'avatarUrl': 'https://cdn.shopify.com/s/files/1/1061/1924/products/Thumbs_Up_Hand_Sign_Emoji_large.png?v=1480481047', 'description': "I love CISC since I was a child.", 'isEmailPrivate': False} +viewedUser1 = {'username': 'mary060196', 'email': 'mary060196@gmail.com', 'avatarUrl': '', 'description': "I love CISC since I was a child.", 'isEmailPrivate': False} viewedUser2 = {'username': 'jtroia', 'email': 'jtroia@joetroia.com', 'avatarUrl': 'https://cdn.sandals.com/beaches/v12/images/general/destinations/home/beach.jpg', 'description': "Lorem Ipsum ... and other stuff.", 'isEmailPrivate': False} # We also want to update the 'user' to contain the following: @@ -265,7 +322,153 @@ def hello16(): def hello17(): return render_template('userInfo.html', name = "Bla", trendPorts = trendPorts, user = user, accountSettings = True, notifications = True) +# ------------------------------------- 08.13.2019 Dashboard ----------------------------- + +# We need to update the 'user' one more time to contain (1) subscribed port data: +myPorts = [ + { + 'id': 1, + 'name': 'port2', + 'mem': 17 + }, + { + 'id': 2, + 'name': 'CISCRocks', + 'mem': 223 + }, + { + 'id': 3, + 'name': 'bcNews', + 'mem': 523 + } +] +# (2) Written comments: +myComments = [ + { + 'postname': "What I Love about CISC", + 'portname': "CISCRocks", + 'totalVotes': 12, + 'text': "There is no more of a professional than you to write such a great post!", + 'dateCreated': '2019-08-19 21:21:21' + }, + { + 'postname': "What Classes Do You Take Next Semester?", + 'portname': "bcNews", + 'totalVotes': 19, + 'text': "Computer and Ethics CISC 2820W", + 'dateCreated': '2019-08-15 14:03:45' + }, + { + 'postname': "How Can I deploy an App with Travis CI?", + 'portname': "CISCRocks", + 'totalVotes': 6, + 'text': "Why doing this with Travis CI? Google Cloud is better!", + 'dateCreated': '2019-08-13 07:58:24' + } +] + +# (3) Saved Posts +savedPosts = [ + { + 'title': "What I Love about CISC", + 'portname': "CISCRocks", + 'totalVotes': 36, + 'text': "What a wonderful world!", + 'dateCreated': '2019-08-11 02:23:04', + 'username': 'jtroia', + 'avatarUrl': 'https://cdn.sandals.com/beaches/v12/images/general/destinations/home/beach.jpg' + }, + { + 'title': "OK I am Lazy Enough to Write This Post", + 'portname': "offTopic", + 'totalVotes': 10000, + 'text': "Bla Bla squared . . . Bla Bla squared . . . Bla Bla squared . . . Bla Bla squared . . .", + 'dateCreated': '2019-08-11 02:23:04', + 'username': 'bla-bla', + 'avatarUrl': 'https://www.designrepublic.com/27631-large_default/blabla-big-plexi.jpg' + }, + { + 'title': "What to Write about Now?", + 'portname': "offTopic", + 'totalVotes': 100, + 'text': "Bla Bla cubed . . . Bla Bla cubed . . . Bla Bla cubed . . . Bla Bla cubed . . .", + 'dateCreated': '2019-08-11 02:23:04', + 'username': 'bla-bla', + 'avatarUrl': 'https://www.designrepublic.com/27631-large_default/blabla-big-plexi.jpg' + } +] + +# and, finally, written posts: + +myPosts = [ + { + 'title': "Bla Bla Post", + 'portname': "CISCRocks", + 'totalVotes': 3, + 'imageUrl': 'https://dxxbxu0f802py.cloudfront.net/wp-content/uploads/2016/07/28093037/feature_are_you_blabla.jpg', + 'commentNum': 55, + 'text': "Just a post", + 'dateCreated': '2019-08-11 02:23:04' + }, + { + 'title': "Foo Post", + 'portname': "CISCRocks", + 'totalVotes': 30, + 'imageUrl': None, + 'commentNum': 50, + 'text': "Just a post", + 'dateCreated': '2019-08-11 02:23:04' + }, + { + 'title': "YAML Post", + 'portname': "CISCRocks", + 'imageUrl': None, + 'commentNum': 1000, + 'totalVotes': 300, + 'text': "Just a post", + 'dateCreated': '2019-08-11 02:23:04' + } +] + +# And we put all of these into the user object: +user['myPorts'] = myPorts +user['myComments'] = myComments +user['savedPosts'] = savedPosts +user['myPosts'] = myPosts + +# Examples for Dashboard: + +# 'user' is logged in and is looking at the "Dashboard" in the section "Subscriptions": +@app.route('/dashboard1') +def hello18(): + return render_template('userInfo.html', name = "Bla", trendPorts = trendPorts, user = user, dashboard = True, subscrptions = True) + +# 'user' is logged in and is looking at the "Dashboard" in the section "Comments": +@app.route('/dashboard2') +def hello19(): + return render_template('userInfo.html', name = "Bla", trendPorts = trendPorts, user = user, dashboard = True, comments = True) + +# 'user' is logged in and is looking at the "Dashboard" in the section "Saved Posts": +@app.route('/dashboard3') +def hello20(): + return render_template('userInfo.html', name = "Bla", trendPorts = trendPorts, user = user, dashboard = True, savedPosts = True) + +# 'user' is logged in and is looking at the "Dashboard" in the section "My Posts": +@app.route('/dashboard4') +def hello21(): + return render_template('userInfo.html', name = "Bla", trendPorts = trendPorts, user = user, dashboard = True, myPosts = True) + +#-------------------------- 404 Error & No Password Reminders ------------- + +# 404 Error Template: +@app.route('/404-error') +def hello22(): + return render_template('_404Error.html', name = "Bla", trendPorts = trendPorts, user = user) +# No "Forgot Password?" Reminders!: +@app.route('/no-such-thing-forgot-password') +def hello23(): + return render_template('noPasswordReminders.html', name = "Bla", trendPorts = trendPorts, user = user) if __name__ == "__main__": # webbrowser.open_new("http://localhost:8181/") @@ -283,9 +486,15 @@ def hello17(): # webbrowser.open_new("http://localhost:8181/post-details1") # webbrowser.open_new("http://localhost:8181/post-details2") # webbrowser.open_new("http://localhost:8181/newsfeed2/") - webbrowser.open_new("http://localhost:8181/user-profile1") - webbrowser.open_new("http://localhost:8181/user-profile2") - webbrowser.open_new("http://localhost:8181/account-settings1") - webbrowser.open_new("http://localhost:8181/account-settings2") + # webbrowser.open_new("http://localhost:8181/user-profile1") + # webbrowser.open_new("http://localhost:8181/user-profile2") + # webbrowser.open_new("http://localhost:8181/account-settings1") + # webbrowser.open_new("http://localhost:8181/account-settings2") + # webbrowser.open_new("http://localhost:8080/dashboard1") + # webbrowser.open_new("http://localhost:8080/dashboard2") + # webbrowser.open_new("http://localhost:8080/dashboard3") + # webbrowser.open_new("http://localhost:8080/dashboard4") + webbrowser.open_new("http://localhost:8080/404-error") + # webbrowser.open_new("http://localhost:8080/no-such-thing-forgot-password") app.run("localhost", 8181, True, use_reloader=False) diff --git a/product/ud-doggo.png b/product/ud-doggo.png new file mode 100644 index 0000000..2dddbca Binary files /dev/null and b/product/ud-doggo.png differ diff --git a/product/ud-logo.png b/product/ud-logo.png new file mode 100644 index 0000000..ff14470 Binary files /dev/null and b/product/ud-logo.png differ diff --git a/requirements.txt b/requirements.txt index ece1bd8..db29c51 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,19 +1,25 @@ +appdirs==1.4.3 +attrs==19.1.0 +black==19.3b0 certifi==2019.6.16 chardet==3.0.4 Click==7.0 Flask==1.1.1 -itsdangerous==1.1.0 -MarkupSafe==1.1.1 +Flask-Cors==3.0.9 +Flask-Login==0.4.1 get==2019.4.13 +gunicorn==19.9.0 idna==2.8 -Jinja2==2.10.1 +itsdangerous==1.1.0 +Jinja2==2.11.3 +MarkupSafe==1.1.1 mysql-connector==2.2.9 post==2019.4.13 public==2019.4.13 query-string==2019.4.13 request==2019.4.13 requests==2.22.0 -urllib3==1.25.3 -Werkzeug==0.15.5 six==1.12.0 -Flask-Cors==3.0.8 +toml==0.10.0 +urllib3==1.26.5 +Werkzeug==0.15.5 diff --git a/server_config/README.md b/server_config/README.md deleted file mode 100644 index bd4eada..0000000 --- a/server_config/README.md +++ /dev/null @@ -1,2 +0,0 @@ -Server config - diff --git a/test1.py b/test1.py new file mode 100644 index 0000000..9f1b437 --- /dev/null +++ b/test1.py @@ -0,0 +1 @@ +print('hi')