diff --git a/_includes/nav_cpthtml b/_includes/nav_cpthtml new file mode 100644 index 0000000..cc923ca --- /dev/null +++ b/_includes/nav_cpthtml @@ -0,0 +1,12 @@ + + + + + + + + + + + +
HomeDB-ADB-BJWTSassImagesGame
\ No newline at end of file diff --git a/_notebooks/2023-09-19-python-sql-U2-4a.ipynb b/_notebooks/2023-09-19-python-sql-U2-4a.ipynb index 7d9e742..4de54e3 100644 --- a/_notebooks/2023-09-19-python-sql-U2-4a.ipynb +++ b/_notebooks/2023-09-19-python-sql-U2-4a.ipynb @@ -13,6 +13,7 @@ "courses: { csp: {week: 13} }\n", "categories: []\n", "type: ccc\n", + "permalink: /cpt/db-a\n", "---" ] }, diff --git a/_notebooks/2023-09-19-python-sql-U2-4b.ipynb b/_notebooks/2023-09-19-python-sql-U2-4b.ipynb index 9c12dfa..11c5105 100644 --- a/_notebooks/2023-09-19-python-sql-U2-4b.ipynb +++ b/_notebooks/2023-09-19-python-sql-U2-4b.ipynb @@ -12,6 +12,7 @@ "description: Using Programs with Data is focused on SQL and database actions. Part B focuses on learning SQL commands, connections, and curses using an Imperative programming style.\n", "courses: { csp: {week: 13} }\n", "categories: []\n", + "permalink: /cpt/db-b\n", "type: ccc\n", "---" ] diff --git a/_notebooks/2023-11-13-PBL-control.ipynb b/_notebooks/2023-11-13-PBL-control.ipynb new file mode 100644 index 0000000..c1dc487 --- /dev/null +++ b/_notebooks/2023-11-13-PBL-control.ipynb @@ -0,0 +1,194 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "---\n", + "layout: post\n", + "toc: true\n", + "title: API/Control\n", + "description: Between Model and View is Control. In this Web application it will be handled by APIs. Data will be input and displayed through View and stored in Model. Control will broker information between projects.\n", + "permalink: /cpt/api\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## API/Control Terms\n", + "> APIs work with methods to GET, POST, PUT, and UPDATE data. Control helps with Requests, Response, and handling JSON. Control is glue layer, thus the term Model-View-Control (or MVC).\n", + "- POST APIs interact with CREATE methods in Model.\n", + "- GET with READ\n", + "- PUT with UPDATE.\n", + "- DELETE with DELETE.\n", + "\n", + "> During development it is best to work with Model and Control without involving View initially. To support this type of development ...\n", + "- Become familiar with [Postman](https://www.postman.com/downloads/)\n", + "- FYI, as an alternative you can become familiar with working with APIs through ***curl***\n", + "\n", + "### Resource\n", + "[API Docs](https://flask-restful.readthedocs.io/en/latest/api.html)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Control/API code\n", + "> ***Control/API concepts*** are receiving and API request and returning a response. \n", + "\n", + "1. [Define API flask objects (api/user.py)](https://github.com/nighthawkcoders/flask_portfolio/blob/main/api/user.py#L7-L11). Flask contains object that help in API definition.\n", + "2. [Register API objects (main.py)](https://github.com/nighthawkcoders/flask_portfolio/blob/main/main.py#L11-L23). Every Flask object in the project needs to be registered with the \"main\" objects.\n", + "3. [Create/POST method](https://github.com/nighthawkcoders/flask_portfolio/blob/main/api/user.py#L14-L54). Post method contains a lot of checking code, but ultimately it creates a database row in the Model and returns that row to the View.\n", + "4. [Read/GET method](https://github.com/nighthawkcoders/flask_portfolio/blob/main/api/user.py#L14-L54). This shows off Object Relational Manager performing a User (class operation) to extract all records from the table and putting them into User objects.\n", + "5. [Define API endpoints](https://github.com/nighthawkcoders/flask_portfolio/blob/main/api/user.py#L62-L64). Endpoints are somewhat patterns to be matched. Note, url_prefix at top of file supplies \"/api/users\" prefix for each pattern. Each pattern when matched invokes the correspond class. Methods are defined in class to correspond to expectations (POST, GET, UPDATE, DELETE).\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from flask import Blueprint, request, jsonify\n", + "from flask_restful import Api, Resource # used for REST API building\n", + "from datetime import datetime\n", + "\n", + "from model.users import User\n", + "\n", + "# blueprint, which is registered to app in main.py\n", + "user_api = Blueprint('user_api', __name__,\n", + " url_prefix='/api/users')\n", + "\n", + "# API docs https://flask-restful.readthedocs.io/en/latest/api.html#id1\n", + "api = Api(user_api)\n", + "class UserAPI: \n", + " class _Create(Resource):\n", + " def post(self):\n", + " ''' Read data for json body '''\n", + " body = request.get_json()\n", + " \n", + " ''' Avoid garbage in, error checking '''\n", + " # validate name\n", + " name = body.get('name')\n", + " if name is None or len(name) < 2:\n", + " return {'message': f'Name is missing, or is less than 2 characters'}, 210\n", + " # validate uid\n", + " uid = body.get('uid')\n", + " if uid is None or len(uid) < 2:\n", + " return {'message': f'User ID is missing, or is less than 2 characters'}, 210\n", + " # look for password and dob\n", + " password = body.get('password')\n", + " dob = body.get('dob')\n", + "\n", + " ''' #1: Key code block, setup USER OBJECT '''\n", + " uo = User(name=name, \n", + " uid=uid)\n", + " \n", + " ''' Additional garbage error checking '''\n", + " # set password if provided\n", + " if password is not None:\n", + " uo.set_password(password)\n", + " # convert to date type\n", + " if dob is not None:\n", + " try:\n", + " uo.dob = datetime.strptime(dob, '%m-%d-%Y').date()\n", + " except:\n", + " return {'message': f'Date of birth format error {dob}, must be mm-dd-yyyy'}, 210\n", + " \n", + " ''' #2: Key Code block to add user to database '''\n", + " # create user in database\n", + " user = uo.create()\n", + " # success returns json of user\n", + " if user:\n", + " return jsonify(user.read())\n", + " # failure returns error\n", + " return {'message': f'Processed {name}, either a format error or User ID {uid} is duplicate'}, 210\n", + "\n", + " class _Read(Resource):\n", + " def get(self):\n", + " users = User.query.all() # read/extract all users from database\n", + " json_ready = [user.read() for user in users] # prepare output in json\n", + " return jsonify(json_ready) # jsonify creates Flask response object, more specific to APIs than json.dumps\n", + "\n", + " # building RESTapi endpoint\n", + " api.add_resource(_Create, '/create')\n", + " api.add_resource(_Read, '/')" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Testing APIs\n", + "> ***Backend Testing*** of APIs is best done through Browser for simple GET APIs, but other API methods (POST, UPDATE, DELETE) will require a tool like PostMan.\n", + "\n", + "1. [Download Postman](https://www.postman.com/downloads/). This tool test APIs effectively on localhost and is great aid for debugging.\n", + "\n", + "2. [Main.py runtime configuration](https://github.com/nighthawkcoders/flask_portfolio/blob/main/main.py#L44-L47). This configuration is setup to produce same port and localhost as deployment.\n", + "\n", + "***`Run` locally as you develop*** Select main.py file in VSCode and press Play button, or press down arrow next to Play button to activate Debug testing. The below dialog will appear in Terminal, though IP address will match you machines.\n", + "\n", + "```bash\n", + "(base) machine:flask_portfolio user$ cd /Users/user/vscode/flask_portfolio ; /usr/bin/env /Users/user/opt/anaconda3/bin/python /Users/user/.vscode/extensions/ms-python.python-2022.20.2/pythonFiles/lib/python/debugpy/adapter/../../debugpy/launcher 61127 -- /Users/user/vscode/flask_portfolio/main.py \n", + " * Serving Flask app \"__init__\" (lazy loading)\n", + " * Environment: production\n", + " WARNING: This is a development server. Do not use it in a production deployment.\n", + " Use a production WSGI server instead.\n", + " * Debug mode: on\n", + " * Running on all addresses.\n", + " WARNING: This is a development server. Do not use it in a production deployment.\n", + " * Running on http://192.168.1.75:8086/ (Press CTRL+C to quit)\n", + " * Restarting with watchdog (fsevents)\n", + " * Debugger is active!\n", + " * Debugger PIN: 403-552-045\n", + "```\n", + "\n", + "***`Test` API GET locally with Postman***. Observe that tests may be saved. \n", + "![](images/postmain_read_get_users.png)\n", + "\n", + "***`Test` API POST locally with Postman***. In this case, Postman can be used to add new records to the table. Observe options to pass data using Body raw-json.\n", + "![](images/postman_create_post_users.png)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Hacks\n", + "Objective of these hacks is to complete full stack. This include Model (flask database), View (github pages markdown), and Control (flask API endpoint).\n", + "\n", + "1. Make Create and Read API endpoints for your project\n", + "2. Test API endpoints by creating test cases in Postman\n", + "3. Build a Frontend for Create and Read endpoints\n", + "4. Make a 30-60 second video showing this work" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.12 ('base')", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.11.5" + }, + "orig_nbformat": 4, + "vscode": { + "interpreter": { + "hash": "8b82d5009c68ba5675978267e2b13a671f2a7143d61273c5a3813c97e0b2493d" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/_notebooks/2023-11-13-jwt-python-flask.ipynb b/_notebooks/2023-11-13-PBL-jwt.ipynb similarity index 99% rename from _notebooks/2023-11-13-jwt-python-flask.ipynb rename to _notebooks/2023-11-13-PBL-jwt.ipynb index d0caf7b..493dc08 100644 --- a/_notebooks/2023-11-13-jwt-python-flask.ipynb +++ b/_notebooks/2023-11-13-PBL-jwt.ipynb @@ -11,9 +11,9 @@ "title: JWT Project\n", "description: A Python Project that is secured with JSON Web Tokens (JWT)\n", "author: Nikhil Chakravarthula\n", - "courses: { csp: {week: 13, categories: [6.B]} }\n", "categories: [C7.0]\n", "type: ccc\n", + "permalink: /cpt/jwt\n", "---" ] }, diff --git a/_notebooks/2023-11-13-PBL-view.ipynb b/_notebooks/2023-11-13-PBL-view.ipynb new file mode 100644 index 0000000..51b9118 --- /dev/null +++ b/_notebooks/2023-11-13-PBL-view.ipynb @@ -0,0 +1,421 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "layout: post\n", + "toc: true\n", + "title: View/Frontend\n", + "description: Frontend coding and backend design will always be related. In building Views you we will need to create in frontend designs that will work with the backend data or databases. \n", + "permalink: /cpt/api\n", + "---" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## GitHub Pages Organization and Design\n", + "> HTML, JavaScript, and a JavaScript fetch are all things you can do in a GitHub Pages View. Additionally, every GitHub page inherits from Theme, minimizing need to define a lot of CSS. Some key elements...\n", + "- Style, the visual design.\n", + " - SASS files in `assets/css/style.scss`, review GitHub pages theme for instructions\n", + "- Head and Body. The HTML tags used to structure every page.\n", + " - Layout files in `_layouts/default.html`, structure is provided by GitHub pages theme\n", + " - Supplement layout with files in `_includes`, for instance `_layouts/home.html` is used to add menu selections to pages by including it in `_layouts/default.html`.\n", + "- Page. Markdown or HTML is defined and constructed into page using Jekyll Build, refer to `content` reference in `_layouts/default.html`. Observe how files are built by looking at generated `html` files under `_site`." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## View/CRUD Concepts\n", + "> In a database project, the key idea is to build a system for capturing key information. For instance, ***student information*** on students and allowing ***blogging** to a Teacher would have Frontend View elements that correspond to a Backend Database. \n", + "\n", + "> Backend Database CRUD operations are as follows...\n", + "- Create new student records\n", + "- Read a list of students\n", + "- Update student data\n", + "- Delete records\n", + "\n", + "### Frontend Visual concepts of the Idea\n", + "![Screen Concept]({{site.baseurl}}/images/crud.png)\n", + "\n", + "### HTML to Obtain Input is a key step (aka Create/Input Step)\n", + "\n", + "#### HTML5 table is a way to organize input\n", + "- th labels\n", + "- td input types\n", + "- onclick action" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "/*\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "*/" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Table

\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### HTML5 form is another way to organize input\n", + "- form action vs onclick\n", + "- p labels and input, in real implementation combine with CSS" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "/*\n", + "
\n", + "

\n", + "

\n", + "

\n", + "

\n", + "

\n", + "

\n", + " \n", + "

\n", + "
\n", + "*/" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Form

\n", + "
\n", + "

\n", + "

\n", + "

\n", + "

\n", + "

\n", + "

\n", + " \n", + "

\n", + "
" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### JavaScript Fetch and Response (aka Post Step)\n", + "- After Input call action\n", + "- Extract data from DOM\n", + "- Build url\n", + "- Fetch\n", + "- Add response to end of table" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "function create_User(){\n", + " // extract data from inputs\n", + " const name = document.getElementById(\"name\").value;\n", + " const email = document.getElementById(\"email\").value;\n", + " const password = document.getElementById(\"password\").value;\n", + " const phone = document.getElementById(\"phone\").value;\n", + " const requestOptions = {\n", + " method: 'POST',\n", + " headers: {\n", + " 'Content-Type': 'application/json',\n", + " 'Authorization': 'Bearer my-token',\n", + " },\n", + " };\n", + " //url for Create API\n", + " const url='/crud_api/create/' + name + '/' + email+ '/' + password + '/' + phone;\n", + " //Async fetch API call to the database to create a new user\n", + " fetch(url, requestOptions).then(response => {\n", + " // prepare HTML search result container for new output\n", + " const resultContainer = document.getElementById(\"result\");\n", + " // trap error response from Web API\n", + " if (response.status !== 200) {\n", + " const errorMsg = 'Database response error: ' + response.status;\n", + " console.log(errorMsg);\n", + " // Email must be unique, no duplicates allowed\n", + " document.getElementById(\"pswError\").innerHTML =\n", + " \"Email already exists in the table\";\n", + " return;\n", + " }\n", + " // response contains valid result\n", + " response.json().then(data => {\n", + " console.log(data);\n", + " //add a table row for the new/created userId\n", + " const tr = document.createElement(\"tr\");\n", + " for (let key in data) {\n", + " if (key !== 'query') {\n", + " //create a DOM element for the data(cells) in table rows\n", + " const td = document.createElement(\"td\");\n", + " console.log(data[key]);\n", + " //truncate the displayed password to length 20\n", + " if (key === 'password'){\n", + " td.innerHTML = data[key].substring(0,17)+\"...\";\n", + " }\n", + " else{\n", + " td.innerHTML = data[key];}\n", + " //add the DOM data element to the row\n", + " tr.appendChild(td);\n", + " }\n", + " }\n", + " //append the DOM row to the table\n", + " table.appendChild(tr);\n", + " })\n", + " })\n", + "}" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### HTML and JavaScript Display Table\n", + "> JavaScript below shows elements needed to construct the rows of data in the table.\n", + "- JSON is required, it is hardcoded in this example. Typically JSON will come from a JavaScript fetch.\n", + "- JSON object is required, it is created from JSON string. This allows access to to elements in JSON using JavaScript dot notation (user._name)\n", + "- DOM editing is a huge part of the remainder of this example. DOM elements often nest inside of other DOM elements. For instance each `td` is nested in `tr`. ***Find examples*** of DOM create and append in the code below.\n", + "- Notice the definition of ***table*** and build you own map or visual of how these things are put together." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "/*\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
NameIDActions
\n", + "*/\n", + "\n", + "// Static json, this can be used to test data prior to API and Model being ready\n", + "const json = '[{\"_name\": \"Thomas Edison\", \"_uid\": \"toby\"}, {\"_name\": \"Nicholas Tesla\", \"_uid\": \"nick\"}, {\"_name\": \"John Mortensen\", \"_uid\": \"jm1021\"}, {\"_name\": \"Eli Whitney\", \"_uid\": \"eli\"}, {\"_name\": \"Hedy Lemarr\", \"_uid\": \"hedy\"}]';\n", + "\n", + "// Convert JSON string to JSON object\n", + "const data = JSON.parse(json);\n", + "\n", + "// prepare HTML result container for new output\n", + "const table = document.getElementById(\"table\");\n", + "data.forEach(user => {\n", + " // build a row for each user\n", + " const tr = document.createElement(\"tr\");\n", + "\n", + " // td's to build out each column of data\n", + " const name = document.createElement(\"td\");\n", + " const id = document.createElement(\"td\");\n", + " const action = document.createElement(\"td\");\n", + " \n", + " // add content from user data \n", + " name.innerHTML = user._name; \n", + " id.innerHTML = user._uid; \n", + "\n", + " // add action for update button\n", + " var updateBtn = document.createElement('input');\n", + " updateBtn.type = \"button\";\n", + " updateBtn.className = \"button\";\n", + " updateBtn.value = \"Update\";\n", + " updateBtn.style = \"margin-right:16px\";\n", + " updateBtn.onclick = function () {\n", + " alert(\"Update: \" + user._uid);\n", + " };\n", + " action.appendChild(updateBtn);\n", + "\n", + " // add action for delete button\n", + " var deleteBtn = document.createElement('input');\n", + " deleteBtn.type = \"button\";\n", + " deleteBtn.className = \"button\";\n", + " deleteBtn.value = \"Delete\";\n", + " deleteBtn.style = \"margin-right:16px\"\n", + " deleteBtn.onclick = function () {\n", + " alert(\"Delete: \" + user._uid);\n", + " };\n", + " action.appendChild(deleteBtn); \n", + "\n", + " // add data to row\n", + " tr.appendChild(name);\n", + " tr.appendChild(id);\n", + " tr.appendChild(action);\n", + "\n", + " // add row to table\n", + " table.appendChild(tr);\n", + "});" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## View/Blog Concepts\n", + "> A notes/blog would be created to add ***Notes*** between students and teacher, part of original concept. Notes could be used for many types of applications. Details on creating notes will be part of another blog, but for now we want you to think about design.\n", + "- In this design, most recent messages are on top\n", + "- Messages are intended to support markdown and inclusion of images\n", + "- Think about technique to format images in conjunction with Text\n", + "\n", + "![Notes and Images](images/notes.png)\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Hacks\n", + "> Build and correlate a technical design between frontend view and backend model. This blog is focussing on frontend view., and visual concepts on how CRUD operations are presented to user of system. This particular Jupyter Notebook and code within it are used to help establish technical ideas. Start a design for your project...\n", + "- Each project must have a View (as pictured) and Model (json data is fetched into the View). Describe your project.\n", + "- Describe your View. Use Markdown, HTML, ***UML***, other visuals, tables are used to characterize a project. This shows the Teacher and Graders understanding of planning Model and View.\n", + "- Transition from pure design and start inserting code elements, like inputs. Also, try build a table with json data versus fetching data.\n", + "- Issues should discuss problems/challenges, in Teacher/Student data here are a couple ... \n", + " - This design will have many JavaScript actions, at least one for each CRUD operation. In this design, developer needs think of JavaScript functions to replace placeholder alerts in example code above.\n", + " - There can be different roles for CRUD operations. For instance, student will only interact with their own account. Teacher may interact with many accounts.\n", + " - Given these CRUD operations what kind of APIs are needed? They should map closely button/on click actions, as each action will fetch or manipulate data differently.\n", + "\n", + "> Extra Credit. Student(s) could assist in rework of my Flask project from last year into a Frontend / Backend solution. Additionally, if Frontend is done correctly it could easily be modified to work with both Spring and Flask backends.\n", + "\n", + "## References\n", + "> Here are some working samples\n", + "\n", + "- [Fetching table data](https://nighthawkcoders.github.io/APCSP/data/database)\n", + "\n", + "- [Obtaining input](https://nighthawkcoders.github.io/APCSP/frontend/grades)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "JavaScript (Node.js)", + "language": "javascript", + "name": "javascript" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "javascript", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12 (main, Apr 5 2022, 01:53:17) \n[Clang 12.0.0 ]" + }, + "vscode": { + "interpreter": { + "hash": "8b82d5009c68ba5675978267e2b13a671f2a7143d61273c5a3813c97e0b2493d" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/_posts/2023-11-13-CSP-tri2_cpt.md b/_posts/2023-11-13-CSP-tri2_cpt.md index 5e4f20d..78ce179 100644 --- a/_posts/2023-11-13-CSP-tri2_cpt.md +++ b/_posts/2023-11-13-CSP-tri2_cpt.md @@ -2,7 +2,8 @@ toc: true comments: false layout: post -title: Innovation, CPT +title: Innovation, CPT Project +permalink: /cpt/home description: Innovation requirements for the Create Performance Task type: collab courses: { csp: {week: 13} } @@ -15,16 +16,16 @@ Students and teams will ***transition to "Create Performance Task" projects***. Plan your Create Performance Task with Classroom Requirements. - During this time individuals will be ... - - learning more about APIs - - creating frontend forms for CRUD operations - - makining backend APIs that support backend Databases CRUD actions + - styling frontend with SASS + - creating frontend for CRUD operations + - learning more about APIs connecting to Database Tables + - supporting backend Databases CRUD actions and OOP - As we get deeper in the trimester... - add user login and site security - - enahancing style through SCCS - - design pages with multiple actions - - have a feature uploading, scaling, and storing (images) - - support complex SQL data types to support JSON + - have features to upload, scale, and store images + - design frontend pages with animation and OOP + - support complex SQL data types to support images and JSON - support primary and foreign key relations in SQL - Teams will start project with Design Documents. There will be lectures to support. @@ -75,4 +76,5 @@ Data and Procedural Abstraction - AAP-1.D.b: Explain how the use of data abstraction manages complexity in program code. - AAP-2.O.a: Write iteration statements to traverse a list. - AAP-2.O.b: Determine the result of an algorithm that includes list traversals. - - AAP-3.B: Explain how the use of procedural abstraction manages complexity in a program. \ No newline at end of file + - AAP-3.B: Explain how the use of procedural abstraction manages complexity in a program. + \ No newline at end of file diff --git a/_posts/2023-11-13-PBL-sassy.md b/_posts/2023-11-13-PBL-sassy.md new file mode 100644 index 0000000..9eded2e --- /dev/null +++ b/_posts/2023-11-13-PBL-sassy.md @@ -0,0 +1,349 @@ +--- +toc: true +comments: false +layout: post +title: UX, Theme and SASS +description: User Experience tips on customizing theme, plus concepts and terms on using SASS. Contributions on SASS +author: Charlie Zhu (class of 2022) +permalink: /cpt/sass +--- + +## User Experience Design + +* At Qualcomm, I was involved in projects related to Customer Experience. In this design phase, Corporate User Experience designers would create concepts of what that system would look like. As a second phase, I would give those concepts to Frontend Designers that would put the concepts into code with motion. We are trying to simulate these steps through Markdown, a little HTML, images, etc. In this process, we can build a concept of a system, prior to having functional code behind the scenes, aka JavaScript, APIs, Backend. + +### Build GitHub pages SASS files + +* Build and explore the output of scss. + +* Build per instruction in Project README + +```text +### Jekyll ### +_site +.sass-cache +.jekyll-cache +.jekyll-metadata +``` + +* Explore output CSS, for example look at customization for h1, h2, ... + * _site/assets/css/style.css + +* Look at other assets, see all the work that goes into Style. Learn to leverage off of it. Learn to customize on top of it using SASS tips in the blog. + +### Stylesheet Notes from [Midnight Theme](https://github.com/pages-themes/midnight/blob/master/README.md#stylesheet) + +Altering GitHub theme and adding custom styles: + +1. Create a file called `/assets/css/style.scss` in your site +2. Add the following content to the top of the file, exactly as shown: + + ```scss + --- + --- + + @import "{{ site.theme }}"; + ``` + +3. Add any custom CSS (or Sass, including imports) you'd like immediately after the `@import` line + +*Note: If you'd like to change the theme's Sass variables, you must set new values before the `@import` line in your stylesheet.* + +### Layouts Notes from [Midnight Theme](https://github.com/pages-themes/midnight/blob/master/README.md#layouts) + +If you'd like to change the theme's HTML layout: + +1. For some changes such as a custom `favicon`, you can add custom files in your local `_includes` folder. The files [provided with the theme](https://github.com/pages-themes/midnight/tree/master/_includes) provide a starting point and are included by the [original layout template](https://github.com/pages-themes/midnight/blob/master/_layouts/default.html). +2. For more extensive changes, [copy the original template](https://github.com/pages-themes/midnight/blob/master/_layouts/default.html) from the theme's repository
(*Pro-tip: click "raw" to make copying easier*) +3. Create a file called `/_layouts/default.html` in your site +4. Paste the default layout content copied in the first step +5. Customize the layout as you'd like + +## Welcome to SASS +> +> SASS helps process a SASS file and compile it like the usual CSS file. Using SASS let's us leverage off of a lot of implementation that has already been performed, such as GitHub pages. But it also lets you more programmatically build CSS. + +![image](https://user-images.githubusercontent.com/72889453/149642880-22b11bab-1c1c-4741-999b-77c1697ce1ec.png) + +## SASS Prerequisites +> +> Skip downloads section unless you have issues. + +### Downloads / Command Prompt Lines + +* Check for `npm --version` to verify install, or download node.js [here](https://nodejs.org/en/) (just download the LTS version). + +* This line of code is just used to check that you actually have npm installed, if not run installer : + +```bash +npm --version +``` + +* Next you will use check for sass : + +```bash +npm view sass version +``` + +* Install sass if required : + +```bash +npm install -g sass +``` + +## SASS Tips + +### Features / Functionality + +* As the great thing about scss is that ***it writes the css for you***, making it much less tedious. There are many aspects as to why it actually simplifies the process. + +### Aspect 1: Partials + +* Sass naturally transpiles all the .scss files directly. However, when you want to import a file, you do not need the file to be transpiled directly. Sass has a mechanism for this: If you start the filename with an underscore, Sass will not transpile it. Files named this way are called partials and they allow you to work in a much more organized space. +![dwankawkldnalwdlkwandklawjdklajdlkwajdlajwldjalwd](https://user-images.githubusercontent.com/72889453/149645411-25d66017-4dd9-4fa5-8728-2f92cc38eac9.png) + +### Aspect 2: Defining Colors / Variables + +* Rather than retyping the hexadecimal values of each color every single time, you can define all of the ones you want to use in a partial and then just reference them with $[color] when you want to use it. However, make sure you import the partial into the scss file where you are going to use it in. + +``` scss +$light: #f7f7f7; +$dark: #222121; +$lime: #00cc66; +$orangeRed: #fb4b4e; +$blue: #2541b2; +``` + +* Example shown here: + +``` scss +.navbar { + background: $light; // see how instead of having to retype the hexadecimal, I can just reference it like this WOWOW so COOL + height: 80px; + display: flex; + justify-content: space-between; + padding: 0.5rem calc((100vw - 1200px) / 2); + z-index: 10; + position: relative; +``` + +### Aspect 3: Nested Styling + +* Another unique aspect about scss is that you can actually nest styles, so if you want an aspect like let's say color to apply to everything you are working on for that portion of the html, you can actually nest the rest of the formatting, animations, etc within that definition. +* Implementation shown here with the Hero section in student scss: + +``` scss +.hero { + background-color: $light; // see how the rest of the code is indented / nested within .hero + + &__container { + display: grid; + grid-template-columns: 1fr 1fr; + align-items: center; + justify-items: center; + margin: 0 auto; + height: 90vh; + z-index: 1; + width: 100%; + max-width: 1200px; + padding-right: 24px; + padding-left: 24px; + + @include tablet { // @include tablet and @include mobile will be explained next + grid-template-columns: 1fr; + height: 100%; + } + + &--left { + width: 100%; + line-height: 1.2; + + @include tablet { + padding: 5rem 0; + } + + @include mobile { + line-height: 1.5; + } + } + + &--left h1 { + font-size: 4rem; + color: $lime; + + @include mobile { + font-size: 1.5rem; + } + } + + &--left h2 { + font-size: 4rem; + color: $dark; + + @include mobile { + font-size: 2rem; + } + } + + &--left p { + font-size: 2rem; + color: $dark; + margin-top: 1rem; + font-weight: 700; + + @include mobile { + font-size: 1.5rem; + } + } + + &--btn { + font-size: 1rem; + background-color: $lime; + padding: 14px 32px; + border: none; + border-radius: 4px; + color: $light; + margin-top: 2rem; + cursor: pointer; + position: relative; + transition: all 0.3s; + outline: none; + } + + &--btn a { + position: relative; + z-index: 2; + color: $light; + text-decoration: none; + } + + &--btn:after { // code animates home page button so that it transitions to red when hovered + position: absolute; + content: ''; + top: 0; + left: 0; + width: 0; + height: 100%; + background: $orangeRed; + transition: all 0.3s; + border-radius: 4px; + } + + &--btn:hover:after { + width: 100%; + } + + &--right { + text-align: center; + } + + &--img { + height: 100%; + width: 100%; + } + } +} +``` + +* You can see how this code works in tandem with the Hero section of the HTML, the class definitions are associated with every definition of styling coded above: + +``` html + +``` + +### Aspect 4: Easily Change Formatting Based on Device + +* With the power of scss, you can more easily than ever change the formatting of your site based on which device a person is using. +* Such can be done by defining the resolutions in a partial like here: + +``` scss + +``` + +* Then you can use @include to reference these resolutions and change the css/formatting based on the device like here: + +``` scss +&--left h1 { + font-size: 4rem; + color: $lime; + + @include mobile { // in this case the font size changes because it's mobile + font-size: 1.5rem; + } +} + +&--left h2 { + font-size: 4rem; + color: $dark; + + @include mobile { + font-size: 2rem; + } +} +``` + +### Aspect 5: Extending, Inheritance, and Calculations + +* In scss, you can also use @extend if you want certain classes to inherit attributes from previously defined classes, sort of similar to nesting inheritance (where the classes nested within inherit the attributes from outermost classes). An example is shown below: + +``` scss + +``` + +* Furthermore, you can actually use math operators like multiplication, addition, subtraction and division in scss. In the code below I use it to extend the animation of a button: + +``` scss +&--btn:hover:after { + width: 100% * 4; //makes the animation extend way farther, past the border of the button +} +``` + +### Supporting Videos + +* These are just some videos Charlie found that he thinks are helpful, click on the images to go directly to the videos! +[![IntelliJ and SASS files compile with File watcher](https://img.youtube.com/vi/LtMgTdjWEuk/0.jpg)](https://www.youtube.com/watch?v=LtMgTdjWEuk "IntelliJ and SASS files compile with File watcher") +[![Learn Sass In 20 Minutes | Sass Crash Course](https://img.youtube.com/vi/Zz6eOVaaelI/0.jpg)](https://www.youtube.com/watch?v=Zz6eOVaaelI "Learn Sass In 20 Minutes | Sass Crash Course") + +## Hacks + +* All hacks related to SASS are with respect to design of your project(s) diff --git a/images/crud.png b/images/crud.png new file mode 100644 index 0000000..46eadb3 Binary files /dev/null and b/images/crud.png differ