diff --git a/Gemfile b/Gemfile
index 6712bea..7b00de9 100644
--- a/Gemfile
+++ b/Gemfile
@@ -43,7 +43,8 @@ gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ]
gem "bootsnap", require: false
# Use Sass to process CSS
-# gem "sassc-rails"
+gem "sassc-rails"
+gem "bootstrap"
# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
# gem "image_processing", "~> 1.2"
diff --git a/Gemfile.lock b/Gemfile.lock
index 92417ee..cbec558 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -68,9 +68,15 @@ GEM
tzinfo (~> 2.0)
addressable (2.8.5)
public_suffix (>= 2.0.2, < 6.0)
+ autoprefixer-rails (10.4.15.0)
+ execjs (~> 2)
bindex (0.8.1)
bootsnap (1.16.0)
msgpack (~> 1.2)
+ bootstrap (5.3.1)
+ autoprefixer-rails (>= 9.1.0)
+ popper_js (>= 2.11.8, < 3)
+ sassc-rails (>= 2.0.0)
builder (3.2.4)
capybara (3.39.2)
addressable
@@ -88,6 +94,8 @@ GEM
irb (>= 1.3.6)
reline (>= 0.2.7)
erubi (1.12.0)
+ execjs (2.9.1)
+ ffi (1.16.2)
globalid (1.2.1)
activesupport (>= 6.1)
i18n (1.14.1)
@@ -127,6 +135,7 @@ GEM
nio4r (2.5.9)
nokogiri (1.15.4-x86_64-linux)
racc (~> 1.4)
+ popper_js (2.11.8)
public_suffix (5.0.3)
puma (5.6.7)
nio4r (~> 2.0)
@@ -168,6 +177,14 @@ GEM
io-console (~> 0.5)
rexml (3.2.6)
rubyzip (2.3.2)
+ sassc (2.4.0)
+ ffi (~> 1.9)
+ sassc-rails (2.1.2)
+ railties (>= 4.0.0)
+ sassc (>= 2.0)
+ sprockets (> 3.0)
+ sprockets-rails
+ tilt
selenium-webdriver (4.12.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
@@ -183,6 +200,7 @@ GEM
stimulus-rails (1.2.2)
railties (>= 6.0.0)
thor (1.2.2)
+ tilt (2.3.0)
timeout (0.4.0)
turbo-rails (1.4.0)
actionpack (>= 6.0.0)
@@ -208,12 +226,14 @@ PLATFORMS
DEPENDENCIES
bootsnap
+ bootstrap
capybara
debug
importmap-rails
jbuilder
puma (~> 5.0)
rails (~> 7.0.8)
+ sassc-rails
selenium-webdriver
sprockets-rails
sqlite3 (~> 1.4)
diff --git a/app/assets/images/avengers-end-game.png b/app/assets/images/avengers-end-game.png
new file mode 100644
index 0000000..f3031eb
Binary files /dev/null and b/app/assets/images/avengers-end-game.png differ
diff --git a/app/assets/images/avengers-infinity-war.png b/app/assets/images/avengers-infinity-war.png
new file mode 100644
index 0000000..a53f319
Binary files /dev/null and b/app/assets/images/avengers-infinity-war.png differ
diff --git a/app/assets/images/batman.png b/app/assets/images/batman.png
new file mode 100644
index 0000000..76f13fe
Binary files /dev/null and b/app/assets/images/batman.png differ
diff --git a/app/assets/images/black-panther.png b/app/assets/images/black-panther.png
new file mode 100644
index 0000000..90eee05
Binary files /dev/null and b/app/assets/images/black-panther.png differ
diff --git a/app/assets/images/captain-marvel.png b/app/assets/images/captain-marvel.png
new file mode 100644
index 0000000..3bddefa
Binary files /dev/null and b/app/assets/images/captain-marvel.png differ
diff --git a/app/assets/images/catwoman.png b/app/assets/images/catwoman.png
new file mode 100644
index 0000000..6e0ba73
Binary files /dev/null and b/app/assets/images/catwoman.png differ
diff --git a/app/assets/images/fantastic-four.png b/app/assets/images/fantastic-four.png
new file mode 100644
index 0000000..e99d213
Binary files /dev/null and b/app/assets/images/fantastic-four.png differ
diff --git a/app/assets/images/green-lantern.png b/app/assets/images/green-lantern.png
new file mode 100644
index 0000000..9e83dbc
Binary files /dev/null and b/app/assets/images/green-lantern.png differ
diff --git a/app/assets/images/hulk.png b/app/assets/images/hulk.png
new file mode 100644
index 0000000..e6afb2d
Binary files /dev/null and b/app/assets/images/hulk.png differ
diff --git a/app/assets/images/ironman.png b/app/assets/images/ironman.png
new file mode 100644
index 0000000..2fb1e29
Binary files /dev/null and b/app/assets/images/ironman.png differ
diff --git a/app/assets/images/logo.png b/app/assets/images/logo.png
new file mode 100644
index 0000000..6830ba3
Binary files /dev/null and b/app/assets/images/logo.png differ
diff --git a/app/assets/images/placeholder.png b/app/assets/images/placeholder.png
new file mode 100644
index 0000000..085874b
Binary files /dev/null and b/app/assets/images/placeholder.png differ
diff --git a/app/assets/images/spiderman.png b/app/assets/images/spiderman.png
new file mode 100644
index 0000000..caba8a9
Binary files /dev/null and b/app/assets/images/spiderman.png differ
diff --git a/app/assets/images/superman.png b/app/assets/images/superman.png
new file mode 100644
index 0000000..43eb9ca
Binary files /dev/null and b/app/assets/images/superman.png differ
diff --git a/app/assets/images/wonder-woman.png b/app/assets/images/wonder-woman.png
new file mode 100644
index 0000000..f63b63e
Binary files /dev/null and b/app/assets/images/wonder-woman.png differ
diff --git a/app/assets/stylesheets/custom.scss b/app/assets/stylesheets/custom.scss
new file mode 100644
index 0000000..9c144b3
--- /dev/null
+++ b/app/assets/stylesheets/custom.scss
@@ -0,0 +1,586 @@
+// Colors
+
+$black: #393939;
+$off-white: #ededed;
+$dark-gray: #666;
+$medium-gray: #6c757d;
+$light-gray: #c2c2c2;
+$blue: #237cbe;
+$light-blue: lighten($blue, 40%);
+$orange: #e8890c;
+$yellow: #ffc107;
+$light-yellow: #ffc;
+$red: #dc3545;
+
+// Custom Variables
+
+$secondary-text-color: $medium-gray;
+$accent-color: $orange;
+$secondary-link-color: $light-blue;
+$border-color: $light-gray;
+$error-color: $red;
+$error-background-color: $light-yellow;
+$sold-out-color: $yellow;
+$box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.09);
+
+// Bootstrap Variable Overrides
+
+$body-color: $black;
+$body-bg: $off-white;
+$primary: $blue;
+$secondary: $dark-gray;
+$min-contrast-ratio: 4;
+$input-bg: white;
+
+// Import Bootstrap Styles
+
+@import "bootstrap";
+
+// Custom CSS
+
+.content {
+ @extend .container;
+}
+
+a {
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+// Header and Nav
+
+header {
+ background-color: $primary;
+ padding: 0.5rem;
+ margin-bottom: 3rem;
+
+ nav {
+ @extend .navbar, .navbar-expand-md;
+
+ img {
+ height: 50px;
+ margin-right: 0.5rem;
+ }
+
+ a {
+ color: $secondary-link-color;
+ }
+
+ a.button {
+ @extend .btn, .btn-outline-secondary;
+ }
+
+ ul {
+ @extend .nav, .navbar-nav;
+ letter-spacing: 1px;
+
+ &.left {
+ @extend .me-auto;
+ }
+
+ &.right {
+ @extend .ms-auto;
+ }
+
+ li {
+ @extend .nav-item;
+ font-size: 1.1rem;
+ margin-right: 5px;
+
+ a {
+ @extend .nav-link;
+ color: $secondary-link-color;
+ padding-bottom: 1px;
+ }
+
+ a:hover:not(.button),
+ a.active {
+ color: $off-white;
+ text-decoration: none;
+ border-bottom: 1px solid $off-white;
+ }
+
+ .button,
+ button {
+ margin-right: 10px;
+ color: $off-white;
+ border-color: $off-white;
+ }
+
+ .button:hover,
+ button:hover {
+ background: $off-white;
+ color: $primary;
+ border-color: $primary;
+ }
+
+ button {
+ @extend .btn, .btn-outline-secondary;
+ }
+ }
+ }
+ }
+}
+
+// Movies Index Page
+
+section.movie {
+ @extend .row;
+ margin-bottom: 1.5rem;
+ padding-bottom: 1em;
+ border-bottom: 1px dotted $border-color;
+
+ &:nth-last-child(1) {
+ border-bottom: none;
+ }
+
+ .image {
+ @extend .col-md-3, .text-center;
+ img {
+ width: 100px;
+ box-shadow: $box-shadow;
+ }
+ }
+
+ .summary {
+ @extend .col-md-9, .text-start;
+ }
+
+ h2 {
+ font-size: 1.5rem;
+ margin-bottom: 0.25rem;
+ }
+
+ h3 {
+ font-size: 1.1rem;
+ color: $secondary-text-color;
+ font-weight: 400;
+ }
+
+ p {
+ margin-top: 1.1rem;
+ }
+
+ span.stars {
+ float: right;
+ margin-top: -3.75rem;
+ }
+}
+
+// Movie Show Page
+
+section.movie-details {
+ @extend .row;
+
+ .image {
+ @extend .col-md-3, .text-start;
+
+ input[type="submit"] {
+ margin-top: 1rem;
+ }
+ }
+
+ .details {
+ @extend .col-md-7, .text-start;
+ }
+
+ aside {
+ @extend .col-md-2;
+ }
+
+ h1 {
+ font-size: 2rem;
+ }
+
+ h2 {
+ font-size: 1.35rem;
+ color: $secondary-text-color;
+ }
+
+ h3 {
+ margin-top: 1.5rem;
+ font-size: 1.25rem;
+ color: $secondary-text-color;
+ font-weight: 300;
+ }
+
+ table {
+ td {
+ padding-top: 0.35rem;
+ padding-bottom: 0.35rem;
+ }
+ th {
+ padding-right: 1rem;
+ }
+ }
+
+ .faves {
+ @extend .input-group;
+ margin-top: 1rem;
+
+ .count {
+ @extend .input-group-text;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+
+ button[type="submit"] {
+ @extend .btn, .btn-outline-secondary;
+ border-color: #cdd3d8;
+ border-right: none;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ margin-top: 0;
+ }
+ }
+
+ p {
+ margin-top: 1rem;
+ font-size: 1.15em;
+ }
+
+ img {
+ margin-top: 0.5rem;
+ width: 150px;
+ box-shadow: $box-shadow;
+ }
+
+ a.review {
+ @extend .btn, .btn-success;
+ letter-spacing: 1px;
+ text-transform: uppercase;
+ margin-top: 1rem;
+ }
+
+ .reviews {
+ .star-rating {
+ margin-bottom: 0.5rem;
+ }
+ }
+}
+
+// Users Index Page
+
+ul.users {
+ font-size: 1.25em;
+ list-style: none;
+ padding: 0;
+
+ li {
+ margin: 1em 0;
+ }
+}
+
+// User Show Page
+
+section.user {
+ h2 {
+ font-size: 1.35rem;
+ color: $secondary-text-color;
+ }
+
+ h3 {
+ margin-top: 3rem;
+ font-size: 1.5rem;
+ margin-bottom: 2rem;
+ }
+
+ .actions {
+ margin-top: 1rem;
+
+ .button {
+ @extend .btn, .btn-sm;
+
+ &.edit {
+ @extend .btn-outline-secondary;
+ }
+
+ &.delete {
+ @extend .btn-danger;
+ }
+ }
+ }
+
+ .review {
+ @extend .row;
+ margin: 1rem 0;
+ border-radius: 0.3rem;
+ border: 1px solid $border-color;
+ padding: 1rem;
+
+ .details {
+ @extend .col-md-12, .text-start;
+
+ .title {
+ font-size: 1.15rem;
+ font-weight: 600;
+ }
+
+ .star-rating {
+ margin-bottom: 0.3rem;
+ }
+ .date {
+ font-size: 1rem;
+ font-weight: 400;
+ color: $secondary-text-color;
+ }
+
+ p {
+ margin-top: 1rem;
+ }
+ }
+ }
+
+ .favorite-movies {
+ display: flex;
+ flex-wrap: wrap;
+ margin-top: -1rem;
+
+ img {
+ margin: 1rem;
+ width: 150px;
+ box-shadow: $box-shadow;
+ }
+ }
+}
+
+// Reviews Index Page
+
+ul.reviews {
+ font-size: 1.25em;
+ list-style: none;
+ padding: 0;
+
+ li {
+ margin: 1em 0 2.5rem 0;
+
+ span {
+ &.date {
+ font-size: 0.8em;
+ font-weight: 400;
+ margin-left: 0.3rem;
+ color: $secondary-text-color;
+ }
+ }
+
+ .button {
+ @extend .btn, .btn-sm, .btn-outline-danger;
+ margin-left: 0.5rem;
+ }
+ }
+}
+
+// Footer
+
+footer {
+ background: $black;
+ color: $light-gray;
+ text-align: center;
+ margin-top: 3rem;
+ padding-top: 2rem;
+ padding-bottom: 2rem;
+}
+
+// Admin Section
+
+section.admin {
+ text-align: center;
+ margin: 3rem 0;
+ padding-top: 2rem;
+ border-top: 1px dashed $border-color;
+
+ &.no-rule {
+ border-top: none;
+ padding-top: 0;
+ }
+
+ a.button, button {
+ @extend .btn, .btn-secondary;
+ letter-spacing: 1px;
+ text-transform: uppercase;
+ }
+}
+
+section.movie + section.admin {
+ border-top: none;
+ padding-top: 0;
+}
+
+// Aside
+
+aside {
+ h4 {
+ color: $secondary-text-color;
+ font-size: 1rem;
+ margin-top: 1rem;
+ padding-bottom: 0.3rem;
+ text-transform: uppercase;
+ border-bottom: 1px solid $border-color;
+ }
+
+ ul {
+ list-style: none;
+ padding-left: 0.25rem;
+
+ li {
+ padding-bottom: 0.5rem;
+ }
+ }
+}
+
+// Forms
+
+form.button_to {
+ display: inline;
+}
+
+form:not([class="button_to"]) {
+ max-width: 503px;
+ margin-top: 1.5rem;
+
+ label {
+ @extend .form-label;
+ font-size: 1.1rem;
+ font-weight: 600;
+ display: block;
+ }
+
+ input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="submit"]),
+ textarea,
+ select:not(.date) {
+ @extend .form-control;
+ margin-bottom: 0.75rem;
+ width: 100%;
+ height: 100%;
+ }
+
+ select.date {
+ @extend .form-select;
+ width: auto;
+ display: inline-block;
+ margin-bottom: 0.75rem;
+ }
+
+ input[type="submit"] {
+ @extend .btn, .btn-primary;
+ display: block;
+ width: 100%;
+ margin-top: 1.5rem;
+ }
+
+ input[type="checkbox"] {
+ @extend .form-check-input;
+ width: 20px;
+ height: 20px;
+ }
+
+ input[type="checkbox"] + label {
+ @extend .form-check-label;
+ padding-left: 0.5rem;
+ margin-bottom: 0.5rem;
+ }
+
+ input[type="radio"] {
+ @extend .form-check-input;
+ width: 20px;
+ height: 20px;
+ }
+
+ input[type="radio"] + label {
+ @extend .form-check-label;
+ margin-bottom: 0.6rem;
+ font-weight: 400;
+ }
+
+ input[type="file"] {
+ margin-bottom: 0.75rem;
+ width: 100%;
+ }
+
+ .star {
+ @extend .form-check, .form-check-inline;
+ }
+
+ .checkboxes {
+ @extend .form-check;
+ margin-top: 1.5rem;
+ }
+
+ div.field_with_errors {
+ display: inline;
+ label {
+ color: $error-color;
+ }
+ input,
+ textarea,
+ select {
+ background: $error-background-color !important;
+ }
+ }
+}
+
+// Flashes
+
+.flash {
+ @extend .alert;
+ text-align: center;
+ margin-top: -1rem;
+ margin-bottom: 2rem;
+
+ &.notice {
+ @extend .alert-success;
+ }
+
+ &.alert {
+ @extend .alert-danger;
+ }
+}
+
+// Errors
+
+section.errors {
+ margin: 1rem 0;
+ padding: 1.5rem;
+ border-radius: 0.3rem;
+ background: $error-background-color;
+
+ h2 {
+ color: $error-color;
+ font-size: 1.25rem;
+ }
+
+ h3 {
+ font-size: 1rem;
+ margin-top: 1rem;
+ font-weight: 600;
+ }
+}
+
+// Star Rating
+//
+// Credit: https://codepen.io/filcp/pen/QvZVOg
+
+.star-rating {
+ display: flex;
+ align-items: center;
+ font-size: 25px;
+ height: 25px;
+ justify-content: left;
+
+ .back-stars {
+ display: flex;
+ color: $light-gray;
+ position: relative;
+ // text-shadow: 0px 1px 0 #a2a2a2;
+ }
+ .front-stars {
+ display: flex;
+ color: $accent-color;
+ overflow: hidden;
+ position: absolute;
+ top: 0;
+ }
+}
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 9ac861f..cbe11db 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -15,6 +15,7 @@
diff --git a/app/views/movies/index.html.erb b/app/views/movies/index.html.erb
index 9e7f19c..d9113a2 100644
--- a/app/views/movies/index.html.erb
+++ b/app/views/movies/index.html.erb
@@ -2,9 +2,19 @@
<% @movies.each do |movie| %>
- - <%= movie.title %> (<%= movie.rating %>, <%= year_of(movie) %>): <%= total_gross(movie) %>
-
<%= truncate(movie.description, length: 40, separator: "") %>
-
+
+
+
+ <%= movie.title %>
+
+
+ <%= total_gross(movie) %>
+
+
+ <%= truncate(movie.description, length: 150, separator: ' ') %>
+
+
+
<% end %>
diff --git a/db/seeds.rb b/db/seeds.rb
index bc25fce..44d6538 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -1,7 +1,140 @@
# This file should contain all the record creation needed to seed the database with its default values.
-# The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup).
+# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
#
# Examples:
#
-# movies = Movie.create([{ name: "Star Wars" }, { name: "Lord of the Rings" }])
-# Character.create(name: "Luke", movie: movies.first)
+# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
+# Character.create(name: 'Luke', movie: movies.first)
+
+Movie.create!([
+ {
+ title: 'Avengers: Endgame',
+ description:
+ %{
+ After the devastating events of Avengers: Infinity War, the universe
+ is in ruins. With the help of remaining allies, the Avengers assemble
+ once more in order to undo Thanos' actions and restore order to the universe.
+ }.squish,
+ released_on: "2019-04-26",
+ rating: 'PG-13',
+ total_gross: 1_223_641_414
+ },
+ {
+ title: 'Captain Marvel',
+ description:
+ %{
+ Carol Danvers becomes one of the universe's most powerful heroes when Earth is caught in the middle of a galactic war between two alien races.
+ }.squish,
+ released_on: "2019-03-08",
+ rating: 'PG-13',
+ total_gross: 1_110_662_849
+ },
+ {
+ title: 'Black Panther',
+ description:
+ %{
+ T'Challa, heir to the hidden but advanced kingdom of Wakanda, must step forward to lead his people into a new future and must confront a challenger from his country's past.
+ }.squish,
+ released_on: "2018-02-16",
+ rating: 'PG-13',
+ total_gross: 1_346_913_161
+ },
+ {
+ title: 'Avengers: Infinity War',
+ description:
+ %{
+ The Avengers and their allies must be willing to sacrifice all in an attempt to defeat the powerful Thanos before his blitz of devastation and ruin puts an end to the universe.
+ }.squish,
+ released_on: "2018-04-27",
+ rating: 'PG-13',
+ total_gross: 2_048_359_754
+ },
+ {
+ title: 'Green Lantern',
+ description:
+ %{
+ Reckless test pilot Hal Jordan is granted an alien ring that bestows him with otherworldly powers that inducts him into an intergalactic police force, the Green Lantern Corps.
+ }.squish,
+ released_on: "2011-06-17",
+ rating: 'PG-13',
+ total_gross: 219_851_172
+ },
+ {
+ title: 'Fantastic Four',
+ description:
+ %{
+ Four young outsiders teleport to an alternate and dangerous universe which alters their physical form in shocking ways. The four must learn to harness their new abilities and work together to save Earth from a former friend turned enemy.
+ }.squish,
+ released_on: "2015-08-07",
+ rating: 'PG-13',
+ total_gross: 168_257_860
+ },
+ {
+ title: 'Iron Man',
+ description:
+ %{
+ When wealthy industrialist Tony Stark is forced to build an
+ armored suit after a life-threatening incident, he ultimately
+ decides to use its technology to fight against evil.
+ }.squish,
+ released_on: "2008-05-02",
+ rating: 'PG-13',
+ total_gross: 585_366_247
+ },
+ {
+ title: 'Superman',
+ description:
+ %{
+ An alien orphan is sent from his dying planet to Earth, where
+ he grows up to become his adoptive home's first and greatest
+ super-hero.
+ }.squish,
+ released_on: "1978-12-15",
+ rating: 'PG',
+ total_gross: 300_451_603
+ },
+ {
+ title: 'Spider-Man',
+ description:
+ %{
+ When bitten by a genetically modified spider, a nerdy, shy, and
+ awkward high school student gains spider-like abilities that he
+ eventually must use to fight evil as a superhero after tragedy
+ befalls his family.
+ }.squish,
+ released_on: "2002-05-03",
+ rating: 'PG-13',
+ total_gross: 825_025_036
+ },
+ {
+ title: 'Batman',
+ description:
+ %{
+ The Dark Knight of Gotham City begins his war on crime with his
+ first major enemy being the clownishly homicidal Joker.
+ }.squish,
+ released_on: "1989-06-23",
+ rating: 'PG-13',
+ total_gross: 411_348_924
+ },
+ {
+ title: "Catwoman",
+ description:
+ %{
+ Patience Philips seems destined to spend her life apologizing for taking up space. Despite her artistic ability she has a more than respectable career as a graphic designer.
+ }.squish,
+ released_on: "2004-07-23",
+ rating: "PG-13",
+ total_gross: 82_102_379
+ },
+ {
+ title: "Wonder Woman",
+ description:
+ %{
+ When a pilot crashes and tells of conflict in the outside world, Diana, an Amazonian warrior in training, leaves home to fight a war, discovering her full powers and true destiny.
+ }.squish,
+ released_on: "2017-06-02",
+ rating: "PG-13",
+ total_gross: 821_847_012
+ }
+])