schoolgirl_uniform 0.2.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,118 @@
1
- uuid: <%= @record.uuid %>
2
- <br>
3
- username: <%= @record.username %>
4
- <br>
5
- email: <%= @record.personal_data.email %>
6
- <br>
7
- phone: <%= @record.personal_data.phone %>
1
+ <style>
2
+ body {
3
+ font-family: Arial, sans-serif;
4
+ background-color: #f4f4f4;
5
+ display: flex;
6
+ justify-content: center;
7
+ align-items: flex-start;
8
+ min-height: 100vh;
9
+ margin: 0;
10
+ padding: 20px 0;
11
+ }
12
+
13
+ .form-container {
14
+ background-color: #fff;
15
+ padding: 30px;
16
+ border-radius: 8px;
17
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
18
+ width: 100%;
19
+ max-width: 600px;
20
+ margin-top: 20px;
21
+ margin-bottom: 20px;
22
+ }
23
+ /* Finish Step / Results Styling */
24
+ .results-display {
25
+ background-color: #e9f5e9; /* Light green background */
26
+ border: 1px solid #c8e6c9; /* Greenish border */
27
+ padding: 25px;
28
+ border-radius: 6px;
29
+ line-height: 1.8; /* Better readability for text lines */
30
+ margin-top: 20px; /* Add some space if it's directly after the form */
31
+ }
32
+
33
+ .results-display h3 {
34
+ margin-top: 0;
35
+ color: #2e7d32; /* Darker green for the heading */
36
+ border-bottom: 1px solid #a5d6a7; /* Lighter green border under heading */
37
+ padding-bottom: 10px;
38
+ margin-bottom: 20px;
39
+ }
40
+
41
+ .results-display .result-item {
42
+ margin-bottom: 12px; /* Space between each result item */
43
+ font-size: 1.05em; /* Slightly larger font for readability */
44
+ }
45
+
46
+ .results-display .result-item b {
47
+ color: #333; /* Dark grey for the labels (bold text) */
48
+ margin-right: 8px; /* Space after the label */
49
+ display: inline-block; /* Ensures proper spacing and layout */
50
+ min-width: 120px; /* Optional: aligns values if labels have varying lengths */
51
+ }
52
+
53
+ .results-display hr {
54
+ border: 0;
55
+ height: 1px;
56
+ background-color: #d0e0d0; /* Lighter green/grey for the horizontal rule */
57
+ margin-top: 20px;
58
+ margin-bottom: 20px;
59
+ }
60
+ </style>
61
+ <div class="form-container">
62
+ <div class="results-display">
63
+ <h3>Registration Complete!</h3>
64
+ <div class="result-item">
65
+ <b>ID:</b> <%= @record.id %>
66
+ </div>
67
+
68
+ <div class="result-item">
69
+ <b>Username:</b> <%= @record.username %>
70
+ </div>
71
+ <hr>
72
+
73
+ <div class="result-item">
74
+ <b>Date of Birth:</b> <%= @record.personal_detail&.date_of_birth %>
75
+ </div>
76
+
77
+ <div class="result-item">
78
+ <b>Gender:</b> <%= @record.personal_detail&.gender %>
79
+ </div>
80
+
81
+ <div class="result-item">
82
+ <b>Favourite Color:</b> <%= @record.personal_detail&.favourite_color %>
83
+ </div>
84
+
85
+ <div class="result-item">
86
+ <b>Device Type:</b> <%= @record.personal_detail&.device_type %>
87
+ </div>
88
+ <hr>
89
+
90
+ <div class="result-item">
91
+ <b>Email:</b> <%= @record.contact_info&.email %>
92
+ </div>
93
+
94
+ <div class="result-item">
95
+ <b>Phone Number:</b> <%= @record.contact_info&.phone_number %>
96
+ </div>
97
+
98
+ <div class="result-item">
99
+ <b>Country:</b> <%= @record.contact_info&.country %>
100
+ </div>
101
+
102
+ <div class="result-item">
103
+ <b>City:</b> <%= @record.contact_info&.city %>
104
+ </div>
105
+
106
+ <div class="result-item">
107
+ <b>Address Line 1:</b> <%= @record.contact_info&.address_field_1 %>
108
+ </div>
109
+
110
+ <div class="result-item">
111
+ <b>Address Line 2:</b> <%= @record.contact_info&.address_field_2 %>
112
+ </div>
113
+
114
+ <div class="result-item">
115
+ <b>Zip Code:</b> <%= @record.contact_info&.zip_code %>
116
+ </div>
117
+ </div>
118
+ </div>
@@ -1,16 +1,7 @@
1
- <style>
2
- .schoolgirl-uniform-errors {
3
- border: 1px solid red;
4
- }
5
- .schoolgirl-uniform-errors span {
6
- color: red;
7
- }
8
- </style>
9
-
10
- <% if @form.errors.any? %>
1
+ <% if form.errors.any? %>
11
2
  <div class="schoolgirl-uniform-errors">
12
3
  <ul>
13
- <% @form.errors.full_messages.each do |message|%>
4
+ <% form.errors.full_messages.each do |message|%>
14
5
  <li>
15
6
  <span><%= message %> </span>
16
7
  </li>
@@ -1,44 +1,87 @@
1
- class <%= class_name %>Form < SchoolgirlUniform::BaseForm
2
- attribute :username, String
3
- attribute :password, String
4
- attribute :email, String
5
- attribute :phone, String
1
+ class <%= class_name %>Form
2
+ include SchoolgirlUniform::Uniformable
6
3
 
7
- validates :username, presence: true, length: 3..10, if: proc { on_step('first') }
8
- validate :custom_username_validation, if: proc { on_step('first') }
9
- validates :password, length: { minimum: 3 }, if: proc { on_step('first') }
4
+ attribute :username, :string
5
+ attribute :password, :string
10
6
 
11
- validates :email, presence: true, if: proc { on_step('second') }
12
- validate :custom_email_validation, if: proc { on_step('second') }
7
+ attribute :date_of_birth, :date
8
+ attribute :gender, :string
9
+ attribute :favourite_color, :string
10
+ attribute :device_type, :string
13
11
 
14
- validates :phone, presence: true, if: proc { on_step('third') }
15
- validate :custom_phone_validation, if: proc { on_step('third') }
12
+ attribute :email, :string
13
+ attribute :phone_number, :string
14
+ attribute :country, :string
15
+ attribute :city, :string
16
+ attribute :address_field_1, :string
17
+ attribute :address_field_2, :string
18
+ attribute :zip_code, :string
19
+
20
+ steps %w[first second third]
21
+
22
+ def self.steps_details
23
+ {
24
+ first: 'Credentials',
25
+ second: 'Personal Details',
26
+ third: 'Contact Information'
27
+ }
28
+ end
29
+
30
+ attr_reader :identifier
31
+
32
+ with_options if: :first? do |step|
33
+ step.validates :username, presence: true, length: 3..10
34
+ step.validate :custom_username_validation
35
+ step.validates :password, length: { minimum: 3 }
36
+ end
37
+
38
+ with_options if: :second? do |step|
39
+ step.validates :date_of_birth, presence: true
40
+ step.validate :custom_date_of_birth_validation
41
+ end
42
+
43
+ with_options if: :third? do |step|
44
+ step.validates :email, presence: true
45
+ step.validate :custom_email_validation
46
+
47
+ step.validates :phone_number, presence: true
48
+ step.validate :custom_phone_validation
49
+ end
16
50
 
17
51
  def custom_username_validation
52
+ errors.add(:username, "#{username} is already taken, enter uniq username") if User.where(username: username).exists?
18
53
  errors.add(:username, 'cannot contain "@"') if username.include?('@')
19
54
  errors.add(:username, 'cannot contain "#"') if username.include?('#')
20
55
  errors.add(:username, 'cannot contain "?"') if username.include?('?')
21
56
  end
22
57
 
58
+ def custom_date_of_birth_validation
59
+ begin
60
+ date = Date.parse(date_of_birth.to_s)
61
+ if date > Date.today - 18.years
62
+ errors.add(:date_of_birth, 'You need to be 18 year old or older to participate in this survey.')
63
+ end
64
+ rescue => e
65
+ errors.add(:date_of_birth, 'Please enter a valid date in the format: DD.MM.YYYY')
66
+ end
67
+ end
68
+
23
69
  def custom_email_validation
24
- errors.add(:email, 'should contain "@"') if email.exclude?('@')
70
+ errors.add(:email, 'should contain "@"') if email.exclude?('@')
25
71
  errors.add(:email, 'should not contain ".."') if email.include?('..')
26
72
  end
27
73
 
28
74
  def custom_phone_validation
29
- errors.add(:phone, 'should be max 14 symbols') if phone.size > 14
75
+ errors.add(:phone_number, 'should be min 3 symbols') if phone_number.size < 3
76
+ errors.add(:phone_number, 'should be max 14 symbols') if phone_number.size > 14
30
77
  end
31
78
 
32
- def self.steps
33
- %w[first second third]
34
- end
35
79
 
36
80
  def save!
37
- ActiveRecord::Base.transaction do
38
- user.save!(validate: false)
39
- personal_data.save!(validate: false)
40
- end
41
- @identifier = user.reload.uuid
81
+ user.save!(validate: false)
82
+ personal_detail.save!(validate: false)
83
+ contact_info.save!(validate: false)
84
+ @identifier = user.id
42
85
  end
43
86
 
44
87
  private
@@ -47,7 +90,24 @@ class <%= class_name %>Form < SchoolgirlUniform::BaseForm
47
90
  @user ||= User.new(username: username, password: password)
48
91
  end
49
92
 
50
- def personal_data
51
- user.build_personal_data(email: email, phone: phone)
93
+ def personal_detail
94
+ user.build_personal_detail(
95
+ date_of_birth: date_of_birth,
96
+ gender: gender,
97
+ favourite_color: favourite_color,
98
+ device_type: device_type
99
+ )
100
+ end
101
+
102
+ def contact_info
103
+ user.build_contact_info(
104
+ email: email,
105
+ phone_number: phone_number,
106
+ country: country,
107
+ city: city,
108
+ address_field_1: address_field_1,
109
+ address_field_2: address_field_2,
110
+ zip_code: zip_code
111
+ )
52
112
  end
53
113
  end
@@ -1,27 +1,203 @@
1
1
  <style>
2
+ body {
3
+ font-family: Arial, sans-serif;
4
+ background-color: #f4f4f4;
5
+ display: flex;
6
+ justify-content: center;
7
+ align-items: flex-start;
8
+ min-height: 100vh;
9
+ margin: 0;
10
+ padding: 20px 0;
11
+ }
12
+
13
+ .form-container {
14
+ background-color: #fff;
15
+ padding: 30px;
16
+ border-radius: 8px;
17
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
18
+ width: 100%;
19
+ max-width: 600px;
20
+ margin-top: 20px;
21
+ margin-bottom: 20px;
22
+ }
23
+
24
+ .schoolgirl-uniform-step-wizard {
25
+ display: flex;
26
+ justify-content: space-around;
27
+ margin-bottom: 30px;
28
+ padding-bottom: 15px;
29
+ border-bottom: 1px solid #e0e0e0;
30
+ }
31
+
32
+ .schoolgirl-uniform-step-wizard .milestone {
33
+ padding: 8px 15px;
34
+ border: 1px solid #ccc;
35
+ border-radius: 20px;
36
+ background-color: #f9f9f9;
37
+ color: #555;
38
+ font-size: 0.9em;
39
+ text-align: center;
40
+ flex-grow: 1;
41
+ margin: 0 5px;
42
+ }
43
+
44
+ .schoolgirl-uniform-step-wizard .milestone.active {
45
+ background-color: #58aaca;
46
+ color: white;
47
+ border-color: #276891;
48
+ border-style: dashed;
49
+ border-width: 2px;
50
+ }
51
+
52
+ .schoolgirl-uniform-step-wizard .milestone.passed {
53
+ background-color: #4CAF50;
54
+ color: white;
55
+ border-color: #388E3C;
56
+ }
57
+
58
+ .schoolgirl-uniform-step-wizard .milestone.completed {
59
+ background-color: #D4EDDA;
60
+ color: #155724;
61
+ border-color: #C3E6CB;
62
+ }
63
+
64
+ .multistep-form .form-step-content {
65
+ border: 1px solid #ddd;
66
+ padding: 25px;
67
+ border-radius: 6px;
68
+ margin-bottom: 25px;
69
+ background-color: #fdfdfd;
70
+ }
71
+
72
+ .multistep-form .form-group {
73
+ margin-bottom: 20px;
74
+ }
75
+
76
+ .multistep-form .form-group label {
77
+ display: block;
78
+ margin-bottom: 8px;
79
+ font-weight: bold;
80
+ color: #333;
81
+ font-size: 0.95em;
82
+ }
83
+
84
+ .multistep-form .form-group input[type="text"],
85
+ .multistep-form .form-group input[type="password"],
86
+ .multistep-form .form-group input[type="date"],
87
+ .multistep-form .form-group input[type="email"],
88
+ .multistep-form .form-group input[type="tel"],
89
+ .multistep-form .form-group select {
90
+ width: 100%;
91
+ padding: 12px;
92
+ border: 1px solid #ccc;
93
+ border-radius: 4px;
94
+ box-sizing: border-box;
95
+ font-size: 1em;
96
+ transition: border-color 0.3s ease;
97
+ }
98
+
99
+ .multistep-form .form-group input[type="text"]:focus,
100
+ .multistep-form .form-group input[type="password"]:focus,
101
+ .multistep-form .form-group input[type="date"]:focus,
102
+ .multistep-form .form-group input[type="email"]:focus,
103
+ .multistep-form .form-group input[type="tel"]:focus,
104
+ .multistep-form .form-group select:focus {
105
+ border-color: #4CAF50;
106
+ outline: none;
107
+ box-shadow: 0 0 5px rgba(76, 175, 80, 0.5);
108
+ }
109
+
2
110
  .field_with_errors {
3
111
  display: inline-block;
112
+ width: 100%;
113
+ }
114
+ .field_with_errors input,
115
+ .field_with_errors select {
116
+ border: 1px solid red !important;
117
+ }
118
+
119
+ .schoolgirl-uniform-errors {
120
+ border: 1px solid red;
121
+ padding: 10px;
122
+ margin-bottom: 20px;
123
+ border-radius: 4px;
124
+ background-color: #ffebeb;
125
+ }
126
+ .schoolgirl-uniform-errors ul {
127
+ list-style-type: none;
128
+ padding-left: 0;
129
+ margin: 0;
130
+ }
131
+ .schoolgirl-uniform-errors li {
132
+ margin-bottom: 5px;
133
+ }
134
+ .schoolgirl-uniform-errors span {
135
+ color: red;
136
+ }
137
+
138
+ .form-navigation {
139
+ display: flex;
140
+ justify-content: space-between;
141
+ align-items: center;
142
+ margin-top: 25px;
143
+ padding-top: 20px;
144
+ border-top: 1px solid #e0e0e0;
145
+ }
146
+
147
+ .form-navigation a,
148
+ .form-navigation input[type="submit"] {
149
+ padding: 12px 25px;
150
+ border: none;
151
+ border-radius: 5px;
152
+ text-decoration: none;
153
+ font-size: 1em;
154
+ cursor: pointer;
155
+ transition: background-color 0.3s ease, box-shadow 0.3s ease;
156
+ }
157
+
158
+ .form-navigation a {
159
+ background-color: #6c757d;
160
+ color: white;
161
+ }
162
+ .form-navigation a:hover {
163
+ background-color: #5a6268;
164
+ box-shadow: 0 2px 5px rgba(0,0,0,0.1);
165
+ }
166
+
167
+ .form-navigation input[type="submit"] {
168
+ background-color: #007bff;
169
+ color: white;
4
170
  }
5
- .field_with_errors input {
6
- border: 1px solid red
171
+ .form-navigation input[type="submit"]:hover {
172
+ background-color: #0056b3;
173
+ box-shadow: 0 2px 5px rgba(0,0,0,0.1);
7
174
  }
8
175
  </style>
176
+ <div class="form-container">
177
+
178
+ <%= render 'wizard', form: @form %>
179
+
180
+ <%= form_for @form, as: "#{controller_name}_form".to_sym, url: form_carrier.current_step_path, html: { id: "#{controller_name}_form", class: 'multistep-form' } do |f| %>
181
+ <%= f.hidden_field :step, value: @form.current_step %>
182
+
183
+ <%= render "form_errors", form: @form %>
184
+
185
+ <div class="form-step-content">
186
+ <%= render "#{ controller_name }/steps/#{@form.current_step.underscore}", form: f %>
187
+ </div>
188
+
189
+ <div class="form-navigation">
190
+ <% if !@form.first_step? %>
191
+ <%= link_to 'Back', form_carrier.previous_step_path %>
192
+ <% else %>
193
+ <span>&nbsp;</span>
194
+ <% end %>
9
195
 
10
- <%= render 'wizard', form: @form %>
11
- <%= form_for @form, as: "#{controller_name}_form".to_sym, url: form_carrier.current_step_path, html: { id: "#{controller_name}_form", class: 'multistep-form' } do |form| %>
12
- <%= form.hidden_field :step, value: @form.current_step %>
13
-
14
- <%= render "form_errors", form: form %>
15
- <%= render "#{ controller_name }/steps/#{@form.current_step}", form: form %>
16
-
17
- <div class="tc">
18
- <% if !@form.first_step? %>
19
- <%= link_to 'back', form_carrier.previous_step_path %>
20
- <% end %>
21
- <% if @form.last_step? %>
22
- <%= form.submit 'submit' %>
23
- <% else %>
24
- <%= form.submit 'next' %>
25
- <% end %>
26
- </div>
27
- <% end %>
196
+ <% if @form.last_step? %>
197
+ <%= f.submit 'Submit Details' %>
198
+ <% else %>
199
+ <%= f.submit 'Next Step' %>
200
+ <% end %>
201
+ </div>
202
+ <% end %>
203
+ </div>
@@ -1,5 +1,9 @@
1
- <%= form.label :username %>
2
- <%= form.text_field :username %>
3
- <br>
4
- <%= form.label :password %>
5
- <%= form.text_field :password %>
1
+ <div class="form-group">
2
+ <%= form.label :username %>
3
+ <%= form.text_field :username %>
4
+ </div>
5
+
6
+ <div class="form-group">
7
+ <%= form.label :password %>
8
+ <%= form.password_field :password %>
9
+ </div>
@@ -1,2 +1,19 @@
1
- <%= form.label :email %>
2
- <%= form.text_field :email %>
1
+ <div class="form-group">
2
+ <%= form.label :date_of_birth %>
3
+ <%= form.date_field :date_of_birth %>
4
+ </div>
5
+
6
+ <div class="form-group">
7
+ <%= form.label :gender %>
8
+ <%= form.select :gender, [:male, :female, :else], prompt: 'Select Gender' %>
9
+ </div>
10
+
11
+ <div class="form-group">
12
+ <%= form.label :favourite_color %>
13
+ <%= form.select :favourite_color, [:red, :green , :blue], prompt: 'Select Color' %>
14
+ </div>
15
+
16
+ <div class="form-group">
17
+ <%= form.label :device_type %>
18
+ <%= form.select :device_type, [:android, :ios, :other], prompt: 'Select Device' %>
19
+ </div>
@@ -1,2 +1,34 @@
1
- <%= form.label :phone %>
2
- <%= form.text_field :phone %>
1
+ <div class="form-group">
2
+ <%= form.label :email %>
3
+ <%= form.email_field :email %>
4
+ </div>
5
+
6
+ <div class="form-group">
7
+ <%= form.label :phone_number %>
8
+ <%= form.telephone_field :phone_number %>
9
+ </div>
10
+
11
+ <div class="form-group">
12
+ <%= form.label :country %>
13
+ <%= form.text_field :country %>
14
+ </div>
15
+
16
+ <div class="form-group">
17
+ <%= form.label :city %>
18
+ <%= form.text_field :city %>
19
+ </div>
20
+
21
+ <div class="form-group">
22
+ <%= form.label :address_field_1 %>
23
+ <%= form.text_field :address_field_1 %>
24
+ </div>
25
+
26
+ <div class="form-group">
27
+ <%= form.label :address_field_2 %>
28
+ <%= form.text_field :address_field_2 %>
29
+ </div>
30
+
31
+ <div class="form-group">
32
+ <%= form.label :zip_code %>
33
+ <%= form.text_field :zip_code %>
34
+ </div>
@@ -1,21 +1,7 @@
1
- <style>
2
- .schoolgirl-uniform-step-wizard {
3
- margin: 10px 25%;
4
- }
5
- .milestone {
6
- display: inline-block;
7
- }
8
- div.active {
9
- background-color: greenyellow;
10
- }
11
- </style>
12
-
13
1
  <div class="schoolgirl-uniform-step-wizard">
14
2
  <% form.steps.each_with_index do |step, index| %>
15
- <div class="<%= 'active' if form.current_step_index >= index %> milestone">
16
- <span>
17
- <%= step %>
18
- </span>
3
+ <div class="milestone <%= 'passed' if form.current_step_index > index %> <%= 'active' if form.current_step_index == index %>">
4
+ <span><%= form.steps_details[step.to_sym] || step %></span>
19
5
  </div>
20
6
  <% end %>
21
7
  </div>
@@ -1,3 +1,3 @@
1
1
  module SchoolgirlUniform
2
- VERSION = "0.2.0"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -1,14 +1,6 @@
1
- require 'virtus'
2
1
  require '../schoolgirl_uniform/app/carriers/carrier'
3
2
  require '../schoolgirl_uniform/app/forms/uniformable'
4
- require '../schoolgirl_uniform/app/forms/base_form'
5
3
  require '../schoolgirl_uniform/app/controllers/base_controller'
6
4
  require 'schoolgirl_uniform/engine'
7
5
 
8
- module SchoolgirlUniform
9
- pp 111
10
- # autoload :Uniformable, 'schoolgirl_uniform/forms/uniformable'
11
- # autoload :BaseForm, 'schoolgirl_uniform/forms/base_form'
12
- # autoload :Carrier, 'schoolgirl_uniform/carriers/carrier'
13
- # autoload :BaseController, 'schoolgirl_uniform/controllers/base_controller'
14
- end
6
+ module SchoolgirlUniform; end
@@ -15,6 +15,7 @@ Gem::Specification.new do |spec|
15
15
  Supports selectable per step validations without data persistence into db.}
16
16
  spec.homepage = "https://github.com/vergilet/schoolgirl_uniform"
17
17
  spec.license = "MIT"
18
+ spec.required_ruby_version = '>= 2.7.0'
18
19
 
19
20
  # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
20
21
  # to allow pushing to a single host or delete this section to allow pushing to any host.
@@ -33,10 +34,9 @@ Gem::Specification.new do |spec|
33
34
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
34
35
  spec.require_paths = ["lib"]
35
36
 
36
- spec.add_runtime_dependency 'activemodel', '~> 6.0'
37
+ spec.add_runtime_dependency 'activemodel', ['>= 5.2', '< 9.0']
37
38
 
38
- spec.add_dependency "bundler", '~> 2.0'
39
- spec.add_dependency "rake", '~> 13.0'
40
- spec.add_dependency "rspec", '~> 3.5'
41
- spec.add_dependency "virtus", '~> 2.0'
39
+ spec.add_development_dependency "bundler", '~> 2.0'
40
+ spec.add_development_dependency "rake", '~> 13.0'
41
+ spec.add_development_dependency "rspec", '~> 3.5'
42
42
  end