{"id":21090212,"url":"https://github.com/nikeshcohen/cool-tech-blog","last_synced_at":"2026-05-16T23:31:39.758Z","repository":{"id":221029653,"uuid":"753250085","full_name":"NikeshCohen/Cool-Tech-Blog","owner":"NikeshCohen","description":"The project is a tech news blog website, featuring user authentication, article management, and category views. It demonstrates clean design and security practices, allowing users to browse, search, and interact based on their role (reader, writer, or admin).","archived":false,"fork":false,"pushed_at":"2024-03-25T07:20:51.000Z","size":653,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-14T06:14:57.893Z","etag":null,"topics":["blog","laravel","php","sql"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NikeshCohen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-05T18:53:59.000Z","updated_at":"2024-03-25T12:53:33.000Z","dependencies_parsed_at":"2024-02-05T20:24:11.933Z","dependency_job_id":"679156eb-b97d-4b35-8c0f-2fc8535fb3c5","html_url":"https://github.com/NikeshCohen/Cool-Tech-Blog","commit_stats":null,"previous_names":["nikeshcohen/-task-9---laravel"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/NikeshCohen/Cool-Tech-Blog","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NikeshCohen%2FCool-Tech-Blog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NikeshCohen%2FCool-Tech-Blog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NikeshCohen%2FCool-Tech-Blog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NikeshCohen%2FCool-Tech-Blog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NikeshCohen","download_url":"https://codeload.github.com/NikeshCohen/Cool-Tech-Blog/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NikeshCohen%2FCool-Tech-Blog/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33122075,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T18:38:32.183Z","status":"ssl_error","status_checked_at":"2026-05-16T18:38:29.903Z","response_time":115,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blog","laravel","php","sql"],"created_at":"2024-11-19T21:34:54.719Z","updated_at":"2026-05-16T23:31:39.723Z","avatar_url":"https://github.com/NikeshCohen.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"./design/cool-tech.png\" width=\"400\" alt=\"Laravel Logo\"\u003e\u003c/a\u003e\u003c/p\u003e\n\n# Project Documentation: Tech News Blog\n\n1.  [Overview](#overview)\n\n2.  [Database](#database)\n\n    -   [Entity Relationship Diagram](#entity-relationship-diagram)\n\n3.  [Website Routes](#website-routes)\n\n    -   [Required](#required)\n\n    -   [Additional](#additional)\n\n4.  [Compulsory Task 1](#compulsory-task-1)\n\n    -   [Home page requirements](#home-page-requirements)\n\n    -   [Article View](#article-view)\n\n    -   [Category View](#category-view)\n\n    -   [Tag View](#tag-view)\n\n    -   [Legal Pages](#legal-pages)\n\n5.  [Compulsory Task 2](#compulsory-task-2)\n\n    -   [Search](#search)\n\n6.  [Cookie Notice](#cookie-notice)\n\n7.  [Footer Date](#footer-date)\n\n8.  [Bonus Task 1 - Writers Dashboard](#bonus-task-1---writers-dashboard)\n\n9.  [Bonus Task 2 - Admin Dashboard](#bonus-task-2---admin-dashboard)\n\n10. [Bonus Task 3 - User Auth](#bonus-task-3---user-auth)\n\n    -   [Login](#login)\n\n    -   [Register](#register)\n\n11. [Notable Mentions](#notable-mentions)\n\n## Overview\n\nThis documentation provides an overview of the mock website created for a fictional tech news blog. The project emphasizes robust user authentication following industry-standard security practices.\n\nNB: Please ensure you run `php artisan hash:user-passwords`once you have inserted the data I have provided. This command ensures all user passwords are hashed. This is just for the test data, when an individual creates a new user via the site their password will be hashed automatically.\n\n## Database\n\nPlease insert the data provided in 'database.sql' in the order provided, as it is a relational database there will be errors if a flied is entered before its foreign key reference.\n\nAs mentioned above it is extremely important to run `php artisan hash:user-passwords` to ensure the program runs as expected. The details for this command can be found in `app\\Console\\Commands\\HashUserPasswords.php`\n\nAll required article categories presented in in the task requirements are present:\n\n```sql\nINSERT INTO Categories (CategoryName) VALUES\n('Tech news'),\n('Software reviews'),\n('Hardware reviews'),\n('Opinion pieces');\n```\n\n### Entity Relationship Diagram\n\nBelow is the ERD for the website's database.\n\n![](./design/ERD-Diagram.png)\n\n## Website Routes\n\nAll required routes presented in in the task requirements are present.\n\n### Required\n\n| Page          | Route               |\n| ------------- | ------------------- |\n| Home          | /                   |\n| Article View  | /article/{id}       |\n| Category View | /category/{slug}    |\n| Tag View      | /tag/{slug}         |\n| About Us      | /about              |\n| Search        | /search             |\n| Legal         | /legal/{subsection} |\n\n### Additional\n\n| Page              | Route            | Description       |\n| ----------------- | ---------------- | ----------------- |\n| Login             | /login           | Login in route    |\n| Register          | /register        | Register Route    |\n| Dashboard         | /dashboard       | Writers dashboard |\n| Dashboard - admin | /dashboard/admin | Admin dashboard   |\n\n## Compulsory Task 1\n\nThe ERD diagram is present above.\n\n### Home page requirements\n\nBelow is an image of what the article card looks like on the home page of the site. The main title, subheading, continue reading and each tag are all links that point to their respective destinations\n\nFile path: [resources\\views\\home.blade.php](resources\\views\\home.blade.php)\n\n![](./design/home.png)\n\n### Article View\n\nEach article can be viewed via /article/{ArticleID}.\nFile path: [routes\\web.php](routes\\web.php)\n\n```php\nRoute::get('/article/{id}', [ArticleController::class, 'showArticle'])-\u003ename('article.show');\n```\n\nAll requests get routed to the [Article Controller](app\\Http\\Controllers\\ArticleController.php)\n\n### Category View\n\nEach category can be viewed via /category/{slug}.\nFile path: [routes\\web.php](routes\\web.php)\n\n```php\nRoute::get('/category/{slug}', [CategoriesController::class, 'showCategory'])-\u003ename('category.show');\n```\n\nAll requests get routed to the [Categories Controller](app\\Http\\Controllers\\CategoriesController.php)\n\n### Tag View\n\nEach tag can be viewed via /tag/{slug}.\nFile path: [routes\\web.php](routes\\web.php)\n\n```php\nRoute::get('/tag/{slug}', [TagsController::class, 'showTag'])-\u003ename('tag.show');\n```\n\nAll requests get routed to the [Tag Controller](app\\Http\\Controllers\\TagsController.php)\n\n### Legal Pages\n\nAccesses /legal results in an option to view either Terms of Service or Privacy policy. Both /legal/tos and legal/privacy have the same end point. Different content is register based on the slug.\n\n[Legal Page](resources\\views\\legal.blade.php)\n\nRoute:\n\n```php\nRoute::group(['prefix' =\u003e 'legal'], function () {\n    Route::get('/', [LegalController::class, 'showLegal'])-\u003ename('legal.show');\n    Route::get('/{subsection}', [LegalController::class, 'showLegalSubsection'])\n        -\u003ewhere('subsection', 'tos|privacy')\n        -\u003ename('legal.subsection');\n});\n```\n\nPage Logic:\n\n```php\n@if(isset($subsection) \u0026\u0026 $subsection === 'tos')\n    // Display tos\n@elseif(isset($subsection) \u0026\u0026 $subsection === 'privacy')\n    // Display privacy\n@else\n    // Display options\n@endif\n```\n\n## Compulsory Task 2\n\n### Search\n\nI did not created 3 different search bars as I believe that is not user experience, taking that into consideration i opted to create a single search bar along with a drop down menu with options; ArticleID, Category, Tags. This way the user can select what that would like to search for in a manner that is user friendly.\n\nSearch logic: [app\\Http\\Controllers\\SearchController.php](app\\Http\\Controllers\\SearchController.php)\n\n```html\n\u003cform class=\"flex search-bar\" action=\"{{ route('search.action') }method=\"post\"\u003e\n    @csrf\n    \u003cinput class=\"text\" type=\"text\" name=\"query\" placeholder=\"Search...\"\u003e\n    \u003cselect class=\"text\" name=\"type\"\u003e\n        \u003coption value=\"article\"\u003eArticle ID\u003c/option\u003e\n        \u003coption value=\"category\"\u003eCategory\u003c/option\u003e\n        \u003coption value=\"tag\"\u003eTag\u003c/option\u003e\n    \u003c/select\u003e\n    \u003cbutton class=\"btn btn-primary\" type=\"submit\"\u003eSearch\u003c/button\u003e\n\u003c/form\u003e\n```\n\n![](./design/search.png)\n\n## Cookie Notice\n\nA cookie notice is displayed on every page of the site, once the user closes the cookie or agrees to it, it no longer renders.\n\nCookie Logic: [public\\javascript\\script.js](public\\javascript\\script.js)\nCookie Component: [resources\\views\\components\\cookie-notice.blade.php](resources\\views\\components\\cookie-notice.blade.php)\n\n![](./design/cookie.png)\n\n## Footer Date\n\nFooter Date Logic: [resources\\views\\components\\footer.blade.php](resources\\views\\components\\footer.blade.php)\n\n```php\n\u003cp class=\"center copyright logo-box-text__footer\"\u003e\n    Copyright © 2023-{{ now()-\u003e year }} by Cool Tech PTY (LTD). \u003cbr /\u003eAll rights\n    reserved\n\u003c/p\u003e\n```\n\n## Bonus Task 1 - Writers Dashboard\n\nBelow is an image of the writers dashboard along with valuable information on how the route works\n\nSome key points:\n\n-   It is available via `/dashboard`\n-   Only users with IsWriter are able to access it\n-   If a normal user tries to access it they get redirected to the home page\n-   If a non logged in user tries to access it they get redirected to the login page with an auth required message.\n    ```php\n    return redirect()-\u003eroute('login')-\u003ewithErrors(['login' =\u003e 'You must blogged in to access the dashboard.']);\n    ```\n-   If an admin tries to access it the get redirected to `/dashboard/admin`\n-   The authors names gets automatically populated based on the user that is logged in. It uses the relation between UserID in current session the UserID present in the Author table\n\n    ```php\n    $author = DB::table('Authors')-\u003ewhere('UserID', $user-\u003eUserID)-\u003efirst();\n    ```\n\nLogic(Controlling Access): [app\\Http\\Controllers\\UserController.php](app\\Http\\Controllers\\UserController.php)\nLogic(Adding Data): [app\\Http\\Controllers\\CoolTechDBController.php](app\\Http\\Controllers\\CoolTechDBController.php)\n\nDashboard routes:\n\n```php\nRoute::group(['prefix' =\u003e 'dashboard'], function () {\n    Route::get('/', [UserController::class, 'validateUser'])-\u003ename('dashboard');\n    Route::get('/admin', [UserController::class, 'validateAdmin'])-\u003ename('admin');\n});\n```\n\n![](./design/writers-dash.png)\n\n## Bonus Task 2 - Admin Dashboard\n\nBelow is an image of the admin dashboard along with valuable information on how the route works\n\n### User Management\n\nThe admin has the ability to manage users.\n\n![](./design/Screenshot%202024-02-09%20180157.png)\n\n### Article Management\n\nThe admin has the ability to manage articles.\n\n![](./design/Screenshot%202024-02-09%20180203.png)\n\n## Bonus Task 3 - User Auth\n\nAll logic for the /login and /register route: [app/Http/Controllers/AuthController.php](app/Http/Controllers/AuthController.php)\n\n## Login\n\nBelow is an image of the login route along with some valuable information about how logic behind the authentication\n\nSome key points:\n\n-   Users get an error if details are incorrect\n    ```php\n    return redirect()-\u003eback()-\u003ewithErrors(['login' =\u003e 'Invalid credentials'])-\u003ewithInput();\n    ```\n-   If admin successfully logged in they get redirected to admin dashboard\n-   If writer successfully logged in they get redirected to dashboard\n-   If reader successfully logged in they get redirected home\n\nRoute Information:\n\n```php\nRoute::group(['prefix' =\u003e 'login'], function () {\n    Route::get('/', [AuthController::class, 'showLoginForm'])-\u003ename('login');\n    Route::post('/', [AuthController::class, 'login'])-\u003ename('login.submit');\n});\n```\n\n![](./design/log-in.png)\n\n## Register\n\nBelow is an image of the register route along with some valuable information about how logic behind the authentication\n\nNB: Please note when registering user, it requires a secure password. Here is an example of a valid password: `aG8=02Sh\u003c63u`\n\n-   Users get an error if details are incorrect\n    ```php\n    if ($validator-\u003efails()) {\n        return redirect()-\u003eback()-\u003ewithErrors($validator)-\u003ewithInput();\n    }\n    ```\n-   User is regarded as reader and is redirected home\n\nRoute Information:\n\n```php\nRoute::group(['prefix' =\u003e 'register'], function () {\n    Route::get('/', [AuthController::class, 'showRegisterForm'])-\u003ename('register');\n    Route::post('/', [AuthController::class, 'register'])-\u003ename('register.submit');\n});\n```\n\n![](./design/reg.png)\n\n## Notable Mentions\n\nThe Buttons is the header change and are styled differently based on who is logged in, all subtle changes but make the ux better, in my opinion\n\nAdmin/Writer:\nIf the logged in user is an admin or a writer their name will be displayed on top of two buttons dashboard(which directs to different routes based on user) and log out\n![](./design/header-btns-admin.png)\n\nReader:\nIf the logged in user is normal user their name will be displayed next to the log out button.\n![](./design/header-btns-reader.png)\n\n```\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikeshcohen%2Fcool-tech-blog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnikeshcohen%2Fcool-tech-blog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnikeshcohen%2Fcool-tech-blog/lists"}