diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..ffeef6732 --- /dev/null +++ b/.gitignore @@ -0,0 +1,562 @@ + +# Created by https://www.gitignore.io/api/eclipse,intellij,netbeans,notepadpp,sublimetext,visualstudio +# Edit at https://www.gitignore.io/?templates=eclipse,intellij,netbeans,notepadpp,sublimetext,visualstudio + +### Eclipse ### +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +### Eclipse Patch ### +# Eclipse Core +.project + +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# Annotation Processing +.apt_generated + +.sts4-cache/ + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +target +target/ +target/* +*.iml +.idea +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/**/sonarlint/ + +# SonarQube Plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator/ + +### NetBeans ### +**/nbproject/private/ +**/nbproject/Makefile-*.mk +**/nbproject/Package-*.bash +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +### NotepadPP ### +# Notepad++ backups # + +### SublimeText ### +# Cache files for Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# Workspace files are userAccount-specific +*.sublime-workspace + +# Project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using Sublime Text +# *.sublime-project + +# SFTP configuration file +sftp-config.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +Package Control.merged-ca-bundle +Package Control.userAccount-ca-bundle +oscrypto-ca-bundle.crt +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings + +### VisualStudio ### +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.userAccount +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.userAccount + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# End of https://www.gitignore.io/api/eclipse,intellij,netbeans,notepadpp,sublimetext,visualstudio diff --git a/README-Sample.md b/README-Sample.md new file mode 100644 index 000000000..3cc25f557 --- /dev/null +++ b/README-Sample.md @@ -0,0 +1,74 @@ +# Project Title + +* **Objective** - To create a product... +* **Purpose** - To gain familiarity the following features... + + + + +## Instructions + + +### Testing Application via Postman + +* Ensure that the `start-class` tag in your `pom.xml` encapsulates `com.github.perscholas.MyApplication` +* Open a command line and navigate to the project's root directory and run this command: + * `mvn spring-boot:run` +* Launch the [Postman](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en) app and enter the URI `http://localhost:8080/` and hit Send. +* If your application cannot run because something is occupying a port, use this command with the respective port number specified: + * **OSX and Linux** + * ``kill -kill `lsof -t -i tcp:8080` `` + * **Windows** + * _For use in command line_: + * `for /f "tokens=5" %a in ('netstat -aon ^| find ":8080" ^| find "LISTENING"') do taskkill /f /pid %a` + * _For use in bat-file_: + * `for /f "tokens=5" %%a in ('netstat -aon ^| find ":8080" ^| find "LISTENING"') do taskkill /f /pid %%a` + + + + +## How to Download + +#### Part 1 - Forking the Project +* To _fork_ the project, click the `Fork` button located at the top right of the project. + + +#### Part 2 - Navigating to _forked_ Repository +* Navigate to your github profile to find the _newly forked repository_. +* Copy the URL of the project to the clipboard. + +#### Part 3 - Cloning _forked_ repository +* Clone the repository from **your account** into the `~/dev` directory. + * if you do not have a `~/dev` directory, make one by executing the following command: + * `mkdir ~/dev` + * navigate to the `~/dev` directory by executing the following command: + * `cd ~/dev` + * clone the project by executing the following command: + * `git clone https://github.com/MYUSERNAME/NAMEOFPROJECT` + +#### Part 4 - Check Build +* Ensure that the tests run upon opening the project. + * You should see `Tests Failed: 99 of 99 tests` + + + + + + + +## How to Submit + +#### Part 1 - _Pushing_ local changes to remote repository +* from a _terminal_ navigate to the root directory of the _cloned_ project. +* from the root directory of the project, execute the following commands: + * add all changes + * `git add .` + * commit changes to be pushed + * `git commit -m 'I have added changes'` + * push changes to your repository + * `git push -u origin master` + +#### Part 2 - Submitting assignment +* from the browser, navigate to the _forked_ project from **your** github account. +* click the `Pull Requests` tab. +* select `New Pull Request` \ No newline at end of file diff --git a/README-annotations.md b/README-annotations.md new file mode 100644 index 000000000..44f2c25e5 --- /dev/null +++ b/README-annotations.md @@ -0,0 +1,171 @@ +### About Spring Annotations + +#### `@Entity` +* Annotates class signature +* **Description:** + * Allows the persistence provider to recognize it as a persistence class. + * An object representative of a snap shot of data from a database. + * By default, maps this entity to a table whose name is the name of the annotated class. Can be rerouted via the `@Table` annotation + * Entities are said to be _fungible_, or _mutually interchangeable_. +* **Pre-requesites for use:** + * An interface cannot be an entity. + * An enum cannot be an entity. + * The class can be abstract or concrete. + * The class must define a no-arg constructor. + * Each `Entity` must be annotated with a respective `ID`. + + + + + + + + +
+ +#### `@Id` +* Annotates field declarations +* **Description:** + * Denotes the primary key for this `Entity`. + * Can be generated manually by application or by automatically by the persistence provider. +* **Pre-requisites for use:** + * Class must be annotated with `@Entity` + + + + + + + + + +
+ +#### `@GeneratedValue(strategy = GenerationType.ENUM_VALUE)` +* Annotates `Id` fields. +* **Description:** + * Specifies how the persistence provider will generate this value. + * `GenerationType.SEQUENCE` - specifies the use of database SQL sequence + * `GenerationType.IDENTITY` - uses a database identity column + * `GenerationType.TABLE` - instructs provider to store the sequence name and its current value in a table, increasing the value of each time a new instance of the entity is persisted. + * `GenerationType.AUTO` - default when nothing specified. Provider does generation of a key automatically. It will select an appropriate strategy for a particular database. +* **Pre-requesites for use:** + * Field must be annotated with `@Id`. + + + + + + + + + + + +
+ +#### `@Autowired` +* Annotates field declaration or method-parameters +* **Description** + * injects bean by type + * can be used alone. + * If is used alone, it will be wired by type + * If more than one bean of same type are declared in the container `@Autowired` does not know which beans to use for injection. +* **Pre-requesites for use:** + * Field-type must be annotated with some form of `@Component`. + + + + + + + +
+ +#### `@Component` +* Annotates class signature +* **Description** + * denotes that Spring framework will autodetect these classes for dependency injection when annotation-based configuration and classpath scanning is used. +* **Prerequisites for use:** + * none + + + + + + +
+ +#### `@Service` +* Annotates class signature +* **Description** + * specialized form of `@Component` + * responsible for performing service tasks + * in many case you use this annotation for best practice, but isn't _always_ necessary. +* **Prerequisites for use:** + * none + + + + +
+ +#### `@com.github.perscholas.Controller` +* Annotates class signature +* **Description** + * specialized form of `@Component` + * indicates that a particular class serves the role of a controller + * acts as a stereotype for the annotated class, indicating its role + * dispatcher scans such annotated classes for mapped methods and detects @RequestMapping annotations +* **Pre-requesites for use:** + * none + + + + + + + + +
+ +#### `@RequestMapping` +* Annotates a method signature +* **Description** + * annotation maps HTTP requests to handler methods of MVC and REST controllers. +* **Pre-requesites for use** + * class must be a annotated with `@com.github.perscholas.Controller` + + + + + + + + +
+ +#### `@PathVariable` +* Annotates a method parameter +* **Description** + * indicates that a method parameter should be bound to a URI template variable +* **Pre-requesites for use** + * class must be a annotated with `@com.github.perscholas.Controller` + + + + + + + +
+ +#### `@RequestParam` +* Annotates a method parameter +* **Description** + * indicates that a method parameter should be bound to a web request parameter + * used to extract query parameters, form parameters +* **Pre-requesites for use** + * class must be a annotated with `@com.github.perscholas.Controller` + + \ No newline at end of file diff --git a/README-spring.md b/README-spring.md new file mode 100644 index 000000000..0bdc6615b --- /dev/null +++ b/README-spring.md @@ -0,0 +1,12 @@ +# Spring Boot With JSP Integration Project Template +* **Objective** - The purpose of this repository is to create a standard template to clone from when creating new spring boot projects. + +## How to use +* To use this project as template, _clone_ the project into your `~/dev` directory, +* Upon cloning reconfigure the remote by + 1. delete the `.git` folder associated with project. + 2. `git init` to create a new `.git` folder + 3. point the new `.git` folder to your new remote via `git remote set-url`. +* After reconfiguring remote, open the project in a text editor (VSCode, IntelliJ, SublimeText, Atom, etc.) +* Ensure that the `artifactId` of the project is changed from `spring-template-project` to a more appropriate project name. +* Click view the [`README-Sample.md`](./README-Sample.md) to view _how_ a `README` should be structured for a project. \ No newline at end of file diff --git a/README.md b/README.md index 5c0a1e7fa..c8af18e03 100644 --- a/README.md +++ b/README.md @@ -1,71 +1,57 @@ -# Full Stack Web Application +# Full Stack Web Application - Party Time -* **Objective** - to create an implementation of a web service -* **Purpose** - to demonstrate the construction of a full-stacked web-application -* **Description** - * This Case Study is your first foray into building a full-stack application. You'll be building a Spring MVC based application, which means you'll learn about what it takes to build a functional application from the ground up yourself. - * This is exciting! It's a lot, but we've given you the tools to be able to build what you need, and you get to decide what you do with it. You also get to be creative in choosing what sort of application you want to build! - * You will be working individually to design your app. We hope you'll exercise creativity on this project, sketch some wireframes before you start, make sure you have time to run these ideas by your instructors to get their feedback before you dive too deep into coding! Remember to keep things small and focus on mastering the fundamentals. -* **Additional Resources** - * [The Original Case Study Document](./case-study.pdf) - * [Case Study Outline](./case-study-outline.pdf) - * [Case Study Deliverables](./README_deliverables.md) - * [Identifying Plagiarism](./README_plagiarism.md) - * [Suggested Project Topics](./README_suggested-project-topics.md) +* **Objective** - to create an implementation of a web service. +* **Purpose** - to demonstrate the construction of a full-stacked web-application for Party Time company that offers variety of services for organization of special events and celebrations. +* **Description** + * This Case Study demonstrates the process of building a functional, Spring MVC based full-stack application from ground up. + * The Party Time Company offers party supplies and rentals, catering, gifts and flowers, advice in family event planning. + * Party Time App is an app for users that are planning to arrange a party or a special event. + * The website includes six webpages: Welcome, Login, Registration, Contact Us, Our Services, and Shopping Cart. + + +* **How to run Party Time App project** + + -## Minimum Features -* `RESTful` web service which consumes requests from a front-end web application and caches each request and the respective response to a database. -* The application must support a login functionality. +## Features +* `RESTful` web service consumes requests from a front-end web application and caches each request and the respective response to a database. +* The application supports a login functionality. +* To access the services and view pages of the website a user will need to create their account, register and login with valid credentials. +* This app will allow a user to plan their event by making a choice of the services, products, and equipment, +* building their own package of products or purchasing the ready package, adding the product to shopping cart and view the total for purchased services. + + +## Developmental Notes -## Developmental Notes -### Tech Stack Selection -* Select at least 1 technology from each of the following categories: +### Tech Stack * **Version Control System** - 1. Github - 2. Bitbucket - + Github + * **Wireframe** - 1. Mockflow - 2. Balsamiq - 3. Lucidcharts + PNG files - images of the web pages + * **Frontend** - 1. Angular - 2. React - 3. Vue.JS + Java Server Pages + Cascading Style Sheets(CSS) + JavaScript * **Business Logic** - 1. Java - 2. TypeScript + Java + * **WebServer Implementation** - 1. Spring Boot - 2. At least 1 [backing service](https://12factor.net/backing-services) API + Spring Boot + * **Data Layer** - 1. MySQL - 2. PostgreSQL - 3. MariaDB - - * **Web Server Cloud Deployment** - 1. Heroku - 2. AWS EC2 Instance - - * **Web Application Cloud Deployment** - 1. Netlify - 2. AWS EC2 Instance - - - + MySQL + ### Installation -* It is advised that you make install each of the following technologies to ensure that are at least accessible - * Install [NodeJs](https://nodejs.org/en/). - * Install [Angular](http://angular.io/). - * Install [AngularCli](https://cli.angular.io/). diff --git a/README_deliverables.md b/README_deliverables.md index 4bb20a97f..65d9aa71a 100644 --- a/README_deliverables.md +++ b/README_deliverables.md @@ -44,7 +44,7 @@ ### Spring MVC * This deliverable includes connecting no. 1, 2 and 3 deliverables to function together - * Spring MVC: Responsible for responding to a request made by the user. This can be login, registration, etc. When using Spring MVC make sure to use at least the following functionalities: different type of session management, annotation-based controller, exception handling, models, model attributes. + * Spring MVC: Responsible for responding to a request made by the userAccount. This can be login, registration, etc. When using Spring MVC make sure to use at least the following functionalities: different type of session management, annotation-based controller, exception handling, models, model attributes. ### Junit (Test all DAO classes) diff --git a/README_plagiarism.md b/README_plagiarism.md deleted file mode 100644 index 5b071dae3..000000000 --- a/README_plagiarism.md +++ /dev/null @@ -1,20 +0,0 @@ -### A Note on Plagiarism -* You are encouraged to ask others, including students, instructors, and StackOverflow, for help. However, it is NOT ACCEPTABLE TO COPY another person's code and submit it as your own. More importantly, it is detrimental to your learning and growth. -* All of the following are considered plagiarism or cheating: - * Turning in work that is not your own. - * Turning in someone else's work as your own. - * Hiring, or paying someone to do your work for you. - * Copying words or code without giving credit. - * Building or copying someone else’s idea without their knowledge or giving credit. - * Giving incorrect information about a source. - * Changing words, variable names, etc. but copying the code or files of a source without giving credit. - * Copying so many ideas or code blocks from a source that it makes up the majority of your work, whether you give credit or not. - * Failing to put a quotation in quotation marks. - - -* In an effort to not plagiarize, credit for this content goes to: -* [Plagiarism.org](plagiarism.org), specifically the “plagiarism 101” section. The content was adapted for the code. For more information, please see: - * [What is Plagiarism](http://www.plagiarism.org/plagiarism-101/what-is-plagiarism) - * [Types of Plagiarism](http://www.plagiarism.org/plagiarism-101/types-of-plagiarism) - * [How do I safely write code in my own 'words' and not plagiarize?](http://programmers.stackexchange.com/questions/80167/how-do-i-safely-write-code-in-my-own-words-and-not-plagiarize) - * [Avoiding Plagiarism: Writing Computer Code](http://www.upenn.edu/academicintegrity/ai_computercode.html) diff --git a/README_suggested-project-topics.md b/README_suggested-project-topics.md deleted file mode 100644 index 9b2ac965e..000000000 --- a/README_suggested-project-topics.md +++ /dev/null @@ -1,54 +0,0 @@ - -## Suggested Project Topics - -### (Suggested Project Topic 1) TCP Application - -#### User Stories to Fulfill -* As a client, (not logged in) I - * can send messages to a _peer_. - * can view default channels - * can view all accessible channels - * can view messages live as they are received - -
- - - - - -### (Suggested Project Topic 2) Blog Application - -#### User Stories to Fulfill -* As a client, (not logged in) I - * can create new blog posts - * A blog post can consist of images and text - * can view list of all blog posts - * can view blog posts filtered by blog-tag - * can view new blog posts upon refreshing the DOM - -
- - - - - -### (Suggested Project Topic 3) Application - -#### User Stories to Fulfill -* As a client, (not logged in) I - * can upload new videos - * can view list of all videos - * can post simple text-comments on a video - - - - - -### (Suggested Project Topic 4) Money Management Application - -#### User Stories to Fulfill -* As a client, (not logged in) I - * can create new accounts - * deposit money to each account - * withdrawl money from each account - * transfer money to and from any 2 accounts diff --git a/case-study-outline.pdf b/case-study-outline.pdf deleted file mode 100644 index 94edbd7e7..000000000 Binary files a/case-study-outline.pdf and /dev/null differ diff --git a/case-study.pdf b/case-study.pdf deleted file mode 100644 index 8aa8a71cb..000000000 Binary files a/case-study.pdf and /dev/null differ diff --git a/kill-8080.bat b/kill-8080.bat new file mode 100644 index 000000000..44b34ddda --- /dev/null +++ b/kill-8080.bat @@ -0,0 +1 @@ +for /f "tokens=5" %%a in ('netstat -aon ^| find ":8080" ^| find "LISTENING"') do taskkill /f /pid %%a \ No newline at end of file diff --git a/kill-8080.sh b/kill-8080.sh new file mode 100644 index 000000000..2198716e0 --- /dev/null +++ b/kill-8080.sh @@ -0,0 +1 @@ +kill -kill `lsof -t -i tcp:8080` diff --git a/login.gif b/login.gif new file mode 100644 index 000000000..83aab8e58 Binary files /dev/null and b/login.gif differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000..44a02570e --- /dev/null +++ b/pom.xml @@ -0,0 +1,77 @@ + + + 4.0.0 + PartyTimeWebApp + 0.0.1-SNAPSHOT + war + PartyTimeWebApp + Party Time Project using Spring Boot With JSP View + + org.springframework.boot + spring-boot-starter-parent + 2.1.2.RELEASE + + + + UTF-8 + UTF-8 + 1.8 + + + + com.h2database + h2 + runtime + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.data + spring-data-jpa + + + javax.servlet + jstl + + + + org.apache.tomcat.embed + tomcat-embed-jasper + + + + org.eclipse.jdt.core.compiler + ecj + 4.6.1 + + + junit + junit + 4.12 + test + + + org.springframework.boot + spring-boot-starter-security + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/src/main/java/com/github/perscholas/MainApplication.java b/src/main/java/com/github/perscholas/MainApplication.java new file mode 100644 index 000000000..082a39cc7 --- /dev/null +++ b/src/main/java/com/github/perscholas/MainApplication.java @@ -0,0 +1,12 @@ +package com.github.perscholas; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class MainApplication { + public static void main(String[] args) { + + SpringApplication.run(MainApplication.class, args); + } +} diff --git a/src/main/java/com/github/perscholas/config/WebSecurityConfig.java b/src/main/java/com/github/perscholas/config/WebSecurityConfig.java new file mode 100644 index 000000000..1603ab753 --- /dev/null +++ b/src/main/java/com/github/perscholas/config/WebSecurityConfig.java @@ -0,0 +1,55 @@ +package com.github.perscholas.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +@Configuration +@EnableWebSecurity +public class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + + @Autowired + private UserDetailsService userDetailsService; + + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .antMatchers("/resources/**", "/registration").permitAll() + .anyRequest().authenticated() + .and() + .formLogin() + .loginPage("/login") + .permitAll() + .and() + .logout() + .permitAll(); + } + + @Override + @Bean + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth + .parentAuthenticationManager(authenticationManagerBean()) + .userDetailsService(userDetailsService) + .passwordEncoder(bCryptPasswordEncoder()); + } +} diff --git a/src/main/java/com/github/perscholas/controllers/ServiceCategoryController.java b/src/main/java/com/github/perscholas/controllers/ServiceCategoryController.java new file mode 100644 index 000000000..9a3bef5f1 --- /dev/null +++ b/src/main/java/com/github/perscholas/controllers/ServiceCategoryController.java @@ -0,0 +1,46 @@ +package com.github.perscholas.controllers; + +import com.github.perscholas.models.ServiceCategory; +import com.github.perscholas.services.ServiceCategoryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + + +@Controller +@RequestMapping(value = "/service_category-controller") +public class ServiceCategoryController { + private ServiceCategoryService serviceCategoryService; + + @Autowired + public ServiceCategoryController(ServiceCategoryService serviceCategoryService) { + this.serviceCategoryService = serviceCategoryService; + } + + @GetMapping("/") + public ResponseEntity> index() { + return new ResponseEntity<>(serviceCategoryService.index(), HttpStatus.OK); + } + + @GetMapping("/{id}") + public ResponseEntity show(@PathVariable Integer id) { + return new ResponseEntity<>(serviceCategoryService.show(id), HttpStatus.OK); + } + + @PostMapping("/") + public ResponseEntity create(@RequestBody ServiceCategory serviceCategory) { + return new ResponseEntity<>(serviceCategoryService.create(serviceCategory), HttpStatus.CREATED); + } + + @PostMapping("/{id}") + public ResponseEntity update(@PathVariable Integer id, @RequestBody ServiceCategory serviceCategory) { + return new ResponseEntity<>(serviceCategoryService.update(id, serviceCategory), HttpStatus.OK); + } + + @DeleteMapping("/{id}") + public ResponseEntity destroy(@PathVariable Integer id) { + return new ResponseEntity<>(serviceCategoryService.delete(id), HttpStatus.OK); + } +} \ No newline at end of file diff --git a/src/main/java/com/github/perscholas/controllers/UserAccountController.java b/src/main/java/com/github/perscholas/controllers/UserAccountController.java new file mode 100644 index 000000000..1b68ad086 --- /dev/null +++ b/src/main/java/com/github/perscholas/controllers/UserAccountController.java @@ -0,0 +1,60 @@ +package com.github.perscholas.controllers; + + +import com.github.perscholas.validator.UserValidator; +import com.github.perscholas.models.UserAccount; +import com.github.perscholas.services.SecurityServiceImpl; +import com.github.perscholas.services.UserAccountService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; + +@Controller +public class UserAccountController { + private UserAccountService userAccountService; + private SecurityServiceImpl securityService; + private UserValidator userValidator; + + @Autowired + public UserAccountController(UserAccountService userService, UserValidator userValidator, SecurityServiceImpl securityService) { + this.userAccountService = userService; + this.userValidator = userValidator; + this.securityService = securityService; + } + + @GetMapping(value = "/registration") + public String registration(Model model) { + model.addAttribute("userForm", new UserAccount()); + return "registration"; + } + + @PostMapping(value = "/registration") + public String registration(@ModelAttribute("userForm") UserAccount userAccountForm, BindingResult bindingResult, Model model) { + userValidator.validate(userAccountForm, bindingResult); + if (bindingResult.hasErrors()) { + return "registration"; + } + userAccountService.save(userAccountForm); + securityService.autologin(userAccountForm.getUsername(), userAccountForm.getPasswordConfirm()); + return "redirect:/welcome"; + } + + @GetMapping(value = "/login") + public String login(Model model, String error, String logout) { + if (error != null) { + model.addAttribute("error", "Your username and password are invalid."); + } + if (logout != null) { + model.addAttribute("message", "You have logged out successfully."); + } + + return "login"; + } + + @GetMapping(value = {"/", "/welcome"}) + public String welcome(Model model) { + return "welcome"; + } +} \ No newline at end of file diff --git a/src/main/java/com/github/perscholas/controllers/UserController.java b/src/main/java/com/github/perscholas/controllers/UserController.java new file mode 100644 index 000000000..336c6d9a4 --- /dev/null +++ b/src/main/java/com/github/perscholas/controllers/UserController.java @@ -0,0 +1,46 @@ +package com.github.perscholas.controllers; + +import com.github.perscholas.models.UserAccount; +import com.github.perscholas.services.UserService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; + + +@Controller +@RequestMapping(value = "/user_account-controller") +public class UserController { + private UserService userService; + + @Autowired + public UserController(UserService userService) { + this.userService = userService; + } + + @GetMapping("/") + public ResponseEntity> index() { + return new ResponseEntity<>(userService.index(), HttpStatus.OK); + } + + @GetMapping("/{id}") + public ResponseEntity show(@PathVariable Long id) { + return new ResponseEntity<>(userService.show(id), HttpStatus.OK); + } + + @PostMapping("/") + public ResponseEntity create(@RequestBody UserAccount userAccount) { + return new ResponseEntity<>(userService.create(userAccount), HttpStatus.CREATED); + } + + @PostMapping("/{id}") + public ResponseEntity update(@PathVariable Long id, @RequestBody UserAccount userAccount) { + return new ResponseEntity<>(userService.update(id, userAccount), HttpStatus.OK); + } + + @DeleteMapping("/{id}") + public ResponseEntity destroy(@PathVariable Long id) { + return new ResponseEntity<>(userService.delete(id), HttpStatus.OK); + } +} \ No newline at end of file diff --git a/src/main/java/com/github/perscholas/models/CartItem.java b/src/main/java/com/github/perscholas/models/CartItem.java new file mode 100644 index 000000000..f3f4556dc --- /dev/null +++ b/src/main/java/com/github/perscholas/models/CartItem.java @@ -0,0 +1,85 @@ +package com.github.perscholas.models; + +import javax.persistence.*; + + +@Entity +public class CartItem { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private String strId; + + private String name; + private String description; + private double price; + private int quantity; + private double totalCost; + + @ManyToOne + private ServiceCategory serviceCategory; + + public CartItem(String strId, String name, String description, double price, int quantity, double totalCost, ServiceCategory serviceCategory) { + this.strId = strId; + this.name = name; + this.description = description; + this.price = price; + this.quantity = quantity; + this.totalCost = totalCost; + this.serviceCategory = serviceCategory; + } + + public CartItem() { + + } + + + public String getStrId() { + return strId; + } + + public void setStrId(String strId) { + this.strId = strId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public int getQuantity() { + return quantity; + } + + public void setQuantity(int quantity) { + this.quantity = quantity; + } + + public double getTotalCost() { + return totalCost; + } + + public void setTotalCost(double totalCost) { + this.totalCost = totalCost; + } +} + + diff --git a/src/main/java/com/github/perscholas/models/ServiceCategory.java b/src/main/java/com/github/perscholas/models/ServiceCategory.java new file mode 100644 index 000000000..667d6aec0 --- /dev/null +++ b/src/main/java/com/github/perscholas/models/ServiceCategory.java @@ -0,0 +1,53 @@ +package com.github.perscholas.models; + + +import javax.persistence.*; +import java.util.Set; + +@Entity +public class ServiceCategory { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Integer id; + + private String categoryName; + + @OneToMany + @ElementCollection + private Set userAccounts; + + @OneToMany + @ElementCollection + private Set cartItems; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getCategoryName() { + return categoryName; + } + + public void setCategoryName(String categoryName) { + this.categoryName = categoryName; + } + + public Set getUser() { + return userAccounts; + } + + public void setUser(Set userAccounts) { + this.userAccounts = userAccounts; + } + + public void setCartItems(Set cartItems) { + this.cartItems = cartItems; + } + public Set getCartItems() { + return cartItems; + } +} diff --git a/src/main/java/com/github/perscholas/models/UserAccount.java b/src/main/java/com/github/perscholas/models/UserAccount.java new file mode 100644 index 000000000..b4b036972 --- /dev/null +++ b/src/main/java/com/github/perscholas/models/UserAccount.java @@ -0,0 +1,133 @@ +package com.github.perscholas.models; + + +import javax.persistence.*; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +@Entity +public class UserAccount { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String name; + private String email; + private String address; + private String phNumber; + private String username; + private String password; + + @Transient // don't persist; not a column + private String passwordConfirm; + + @ManyToMany + @ElementCollection + private List userRoles; + + @ManyToOne + private ServiceCategory serviceCategory; + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getPhNumber() { + return phNumber; + } + + public void setPhNumber(String phNumber) { + this.phNumber = phNumber; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPasswordConfirm() { + return passwordConfirm; + } + + public void setPasswordConfirm(String passwordConfirm) { + this.passwordConfirm = passwordConfirm; + } + + public List getUserRoles() { + return userRoles; + } + + public void setUserRoles(List userRoles) { + this.userRoles = userRoles; + } + + public ServiceCategory getServiceCategory() { + return serviceCategory; + } + + public void setServiceCategory(ServiceCategory serviceCategory) { + this.serviceCategory = serviceCategory; + } + + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + UserAccount userAccount = (UserAccount) obj; + return Objects.equals(id, userAccount.id) && + Objects.equals(name, userAccount.name) && + Objects.equals(email, userAccount.email) && + Objects.equals(address, userAccount.address) && + Objects.equals(phNumber, userAccount.phNumber) && + Objects.equals(username, userAccount.username) && + Objects.equals(password, userAccount.password) && + Objects.equals(passwordConfirm, userAccount.passwordConfirm); + } + + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} diff --git a/src/main/java/com/github/perscholas/models/UserRole.java b/src/main/java/com/github/perscholas/models/UserRole.java new file mode 100644 index 000000000..03d548d60 --- /dev/null +++ b/src/main/java/com/github/perscholas/models/UserRole.java @@ -0,0 +1,44 @@ +package com.github.perscholas.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +import javax.persistence.*; +import java.util.List; + +@Entity +public class UserRole { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + private String name; + + @JsonIgnore + @ManyToMany + @ElementCollection + private List userAccounts; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getUsers() { + return userAccounts; + } + + public void setUsers(List userAccounts) { + this.userAccounts = userAccounts; + } +} diff --git a/src/main/java/com/github/perscholas/repositories/ServiceRepository.java b/src/main/java/com/github/perscholas/repositories/ServiceRepository.java new file mode 100644 index 000000000..f0fdb4e3b --- /dev/null +++ b/src/main/java/com/github/perscholas/repositories/ServiceRepository.java @@ -0,0 +1,11 @@ +package com.github.perscholas.repositories; + +import com.github.perscholas.models.ServiceCategory; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + + +@Repository +public interface ServiceRepository extends CrudRepository { +} + diff --git a/src/main/java/com/github/perscholas/repositories/UserRegistrationRepo.java b/src/main/java/com/github/perscholas/repositories/UserRegistrationRepo.java new file mode 100644 index 000000000..5db911168 --- /dev/null +++ b/src/main/java/com/github/perscholas/repositories/UserRegistrationRepo.java @@ -0,0 +1,13 @@ +package com.github.perscholas.repositories; + +import com.github.perscholas.models.UserAccount; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + + +@Repository +public interface UserRegistrationRepo extends CrudRepository { + +} + + diff --git a/src/main/java/com/github/perscholas/repositories/UserRepository.java b/src/main/java/com/github/perscholas/repositories/UserRepository.java new file mode 100644 index 000000000..9d8a73f54 --- /dev/null +++ b/src/main/java/com/github/perscholas/repositories/UserRepository.java @@ -0,0 +1,8 @@ +package com.github.perscholas.repositories; + +import com.github.perscholas.models.UserAccount; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + UserAccount findByUsername(String username); +} diff --git a/src/main/java/com/github/perscholas/repositories/UserRoleRepository.java b/src/main/java/com/github/perscholas/repositories/UserRoleRepository.java new file mode 100644 index 000000000..eb204c041 --- /dev/null +++ b/src/main/java/com/github/perscholas/repositories/UserRoleRepository.java @@ -0,0 +1,7 @@ +package com.github.perscholas.repositories; + +import com.github.perscholas.models.UserRole; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRoleRepository extends JpaRepository { +} diff --git a/src/main/java/com/github/perscholas/services/SecurityServiceImpl.java b/src/main/java/com/github/perscholas/services/SecurityServiceImpl.java new file mode 100644 index 000000000..70ce154ae --- /dev/null +++ b/src/main/java/com/github/perscholas/services/SecurityServiceImpl.java @@ -0,0 +1,46 @@ +package com.github.perscholas.services; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.stereotype.Service; + +@Service +public class SecurityServiceImpl { + private static final Logger logger = LoggerFactory.getLogger(SecurityServiceImpl.class); + private AuthenticationManager authenticationManager; + + private UserDetailsService userDetailsService; + + @Autowired + public SecurityServiceImpl(AuthenticationManager authenticationManager, UserDetailsService userDetailsService) { + this.authenticationManager = authenticationManager; + this.userDetailsService = userDetailsService; + } + + public String findLoggedInUsername() { + Object userDetails = SecurityContextHolder.getContext().getAuthentication().getDetails(); + if (userDetails instanceof UserDetails) { + return ((UserDetails) userDetails).getUsername(); + } + + return null; + } + + public void autologin(String username, String password) { + UserDetails userDetails = userDetailsService.loadUserByUsername(username); + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities()); + + authenticationManager.authenticate(usernamePasswordAuthenticationToken); + + if (usernamePasswordAuthenticationToken.isAuthenticated()) { + SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); + logger.debug(String.format("Auto login %s successfully!", username)); + } + } +} diff --git a/src/main/java/com/github/perscholas/services/ServiceCategoryService.java b/src/main/java/com/github/perscholas/services/ServiceCategoryService.java new file mode 100644 index 000000000..906771ad2 --- /dev/null +++ b/src/main/java/com/github/perscholas/services/ServiceCategoryService.java @@ -0,0 +1,44 @@ +package com.github.perscholas.services; + +import com.github.perscholas.models.ServiceCategory; +import com.github.perscholas.repositories.ServiceRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class ServiceCategoryService { + private ServiceRepository serviceRepository; + + @Autowired + public ServiceCategoryService(ServiceRepository serviceRepository) { + + this.serviceRepository = serviceRepository; + } + + public List index() { + List list = new ArrayList<>(); + serviceRepository.findAll().forEach(list::add); + return list; + } + public ServiceCategory show(Integer id) { + return serviceRepository.findById(id).get(); + } + + public ServiceCategory create(ServiceCategory serviceCategory) { + return serviceRepository.save(serviceCategory); + } + + public ServiceCategory update(Integer id, ServiceCategory newCategory) { + ServiceCategory entrySC = serviceRepository.findById(id).get(); + entrySC.setCategoryName(newCategory.getCategoryName()); + return serviceRepository.save(entrySC); + } + + public Boolean delete(Integer id) { + serviceRepository.deleteById(id); + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/github/perscholas/services/UserAccountService.java b/src/main/java/com/github/perscholas/services/UserAccountService.java new file mode 100644 index 000000000..303495aee --- /dev/null +++ b/src/main/java/com/github/perscholas/services/UserAccountService.java @@ -0,0 +1,53 @@ +package com.github.perscholas.services; + + +import com.github.perscholas.models.UserAccount; +import com.github.perscholas.models.UserRole; +import com.github.perscholas.repositories.UserRepository; +import com.github.perscholas.repositories.UserRoleRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashSet; +import java.util.Set; + +@Service +public class UserAccountService implements UserDetailsService { + private UserRepository userRepository; + private UserRoleRepository userRoleRepository; + private BCryptPasswordEncoder bCryptPasswordEncoder; + + @Autowired + public UserAccountService(UserRepository userRepository, UserRoleRepository userRoleRepository, BCryptPasswordEncoder bCryptPasswordEncoder) { + this.userRepository = userRepository; + this.userRoleRepository = userRoleRepository; + this.bCryptPasswordEncoder = bCryptPasswordEncoder; + } + + @Override + @Transactional(readOnly = true) + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + UserAccount user = userRepository.findByUsername(username); + Set grantedAuthorities = new HashSet<>(); + user.getUserRoles().forEach(role -> grantedAuthorities.add(new SimpleGrantedAuthority(role.getName()))); + return new User(user.getUsername(), user.getPassword(), grantedAuthorities); + } + + public void save(UserAccount user) { + user.setPassword(bCryptPasswordEncoder.encode(user.getPassword())); + user.setUserRoles(userRoleRepository.findAll()); + userRepository.save(user); + } + + public UserAccount findByUsername(String username) { + return userRepository.findByUsername(username); + } +} diff --git a/src/main/java/com/github/perscholas/services/UserService.java b/src/main/java/com/github/perscholas/services/UserService.java new file mode 100644 index 000000000..3ba687533 --- /dev/null +++ b/src/main/java/com/github/perscholas/services/UserService.java @@ -0,0 +1,40 @@ +package com.github.perscholas.services; + +import com.github.perscholas.models.UserAccount; +import com.github.perscholas.repositories.UserRegistrationRepo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class UserService { + private UserRegistrationRepo userRegistrationRepo; + + @Autowired + public UserService(UserRegistrationRepo userRegistrationRepo) { + + this.userRegistrationRepo = userRegistrationRepo; + } + + public Iterable index() { + return userRegistrationRepo.findAll(); + } + + public UserAccount show(Long id) { + return userRegistrationRepo.findById(id).get(); + } + + public UserAccount create(UserAccount userAccount) { + return userRegistrationRepo.save(userAccount); + } + + public UserAccount update(Long id, UserAccount newUserAccountData) { + UserAccount entryUserAccount = userRegistrationRepo.findById(id).get(); + entryUserAccount.setName(newUserAccountData.getName()); + return userRegistrationRepo.save(entryUserAccount); + } + + public Boolean delete(Long id) { + userRegistrationRepo.deleteById(id); + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/github/perscholas/validator/UserValidator.java b/src/main/java/com/github/perscholas/validator/UserValidator.java new file mode 100644 index 000000000..45d591ee4 --- /dev/null +++ b/src/main/java/com/github/perscholas/validator/UserValidator.java @@ -0,0 +1,47 @@ +package com.github.perscholas.validator; + + +import com.github.perscholas.models.UserAccount; +import com.github.perscholas.services.UserAccountService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.ValidationUtils; +import org.springframework.validation.Validator; + +@Component +public class UserValidator implements Validator { + + private final UserAccountService userAccountService; + + public UserValidator(UserAccountService userAccountService) { + this.userAccountService = userAccountService; + } + + @Override + public boolean supports(Class aClass) { + return UserAccount.class.equals(aClass); + } + + @Override + public void validate(Object o, Errors errors) { + UserAccount userAccount = (UserAccount) o; + + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "username", "NotEmpty"); + if (userAccount.getUsername().length() < 6 || userAccount.getUsername().length() > 32) { + errors.rejectValue("username", "Size.userForm.username"); + } + if (userAccountService.findByUsername(userAccount.getUsername()) != null) { + errors.rejectValue("username", "Duplicate.userForm.username"); + } + + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", "NotEmpty"); + if (userAccount.getPassword().length() < 8 || userAccount.getPassword().length() > 32) { + errors.rejectValue("password", "Size.userForm.password"); + } + + if (!userAccount.getPasswordConfirm().equals(userAccount.getPassword())) { + errors.rejectValue("passwordConfirm", "Diff.userForm.passwordConfirm"); + } + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 000000000..6b2d289ed --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,9 @@ +server.port=8080 +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console +spring.mvc.view.prefix: /WEB-INF/jsp/ +spring.mvc.view.suffix: .jsp +spring.messages.basename=validation + +spring.datasource.username=root +spring.datasource.password=root \ No newline at end of file diff --git a/src/main/resources/validation.properties b/src/main/resources/validation.properties new file mode 100644 index 000000000..e33a0b6c1 --- /dev/null +++ b/src/main/resources/validation.properties @@ -0,0 +1,5 @@ +NotEmpty=This field is required. +Size.userAccountForm.username=Please use between 6 and 32 characters. +Duplicate.userAccountForm.username=Someone already has that username. +Size.userAccountForm.password=Try one with at least 8 characters. +Diff.userAccountForm.passwordConfirm=These passwords don't match. \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/dispatcher-servlet.xml b/src/main/webapp/WEB-INF/dispatcher-servlet.xml new file mode 100644 index 000000000..b6307aed4 --- /dev/null +++ b/src/main/webapp/WEB-INF/dispatcher-servlet.xml @@ -0,0 +1,22 @@ + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/jsp/contact_us.jsp b/src/main/webapp/WEB-INF/jsp/contact_us.jsp new file mode 100644 index 000000000..5a38abb57 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/contact_us.jsp @@ -0,0 +1,67 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> + + + + + + Contact Us + + + + + + + +
+ +
+
+
+

Contact Us

+

Let's plan your event together! +
Stop by for a coffee or Leave us a message!

+
+
+
+ +
Our Location: 2345 Party Ave, Charlotte NC
+
Phone number: (704) 567-7869
+ + +
+
+
+ + + + + + + + + +
+
+
+
+
+ +
+ + + + + + + + + diff --git a/src/main/webapp/WEB-INF/jsp/footer.jsp b/src/main/webapp/WEB-INF/jsp/footer.jsp new file mode 100644 index 000000000..18a042be5 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/footer.jsp @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/head.jsp b/src/main/webapp/WEB-INF/jsp/head.jsp new file mode 100644 index 000000000..a097f891c --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/head.jsp @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/jsp/header.jsp b/src/main/webapp/WEB-INF/jsp/header.jsp new file mode 100644 index 000000000..4dccd82b4 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/header.jsp @@ -0,0 +1,16 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> + + + +

Party Time! We Bring Life to Your Party!

+ diff --git a/src/main/webapp/WEB-INF/jsp/login.jsp b/src/main/webapp/WEB-INF/jsp/login.jsp new file mode 100644 index 000000000..18ed8263d --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/login.jsp @@ -0,0 +1,56 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> + + + + + + + + + Login + + + + + + + +
+ +
+ +
+
+
+ +
+
+
+ +
+ +
+ + + + + + diff --git a/src/main/webapp/WEB-INF/jsp/registration.jsp b/src/main/webapp/WEB-INF/jsp/registration.jsp new file mode 100644 index 000000000..c9cbc1423 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/registration.jsp @@ -0,0 +1,99 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> + + + + + + + + + Registration + + + + + + + +
+ +
+ + + +
+
+
+ +
+
+
+ +
+ +
+ + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/service.jsp b/src/main/webapp/WEB-INF/jsp/service.jsp new file mode 100644 index 000000000..e1fb6d34d --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/service.jsp @@ -0,0 +1,511 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> + + + + + + + + Service + + + + + + + +
+ +
+ +

List of Services

+View Cart +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ Party Supplies: + Balloons +

+ Description: + Choose by color and theme +

+ Quantity: + 50 +

+

+ Price: + $25.00 +

+ + +
+
+
+ Party Supplies: + Decoration +

+ Description: + Choose by color, age and theme +

+ Quantity: + 1 +

+

+ Price: + $100.00 +

+ + +
+
+
+ Party Supplies: + Games and Activities +

+ Description: + Choose by age and theme +

+ Quantity: + 1 +

+

+ Price: + $30 +

+ + +
+
+
+ Event Setting: + Pool Party +

+ Description: + location +

+ Quantity: + 1 +

+

+ Price: + $500.00 +

+ + +
+
+
+ Event Setting: + Garden Party +

+ Description: + location +

+ Quantity: + 1 +

+

+ Price: + $450.00 +

+ + +
+
+
+ Event Setting: + Block Party +

+ Description: + location +

+ Quantity: + 1 +

+

+ Price: + $550.00 +

+ + +
+
+
+ Event Setting: + Corporate Event +

+ Description: + location +

+ Quantity: + 1 +

+

+ Price: + $400.00 +

+ + +
+
+
+ Event Planning: + Fundraising +

+ Description: + planning +

+ Quantity: + 1 +

+

+ Price: + $500.00 +

+ + +
+
+
+ Event Planning: + Graduation +

+ Description: + planning +

+ Quantity: + 1 +

+

+ Price: + $700.00 +

+ + +
+
+
+ Event Planning: + Showers +

+ Description: + planning +

+ Quantity: + 1 +

+

+ Price: + $600.00 +

+ + +
+
+
+ Event Planning: + Destination Wedding +

+ Description: + planning +

+ Quantity: + 1 +

+

+ Price: + $1000.00 +

+ + +
+
+
+ Catering: + Tea Party +

+ Description: + serving +

+ Quantity: + 1 +

+

+ Price: + $300.00 +

+ + +
+
+
+ Catering: + Dinner Party +

+ Description: + serving +

+ Quantity: + 1 +

+

+ Price: + $425.00 +

+ + +
+
+
+ Catering: + Banquet +

+ Description: + serving +

+ Quantity: + 1 +

+

+ Price: + $1500.00 +

+ + +
+
+
+ Flowers & Gifts: + In a Vase +

+ Description: + design +

+ Quantity: + 1 +

+

+ Price: + $100.00 +

+ + +
+
+
+ Flowers & Gifts: + Plant +

+ Description: + design +

+ Quantity: + 1 +

+

+ Price: + $65.00 +

+ + +
+
+
+ Flowers & Gifts: + Lavish +

+ Description: + design +

+ Quantity: + 1 +

+

+ Price: + $50.00 +

+ + +
+
+
+ Flowers & Gifts: + Modern +

+ Description: + design +

+ Quantity: + 1 +

+

+ Price: + $100.00 +

+ + +
+
+
+ Flowers & Gifts: + Small Plush Toy +

+ Description: + personalized design +

+ Quantity: + 1 +

+

+ Price: + $55.00 +

+ + +
+
+
+ Flowers & Gifts: + Large Plush Toy +

+ Description: + personalized design +

+ Quantity: + 1 +

+

+ Price: + $100.00 +

+ + +
+
+
+ Flowers & Gifts: + Housewarming Gifts +

+ Description: + personalized design +

+ Quantity: + 1 +

+

+ Price: + $80.00 +

+ + +
+
+
+ Flowers & Gifts: + Photo Gifts +

+ Description: + personalized design +

+ Quantity: + 1 +

+

+ Price: + $85.00 +

+ + +
+
+
+ Flowers & Gifts: + Birthday Gifts +

+ Description: + personalized design +

+ Quantity: + 1 +

+

+ Price: + $100.00 +

+ + +
+
+
+ Flowers & Gifts: + Anniversary Gifts +

+ Description: + personalized design +

+ Quantity: + 1 +

+

+ Price: + $150.00 +

+ + +
+
+

+
+ +
+ + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/services.jsp b/src/main/webapp/WEB-INF/jsp/services.jsp new file mode 100644 index 000000000..bb6d544ac --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/services.jsp @@ -0,0 +1,139 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> + + + + + + Our Services + + + + + + +
+ +
+

Our Services

+

We can make your event happen!

+
+
+
+
+
+
+

Party Supplies

+
+ Select:  + + +
+
+
+

Event Setting

+
+ Select:  + + +
+
+
+

Event Planning

+
+ Select:  + + +
+
+
+

Catering

+
+ Select:  + + +
+
+
+

Flowers & Gifts

+
+ Select:  + + +
+
+
+ +
+ +
+ + + + + + + + + +<%--template for dropdown menu +
+

Dynamic Drop Down List

+
+Select:  + +
+ +
+
+--%> \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/shopping_cart.jsp b/src/main/webapp/WEB-INF/jsp/shopping_cart.jsp new file mode 100644 index 000000000..debcb372a --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/shopping_cart.jsp @@ -0,0 +1,78 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> + + + + + + Shopping Cart + + + + + + + +
+ +
+ +
+
+

If you have a question about your order call (704) 567-7869

+ + + +
+ +
+

Shopping Cart

+ + + + + + + + + +
+
+ + + + + + + + + + + + +
Service OptionsQuantityUnit PriceTotal
+
+ +
+ +
+
$$
Subtotal: $
+

View and Submit Your Order


+ +
+
+ +
+ +
+ + + + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/welcome.jsp b/src/main/webapp/WEB-INF/jsp/welcome.jsp new file mode 100644 index 000000000..30d563b5c --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/welcome.jsp @@ -0,0 +1,56 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> + + + + + + + + + Home Page: Welcome + + + + + + + +
+ +
+ +
+
+
+ + +
+ +
+ +

Welcome ${pageContext.request.userPrincipal.name} | Logout

+ +
+ +
+
+

About Us

+ +

The Party Time Company offers services to make your family event unforgettable! We offer party supplies and rentals, assistance in your family event planning. Just anything you may need to make your event the best it can be! Whether it is a wedding, a child’s birthday, or a corporate event, we are here to offer you our superior service.

+
+ + + +
+ +
+ + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..ab7ea5cc0 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,17 @@ + + PartyTimeApp + + dispatcher + org.springframework.web.servlet.DispatcherServlet + 1 + + + dispatcher + / + + \ No newline at end of file diff --git a/src/main/webapp/resources/css/contact_us.css b/src/main/webapp/resources/css/contact_us.css new file mode 100644 index 000000000..c23fa5cf7 --- /dev/null +++ b/src/main/webapp/resources/css/contact_us.css @@ -0,0 +1,97 @@ +html { + font-family: Cambria, serif; + color: midnightblue; + font-size: 20px; +} +header { + background-color: plum; +} +body { + background-color: plum; + background-position: center; + background-size: cover; + width: 980px; + margin-left: auto; + margin-right: 30px; + padding: 10px; + padding-top: 0px; +} +.topNavBar { + background-color: grey; + overflow: hidden; +} + +.topNavBar a { + float: left; + display: block; + color: midnightblue; + text-align: center; + padding: 14px 16px; + text-decoration: none; + font-size: 17px; +} + +.topNavBar a:hover { + background-color:whitesmoke; + color: blue; +} + +.topNavBar a.active { + background-color:darkslategray; + color: white; +} + +.topNavBar .icon { + display: none; +} + +* { + box-sizing: border-box; +} + +input[type=text], select, textarea { + width: 100%; + padding: 12px; + border: 1px solid gainsboro; + margin-top: 6px; + margin-bottom: 16px; + resize: vertical; +} + +input[type=submit] { + background-color: gray; + color: white; + padding: 12px 20px; + border: none; + cursor: pointer; +} + +input[type=submit]:hover { + background-color: gray; +} + +.container { + border-radius: 5px; + background-color: pink; + padding: 10px; +} + +.column { + float: left; + width: 50%; + margin-top: 6px; + padding: 20px; +} + +.row:after { + content: ""; + display: table; + clear: both; +} + +@media screen and (max-width: 600px) { + .column, input[type=submit] { + width: 100%; + margin-top: 0; + } +} \ No newline at end of file diff --git a/src/main/webapp/resources/css/service.css b/src/main/webapp/resources/css/service.css new file mode 100644 index 000000000..e53d4b644 --- /dev/null +++ b/src/main/webapp/resources/css/service.css @@ -0,0 +1,73 @@ +html { + font-family: Cambria, serif; + color: midnightblue; + font-size: 20px; +} +header { + background-color: plum; +} +body { + background-color: plum; + background-position: center; + background-size: cover; + width: 980px; + margin-left: auto; + margin-right: 30px; + padding: 0px 10px 10px; +} +.topNavBar { + background-color: grey; + overflow: hidden; +} + +.topNavBar a { + float: left; + display: block; + color: midnightblue; + text-align: center; + padding: 14px 16px; + text-decoration: none; + font-size: 17px; +} + +.topNavBar a:hover { + background-color:whitesmoke; + color: blue; +} + +.topNavBar a.active { + background-color:darkslategray; + color: white; +} + +.topNavBar .icon { + display: none; +} + +input[type=text], select, textarea { + width: 100%; + padding: 12px; + border: 1px solid gainsboro; + margin-top: 6px; + margin-bottom: 16px; + resize: vertical; +} + +input[type=submit] { + background-color: gray; + color: white; + padding: 12px 20px; + border: none; + cursor: pointer; +} + +input[type=submit]:hover { + background-color: gray; +} + +@media screen and (max-width: 600px) { + .column, input[type=submit] { + width: 100%; + margin-top: 0; + } +} \ No newline at end of file diff --git a/src/main/webapp/resources/css/services.css b/src/main/webapp/resources/css/services.css new file mode 100644 index 000000000..43871635e --- /dev/null +++ b/src/main/webapp/resources/css/services.css @@ -0,0 +1,157 @@ +html { + font-family: Cambria, serif; + color: midnightblue; + font-size: 20px; + width:100%; + height:100%; +} +header { + background-color: plum; +} +body { + background-color: plum; + background-position: center; + background-size: cover; + max-width:100%; + margin: 40px; + padding: 10px; + padding-top: 0px; +} +.topNavBar { + background-color: grey; + overflow: hidden; +} + +.topNavBar a { + float: left; + display: block; + color: midnightblue; + text-align: center; + padding: 14px 16px; + text-decoration: none; + font-size: 17px; + max-width:100%; +} + +.topNavBar a:hover { + background-color:whitesmoke; + color: blue; +} + +.topNavBar a.active { + background-color:darkslategray; + color: white; +} + +.topNavBar .icon { + display: none; +} + +.wrapper { + display: grid; + grid-gap: 10px; + grid-template-columns: repeat(4, [col] 170px ) ; + grid-template-rows: repeat(3, [row] auto ); + background-color: plum; + color: grey; +} +.wrapper img { + float: center; +} +.container > div { + display: inline; + max-width: 100%; + position:relative; +} +.container img { + max-width: 100%; + vertical-align: right; +} +.box { + color: white; + border-radius: 5px; + padding: 20px; + font-size: 120%; +} + +.box:hover { + animation: shake 1s; +} + +@keyframes shake { + 0%{transform: translate(1px,1px) rotate(0deg);} + 25%{transform: translate(-2px,0px)rotate(1deg) ;} + 50%{transform: translate(-1px,2px) rotate(-1deg);} + 75%{transform: translate(-1px,-1px) rotate(0deg);} + 100%{transform: translate(1px,-2px) rotate(-1deg);} +} + +.a { + grid-column: col / span 2; + grid-row: row ; + background-color: grey; +} +.b { + grid-column: col 3 / span 2 ; + grid-row: row ; + background-color: purple; +} +.c { + grid-column: col ; + grid-row: row 2 ; + background-color: teal; +} +.d { + grid-column: col 2 / span 3 ; + grid-row: row 2 ; + background-color: tomato; +} + +.e { + grid-column: col / span 4; + grid-row: row 3; + background-color: turquoise; +} +/* Dropdown Button */ +.dropbtn { + background-color: grey; + color: white; + padding: 5px; + font-size: 16px; + border: 1px; + cursor: pointer; +} + +/* Dropdown button on hover & focus */ +.dropbtn:hover, .dropbtn:focus { + background-color: grey; +} + +/* The container
- needed to position the dropdown content */ +.dropdown { + position: relative; + display: inline-block; +} + +/* Dropdown Content (Hidden by Default) */ +.dropdown-content { + display: none; + position: absolute; + background-color: grey; + min-width: 130px; + z-index: 1; +} + +/* Links inside the dropdown */ +.dropdown-content a { + color: black; + padding: 5px 5px; + text-decoration: none; + display: block; +} + +/* Change color of dropdown links on hover */ +.dropdown-content a:hover {background-color: grey} + +/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */ +.show {display:block;} \ No newline at end of file diff --git a/src/main/webapp/resources/css/shopping_cart.css b/src/main/webapp/resources/css/shopping_cart.css new file mode 100644 index 000000000..eeba766bf --- /dev/null +++ b/src/main/webapp/resources/css/shopping_cart.css @@ -0,0 +1,96 @@ +html { + font-family: Cambria, serif; + color: midnightblue; + font-size: 20px; +} +header { + background-color: plum; +} +body { + background-color: plum; + background-position: center; + background-size: cover; + width: 980px; + margin-left: auto; + margin-right: 30px; + padding: 0px 10px 10px; +} +.topNavBar { + background-color: grey; + overflow: hidden; +} + +.topNavBar a { + float: left; + display: block; + color: midnightblue; + text-align: center; + padding: 14px 16px; + text-decoration: none; + font-size: 17px; +} + +.topNavBar a:hover { + background-color:whitesmoke; + color: blue; +} + +.topNavBar a.active { + background-color:darkslategray; + color: white; +} + +.topNavBar .icon { + display: none; +} + +* { + box-sizing: border-box; +} + +input[type=text], select, textarea { + width: 100%; + padding: 12px; + border: 1px solid gainsboro; + margin-top: 6px; + margin-bottom: 16px; + resize: vertical; +} + +input[type=submit] { + background-color: plum; + color: midnightblue; + padding: 12px 20px; + border: 1px solid gainsboro; + cursor: pointer; +} + +input[type=submit]:hover { + background-color: gray; +} + +.container { + border-radius: 5px; + background-color: plum; + padding: 10px; +} + +.column { + float: left; + width: 50%; + margin-top: 6px; + padding: 20px; +} + +.row:after { + content: ""; + display: table; + clear: both; +} + +@media screen and (max-width: 600px) { + .column, input[type=submit] { + width: 100%; + margin-top: 0; + } +} \ No newline at end of file diff --git a/src/main/webapp/resources/css/style.css b/src/main/webapp/resources/css/style.css new file mode 100644 index 000000000..fd4b16dfd --- /dev/null +++ b/src/main/webapp/resources/css/style.css @@ -0,0 +1,94 @@ +html { + font-family: Cambria, serif; + color: midnightblue; + font-size: 15px; + background: #dda0dd; +} +body { + font-family: 'Montserrat', "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 25px; + color: midnightblue; + padding-top: 50px; + padding-bottom: 50px; + background-size: cover; + background: #dda0dd center; +} + +header { + background: #dda0dd; +} + +/* +.container { + background: plum; +} + */ + + +img { + float: right; +} +.topNavBar { + background-color: grey; + overflow: hidden; +} + +.topNavBar a { + float: left; + display: block; + color: midnightblue; + text-align: center; + padding: 14px 16px; + text-decoration: none; + font-size: 17px; +} + +.topNavBar a:hover { + background-color:whitesmoke; + color: blue; +} + +.topNavBar a.active { + background-color:darkslategray; + color: white; +} + +.topNavBar .icon { + display: none; +} + +.form-heading { + text-align: center; + text-transform: uppercase; +} +.form-signin { + max-width: 360px; + padding: 15px; + margin: 0 auto; +} +.form-signin .form-control { + position: relative; + height: auto; + padding: 10px; + font-size: 15px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.form-signin .form-control:focus { + z-index: 3; +} +.form-signin input, .form-signin button { + margin-top: 10px; +} +.form-signin .form-signin-heading, .form-signin .checkbox { + margin-bottom: 10px; +} +.form-signin .checkbox { + font-weight: normal; +} +.has-error { + color: midnightblue; + line-height: 1; + font-size: 14px; +} \ No newline at end of file diff --git a/src/main/webapp/resources/css/welcome.css b/src/main/webapp/resources/css/welcome.css new file mode 100644 index 000000000..50f6ea26e --- /dev/null +++ b/src/main/webapp/resources/css/welcome.css @@ -0,0 +1,52 @@ +html { + font-family: 'Montserrat', "Helvetica Neue", Helvetica, Arial, sans-serif; + color: midnightblue; + font-size: 15px; + padding: 0px; + +} +body { + font-family: 'Montserrat', "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 25px; + color: midnightblue; + padding: 0px; + background-size: cover; + background: center; +} + +* { + background: plum; +} + + +img { + float: right; +} +.topNavBar { + background-color: grey; + overflow: hidden; +} + +.topNavBar a { + float: left; + display: block; + color: midnightblue; + text-align: center; + padding: 14px 16px; + text-decoration: none; + font-size: 17px; +} + +.topNavBar a:hover { + background-color:whitesmoke; + color: blue; +} + +.topNavBar a.active { + background-color:darkslategray; + color: white; +} + +.topNavBar .icon { + display: none; +} diff --git a/src/main/webapp/resources/img/birthday.jpg b/src/main/webapp/resources/img/birthday.jpg new file mode 100644 index 000000000..df0ad2bb6 Binary files /dev/null and b/src/main/webapp/resources/img/birthday.jpg differ diff --git a/src/main/webapp/resources/img/catering.jpg b/src/main/webapp/resources/img/catering.jpg new file mode 100644 index 000000000..7df646b70 Binary files /dev/null and b/src/main/webapp/resources/img/catering.jpg differ diff --git a/src/main/webapp/resources/img/coffee_plan.jpg b/src/main/webapp/resources/img/coffee_plan.jpg new file mode 100644 index 000000000..a1f52976f Binary files /dev/null and b/src/main/webapp/resources/img/coffee_plan.jpg differ diff --git a/src/main/webapp/resources/img/flowers.jpg b/src/main/webapp/resources/img/flowers.jpg new file mode 100644 index 000000000..e4c197fa3 Binary files /dev/null and b/src/main/webapp/resources/img/flowers.jpg differ diff --git a/src/main/webapp/resources/img/gifts.jpeg b/src/main/webapp/resources/img/gifts.jpeg new file mode 100644 index 000000000..4df34f434 Binary files /dev/null and b/src/main/webapp/resources/img/gifts.jpeg differ diff --git a/src/main/webapp/resources/img/location.jpg b/src/main/webapp/resources/img/location.jpg new file mode 100644 index 000000000..5036a1045 Binary files /dev/null and b/src/main/webapp/resources/img/location.jpg differ diff --git a/src/main/webapp/resources/img/myparty.jpeg b/src/main/webapp/resources/img/myparty.jpeg new file mode 100644 index 000000000..741a80a91 Binary files /dev/null and b/src/main/webapp/resources/img/myparty.jpeg differ diff --git a/src/main/webapp/resources/img/party-organiser.jpeg b/src/main/webapp/resources/img/party-organiser.jpeg new file mode 100644 index 000000000..dce713850 Binary files /dev/null and b/src/main/webapp/resources/img/party-organiser.jpeg differ diff --git a/src/main/webapp/resources/js/contact_us.js b/src/main/webapp/resources/js/contact_us.js new file mode 100644 index 000000000..d64b35d05 --- /dev/null +++ b/src/main/webapp/resources/js/contact_us.js @@ -0,0 +1,8 @@ +function myFunction() { + let i = document.getElementById("myTopnav"); + if (i.className === "topNavBar") { + i.className += " responsive"; + } else { + i.className = "topNavBar"; + } +} \ No newline at end of file diff --git a/src/main/webapp/resources/js/services.js b/src/main/webapp/resources/js/services.js new file mode 100644 index 000000000..08d341172 --- /dev/null +++ b/src/main/webapp/resources/js/services.js @@ -0,0 +1,28 @@ +function myFunction() { + let i = document.getElementById("myTopnav"); + if (i.className === "topNavBar") { + i.className += " responsive"; + } else { + i.className = "topNavBar"; + } +} + +function renderGrid() { + let blocks = document.getElementById("wrapper").children; + let cols = 4, newleft, newtop; + for(let i = 1; i < blocks.length; i++){ + if (i % cols == 0) { + newtop = (blocks[i-cols].offsetTop + blocks[i-cols].offsetHeight); + blocks[i].style.top = newtop+"px"; + } else { + if(blocks[i-cols]){ + newleft = (blocks[i-cols].offsetTop + blocks[i-cols].offsetHeight); + blocks[i].style.top = newleft+"px"; + } + newleft = (blocks[i-1].offsetLeft + blocks[i-1].offsetWidth); + blocks[i].style.left = newleft+"px"; + } + } +} +window.addEventListener("load", renderGrid, false); +window.addEventListener("resize", renderGrid, false); \ No newline at end of file diff --git a/src/main/webapp/resources/js/utils.js b/src/main/webapp/resources/js/utils.js new file mode 100644 index 000000000..629b00892 --- /dev/null +++ b/src/main/webapp/resources/js/utils.js @@ -0,0 +1,26 @@ +// Utility JS functions are to be defined here +function resizeIFrameToFitContent( iFrame ) { + iFrame.width = iFrame.contentWindow.document.body.scrollWidth; + iFrame.height = iFrame.contentWindow.document.body.scrollHeight; +} + +// used to fetch all methods of an arbitrary object to display to client +function getAllMethodsOfObject(obj) { + var result = []; + for (var id in obj) { + try { + if (typeof(obj[id]) == "function") { + result.push(id + ": " + obj[id].toString()); + } + } catch (err) { + result.push(id + ": inaccessible"); + } + } + return result; +} + + + +function loadHtml(elementId, fileName) { + $(elementId).html(''); +}; \ No newline at end of file diff --git a/src/main/webapp/resources/wireframing/wireframing_Registration.PNG b/src/main/webapp/resources/wireframing/wireframing_Registration.PNG new file mode 100644 index 000000000..e0421d5ee Binary files /dev/null and b/src/main/webapp/resources/wireframing/wireframing_Registration.PNG differ diff --git a/src/main/webapp/resources/wireframing/wireframing_contact_us.PNG b/src/main/webapp/resources/wireframing/wireframing_contact_us.PNG new file mode 100644 index 000000000..57e46bf76 Binary files /dev/null and b/src/main/webapp/resources/wireframing/wireframing_contact_us.PNG differ diff --git a/src/main/webapp/resources/wireframing/wireframing_login_page.PNG b/src/main/webapp/resources/wireframing/wireframing_login_page.PNG new file mode 100644 index 000000000..0ba4fa803 Binary files /dev/null and b/src/main/webapp/resources/wireframing/wireframing_login_page.PNG differ diff --git a/src/main/webapp/resources/wireframing/wireframing_our_services_1.PNG b/src/main/webapp/resources/wireframing/wireframing_our_services_1.PNG new file mode 100644 index 000000000..22ee258b9 Binary files /dev/null and b/src/main/webapp/resources/wireframing/wireframing_our_services_1.PNG differ diff --git a/src/main/webapp/resources/wireframing/wireframing_service_1.PNG b/src/main/webapp/resources/wireframing/wireframing_service_1.PNG new file mode 100644 index 000000000..630a137ac Binary files /dev/null and b/src/main/webapp/resources/wireframing/wireframing_service_1.PNG differ diff --git a/src/main/webapp/resources/wireframing/wireframing_service_p2.PNG b/src/main/webapp/resources/wireframing/wireframing_service_p2.PNG new file mode 100644 index 000000000..0d1b64691 Binary files /dev/null and b/src/main/webapp/resources/wireframing/wireframing_service_p2.PNG differ diff --git a/src/main/webapp/resources/wireframing/wireframing_shopping_cart.PNG b/src/main/webapp/resources/wireframing/wireframing_shopping_cart.PNG new file mode 100644 index 000000000..01e02b934 Binary files /dev/null and b/src/main/webapp/resources/wireframing/wireframing_shopping_cart.PNG differ diff --git a/src/main/webapp/resources/wireframing/wireframing_shopping_cart_1.PNG b/src/main/webapp/resources/wireframing/wireframing_shopping_cart_1.PNG new file mode 100644 index 000000000..521b20805 Binary files /dev/null and b/src/main/webapp/resources/wireframing/wireframing_shopping_cart_1.PNG differ diff --git a/src/main/webapp/resources/wireframing/wireframing_welcome_page.PNG b/src/main/webapp/resources/wireframing/wireframing_welcome_page.PNG new file mode 100644 index 000000000..f381b5858 Binary files /dev/null and b/src/main/webapp/resources/wireframing/wireframing_welcome_page.PNG differ diff --git a/src/test/java/com/github/perscholas/MyObjectTest.java b/src/test/java/com/github/perscholas/MyObjectTest.java new file mode 100644 index 000000000..a2e65787e --- /dev/null +++ b/src/test/java/com/github/perscholas/MyObjectTest.java @@ -0,0 +1,21 @@ +package com.github.perscholas; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Created by leon on 9/3/2020. + */ +public class MyObjectTest { + @Test + public void test() { + // given + Runnable r = System.out::println; + + // when + r.run(); + + // then + Assert.assertNotNull(r); + } +} diff --git a/start_my_project.gif b/start_my_project.gif new file mode 100644 index 000000000..0ce43c3a3 Binary files /dev/null and b/start_my_project.gif differ