diff --git a/Gemfile.lock b/Gemfile.lock
index 0755bfd..8eb5779 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,6 +1,6 @@
GIT
remote: https://github.com/HubFeenixMakers/merged
- revision: 05ee69ce24b7c5a593b8c57c87a3e1f8e50f3b32
+ revision: 528cd025880bdb656e19736654e6621e8a4b27b3
specs:
merged (0.1.0)
active_hash
@@ -294,7 +294,7 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
- rails-html-sanitizer (1.4.4)
+ rails-html-sanitizer (1.5.0)
loofah (~> 2.19, >= 2.19.1)
rails_gravatar (1.0.4)
actionview
diff --git a/app/assets/images/fallback/default.png b/app/assets/images/fallback/default.png
new file mode 100644
index 0000000..ef843ce
Binary files /dev/null and b/app/assets/images/fallback/default.png differ
diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb
index 04b1266..51926d9 100644
--- a/app/controllers/members_controller.rb
+++ b/app/controllers/members_controller.rb
@@ -48,6 +48,7 @@ class MembersController < ApplicationController
# Only allow a list of trusted parameters through.
def member_params
- params.require(:member).permit(:name, :public, :bio , :picture, :arrived ,:left)
+ params.require(:member).permit(:name, :public, :bio , :picture,
+ :picture_cache , :arrived ,:left)
end
end
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 08429f1..0286699 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -5,20 +5,22 @@ class RegistrationsController < Devise::RegistrationsController
# before_action :configure_account_update_params, only: [:update]
prepend_before_action :authenticate_scope!, only: [:edit_email]
-
def new
build_resource
super
end
- # POST /resource
+
def create
if message = math_check
+ puts message
flash.now.alert = message
+ build_resource(sign_up_params)
+ render :new
+ else
+ super
end
- super
end
- # GET /resource/edit
def edit_email
build_resource
puts "EDIT"
@@ -28,17 +30,12 @@ class RegistrationsController < Devise::RegistrationsController
build_resource
super
end
- # PUT /resource
+
def update
puts "UPDATE"
super
end
- # DELETE /resource
- # def destroy
- # super
- # end
-
protected
def math_check
diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb
index fdf670d..a666c9f 100644
--- a/app/controllers/stories_controller.rb
+++ b/app/controllers/stories_controller.rb
@@ -1,26 +1,21 @@
class StoriesController < ApplicationController
before_action :set_story, only: %i[ show edit update destroy ]
- # GET /stories
def index
@stories = Story.all.page params[:page]
end
- # GET /stories/1
def show
end
- # GET /stories/new
def new
@story = Story.new
end
- # GET /stories/1/edit
def edit
authorize @story
end
- # POST /stories
def create
@story = Story.new(story_params)
@story.member = current_member
@@ -32,8 +27,8 @@ class StoriesController < ApplicationController
end
end
- # PATCH/PUT /stories/1
def update
+ authorize @story
if @story.update(story_params)
redirect_to @story, notice: "Story was successfully updated."
else
@@ -41,8 +36,8 @@ class StoriesController < ApplicationController
end
end
- # DELETE /stories/1
def destroy
+ authorize @story
@story.destroy
redirect_to stories_url, notice: "Story was successfully destroyed."
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 69188e1..814de4c 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -5,10 +5,11 @@ module ApplicationHelper
# different template according to the amount of text
def render_story(story)
return "" unless story
+ puts story.text.length
text_length = story.text.length
template = "text"
- template = "half" if text_length < 400
- template = "pic" if text_length < 200
+ template = "half" if text_length < 500
+ template = "pic" if text_length < 300
render partial: "stories/#{template}" , locals: {story: story}
end
@@ -54,4 +55,22 @@ module ApplicationHelper
rows
end
+ def main_menu
+ [["/members" , "Volunteers"],["/stories" , "Stories"], ["/info" , "Info"],
+ ["/arriving" , "Arriving"],["/about" , "About"], ]
+ end
+ def member_memu
+ items =[["/forum" ,"Forum"] , [main_app.member_path(current_member) , "Settings"]]
+ if current_member.admin? and !Rails.env.production?
+ items << [merged.pages_path(), "CMS" ]
+ end
+ items
+ end
+ def mobile_menu
+ if current_member
+ member_memu
+ else
+ [main_app.member_session_path, "Login"]
+ end
+ end
end
diff --git a/app/helpers/heroicon_helper.rb b/app/helpers/heroicon_helper.rb
new file mode 100644
index 0000000..c4f9665
--- /dev/null
+++ b/app/helpers/heroicon_helper.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+module HeroiconHelper
+ include Heroicon::Engine.helpers
+end
\ No newline at end of file
diff --git a/app/javascript/marked.min.js b/app/javascript/marked.min.js
deleted file mode 100644
index c61fd0a..0000000
--- a/app/javascript/marked.min.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * marked - a markdown parser
- * Copyright (c) 2011-2022, Christopher Jeffrey. (MIT Licensed)
- * https://github.com/markedjs/marked
- */
-!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).marked={})}(this,function(r){"use strict";function i(e,t){for(var u=0;u "+e+"'+(u?e:c(e,!0))+"
\n":"
\n"},t.blockquote=function(e){return""+(u?e:c(e,!0))+"
\n"+e+"
\n"},t.html=function(e){return e},t.heading=function(e,t,u,n){return this.options.headerIds?"
\n":"
\n"},t.list=function(e,t,u){var n=t?"ol":"ul";return"<"+n+(t&&1!==u?' start="'+u+'"':"")+">\n"+e+""+n+">\n"},t.listitem=function(e){return"\n\n"+e+"\n"+(t=t&&""+t+"")+"
\n"},t.tablerow=function(e){return"\n"+e+" \n"},t.tablecell=function(e,t){var u=t.header?"th":"td";return(t.align?"<"+u+' align="'+t.align+'">':"<"+u+">")+e+""+u+">\n"},t.strong=function(e){return""+e+""},t.em=function(e){return""+e+""},t.codespan=function(e){return""+e+"
"},t.br=function(){return this.options.xhtml?"
":"
"},t.del=function(e){return""+e+""},t.link=function(e,t,u){return null===(e=F(this.options.sanitize,this.options.baseUrl,e))?u:(e='"+u+"")},t.image=function(e,t,u){return null===(e=F(this.options.sanitize,this.options.baseUrl,e))?u:(e='":">"))},t.text=function(e){return e},e}(),S=function(){function e(){}var t=e.prototype;return t.strong=function(e){return e},t.em=function(e){return e},t.codespan=function(e){return e},t.del=function(e){return e},t.html=function(e){return e},t.text=function(e){return e},t.link=function(e,t,u){return""+u},t.image=function(e,t,u){return""+u},t.br=function(){return""},e}(),T=function(){function e(){this.seen={}}var t=e.prototype;return t.serialize=function(e){return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")},t.getNextSafeSlug=function(e,t){var u=e,n=0;if(this.seen.hasOwnProperty(u))for(n=this.seen[e];u=e+"-"+ ++n,this.seen.hasOwnProperty(u););return t||(this.seen[e]=n,this.seen[u]=0),u},t.slug=function(e,t){void 0===t&&(t={});e=this.serialize(e);return this.getNextSafeSlug(e,t.dryrun)},e}(),R=function(){function u(e){this.options=e||r.defaults,this.options.renderer=this.options.renderer||new $,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new S,this.slugger=new T}u.parse=function(e,t){return new u(t).parse(e)},u.parseInline=function(e,t){return new u(t).parseInline(e)};var e=u.prototype;return e.parse=function(e,t){void 0===t&&(t=!0);for(var u,n,r,i,s,l,a,o,D,c,h,p,f,g,F,A,d="",C=e.length,k=0;k
"+c(e.message+"",!0)+"";throw e}try{var a=z.lex(e,u);if(u.walkTokens){if(u.async)return Promise.all(I.walkTokens(a,u.walkTokens)).then(function(){return R.parse(a,u)}).catch(t);I.walkTokens(a,u.walkTokens)}return R.parse(a,u)}catch(e){t(e)}}I.options=I.setOptions=function(e){return C(I.defaults,e),e=I.defaults,r.defaults=e,I},I.getDefaults=e,I.defaults=r.defaults,I.use=function(){for(var o=I.defaults.extensions||{renderers:{},childTokens:{}},e=arguments.length,t=new Array(e),u=0;u
"+c(e.message+"",!0)+"";throw e}},I.Parser=R,I.parser=R.parse,I.Renderer=$,I.TextRenderer=S,I.Lexer=z,I.lexer=z.lex,I.Tokenizer=w,I.Slugger=T;var d=(I.parse=I).options,P=I.setOptions,Q=I.use,U=I.walkTokens,M=I.parseInline,N=I,X=R.parse,G=z.lex;r.Lexer=z,r.Parser=R,r.Renderer=$,r.Slugger=T,r.TextRenderer=S,r.Tokenizer=w,r.getDefaults=e,r.lexer=G,r.marked=I,r.options=d,r.parse=N,r.parseInline=M,r.parser=X,r.setOptions=P,r.use=Q,r.walkTokens=U}); \ No newline at end of file diff --git a/app/models/member.rb b/app/models/member.rb index 11298f7..4c73a86 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -7,6 +7,9 @@ class Member < ApplicationRecord mount_uploader :picture, PictureUploader has_many :stories + validates :bio, length: { maximum: 1000 } + validates :name , length: { minimum: 3 } + def admin self.email == "torsten@villataika.fi" end diff --git a/app/models/story.rb b/app/models/story.rb index 1f6685e..e55ab4b 100644 --- a/app/models/story.rb +++ b/app/models/story.rb @@ -3,8 +3,8 @@ class Story < ApplicationRecord mount_uploader :picture, PictureUploader - validates :text, length: { maximum: 1000 } - validates :header , length: { minimum: 5 } + validates :text, length: { minimum: 5 , maximum: 1000 } + validates :header , length: { minimum: 5 , maximum: 400} def name header diff --git a/app/policies/edit_own_policy.rb b/app/policies/edit_own_policy.rb new file mode 100644 index 0000000..0882e81 --- /dev/null +++ b/app/policies/edit_own_policy.rb @@ -0,0 +1,14 @@ +# allows to edit/detroy own data +# which can be viewed by anyone +class EditOwnPolicy < ApplicationPolicy + def edit? + return true if member.admin? + owner? + end + def owner? + member == record.member + end + alias :update? :edit? + alias :destroy? :edit? + +end diff --git a/app/policies/story_policy.rb b/app/policies/story_policy.rb index 53b3bb4..fb142fb 100644 --- a/app/policies/story_policy.rb +++ b/app/policies/story_policy.rb @@ -1,4 +1,4 @@ -class StoryPolicy < ApplicationPolicy +class StoryPolicy < EditOwnPolicy def edit? (member == record.member) or member.admin? diff --git a/app/uploaders/picture_uploader.rb b/app/uploaders/picture_uploader.rb index fbe8e09..42856bd 100644 --- a/app/uploaders/picture_uploader.rb +++ b/app/uploaders/picture_uploader.rb @@ -14,12 +14,10 @@ class PictureUploader < CarrierWave::Uploader::Base end # Provide a default URL as a default if there hasn't been a file uploaded: - # def default_url(*args) - # # For Rails 3.1+ asset pipeline compatibility: - # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) - # - # "/images/fallback/" + [version_name, "default.png"].compact.join('_') - # end + def default_url(*args) + # For Rails 3.1+ asset pipeline compatibility: + ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) + end # Process files as they are uploaded: # process scale: [200, 300] diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index 1204781..4d80568 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -5,6 +5,11 @@ html: { class: "bg-white mb-4 px-8 pt-6 pb-8 rounded shadow-md" } , url: registration_path(resource_name) ) do |f| = render "devise/shared/error_messages", resource: resource + .mb-4 + = f.label :name, class: "block font-bold mb-2 text-gray-700 text-sm" + = f.input :name, + placeholder: "Pekka Virtanen", + class: "appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none shadow focus:shadow-outline" .mb-4 = f.label :email, class: "block font-bold mb-2 text-gray-700 text-sm" = f.email_field :email, diff --git a/app/views/layouts/_header.haml b/app/views/layouts/_header.haml index 93a8fd3..28ea087 100644 --- a/app/views/layouts/_header.haml +++ b/app/views/layouts/_header.haml @@ -4,11 +4,9 @@ = image_tag("feenix_lintu.webp" , class: "h-20") %span.ml-2.text-xl.font-bold.tracking-wide.text-gray-800.uppercase Hub Feenix %ul.flex.items-center.hidden.space-x-8.lg:flex - %li - %a.font-medium.tracking-wide.text-gray-700.transition-colors.duration-400.hover:text-cyan-800{"aria-label" => "Our product", :href => "/members", :title => "Volunteers"} Volunteers - - [ :stories , :info , :arriving, :about].each do |link| + - main_menu.each do |link , text| %li - %a.font-medium.tracking-wide.text-gray-700.transition-colors.duration-400.hover:text-cyan-800{"aria-label" => "Our product", :href => "/#{link}", :title => link.capitalize}= link.capitalize + %a.font-medium.tracking-wide.text-gray-700.transition-colors.duration-400.hover:text-cyan-800{"aria-label" => "Our product", :href => link, :title => text}= text %li = link_to "https://www.facebook.com/hubfeenix" , :target => "_blank" do = image_tag("fb.webp" , class: "h-10 rounded-md") diff --git a/app/views/layouts/_member_menu.haml b/app/views/layouts/_member_menu.haml index beb6759..933cff5 100644 --- a/app/views/layouts/_member_menu.haml +++ b/app/views/layouts/_member_menu.haml @@ -1,12 +1,8 @@ #menu-dropdown.hidden.absolute.right-0.z-10.mt-4.w-36.origin-top-right.rounded-md.border.border-gray-100.bg-white.shadow-lg{:role => "menu"} .p-2 - %a.block.rounded-lg.px-4.py-2.text-sm.text-gray-500.hover:bg-gray-50.hover:text-gray-700{:href => "/forum", :role => "menuitem"} - Forum - %a.block.rounded-lg.px-4.py-2.text-sm.text-gray-500.hover:bg-gray-50.hover:text-gray-700{:href => main_app.member_path(current_member), :role => "menuitem"} - Profile - - unless Rails.env.production? - %a.block.rounded-lg.px-4.py-2.text-sm.text-gray-500.hover:bg-gray-50.hover:text-gray-700{:href => merged.pages_path(), :role => "menuitem"} - CMS + - member_memu.each do |link , text| + %a.block.rounded-lg.px-4.py-2.text-sm.text-gray-500.hover:bg-gray-50.hover:text-gray-700{:href => link, :role => "menuitem"} + =text = form_tag( main_app.destroy_member_session_path , {method: :delete } ) do %button.flex.w-full.items-center.gap-2.rounded-lg.px-4.py-2.text-sm.text-blue-700.hover:bg-red-50{:role => "menuitem", :type => "submit"} %svg.h-4.w-4{:fill => "none", :stroke => "currentColor", "stroke-width" => "2", :viewbox => "0 0 24 24", :xmlns => "http://www.w3.org/2000/svg"} diff --git a/app/views/layouts/_mobile_menu.haml b/app/views/layouts/_mobile_menu.haml index 4f9a31b..d16ff01 100644 --- a/app/views/layouts/_mobile_menu.haml +++ b/app/views/layouts/_mobile_menu.haml @@ -1,4 +1,4 @@ -#mobile-menu.absolute.top-0.left-0.w-full.hidden +#mobile-menu.absolute.top-0.left-0.w-full.hidden.z-10 .p-5.bg-white.border.rounded.shadow-sm .flex.items-center.justify-between.mb-4 %div @@ -10,10 +10,26 @@ %svg.w-5.text-gray-600{:viewbox => "0 0 24 24"} %path{:d => "M19.7,4.3c-0.4-0.4-1-0.4-1.4,0L12,10.6L5.7,4.3c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l6.3,6.3l-6.3,6.3 c-0.4,0.4-0.4,1,0,1.4C4.5,19.9,4.7,20,5,20s0.5-0.1,0.7-0.3l6.3-6.3l6.3,6.3c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3 c0.4-0.4,0.4-1,0-1.4L13.4,12l6.3-6.3C20.1,5.3,20.1,4.7,19.7,4.3z", :fill => "currentColor"} %nav - %ul.space-y-6.px-20 - - [:volunteers , :stories , :info , :arriving, :about].each do |link| + %ul.space-y-6.px-20.w-lg.text-center + - main_menu.each do |link , text| %li - %a.font-medium.tracking-wide.text-xl{ :href => "/#{link}" , :title => link.capitalize}= link.capitalize + %a.w-full.h-full.block.tracking-wide.text-xl.p-2.rounded-lg.hover:bg-cyan-200{ :href => link , :title => text} + = text + %li + %hr + - mobile_menu.each do |link , text| + %li + %a.w-full.h-full.block.tracking-wide.text-xl.p-2.rounded-lg.hover:bg-cyan-200{ :href => link , :title => text} + = text + -if(current_member) + = form_tag( main_app.destroy_member_session_path , {method: :delete ,class: "text-center"}) do + %button.w-full.items-center.gap-2.rounded-lg.px-4.py-2.text-sm.text-blue-700.hover:bg-red-50{:role => "menuitem", :type => "submit"} + %svg.h-4.w-4{:fill => "none", :stroke => "currentColor", "stroke-width" => "2", :viewbox => "0 0 24 24", :xmlns => "http://www.w3.org/2000/svg"} + %path{:d => "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16", "stroke-linecap" => "round", "stroke-linejoin" => "round"} + Sign out + -else + %a.inline-flex.items-center.justify-center.h-12.px-6.font-medium.tracking-wide.text-white.transition.duration-200.rounded-lg.shadow-md.bg-green-800.hover:bg-blue-800.focus:shadow-outline.focus:outline-none{"aria-label" => "Sign up", :href => main_app.member_session_path, :title => "Log in or Sign up"} + Login :javascript var drop_hidden = true; function menu_on() { diff --git a/app/views/layouts/application.haml b/app/views/layouts/application.haml index 5eecd05..e487f79 100644 --- a/app/views/layouts/application.haml +++ b/app/views/layouts/application.haml @@ -32,7 +32,7 @@ - if false %script{:src => "https://cdn.tailwindcss.com"} - %body + %body.max-w-screen-2xl.xl:mx-auto = render "layouts/header" = render "layouts/messages" = yield diff --git a/app/views/members/_form.html.haml b/app/views/members/_form.html.haml deleted file mode 100644 index fe415a0..0000000 --- a/app/views/members/_form.html.haml +++ /dev/null @@ -1,29 +0,0 @@ -= form_for @member do |f| - .flex.flex-col - - if @member.errors.any? - #error_explanation - %h2= "#{pluralize(@member.errors.count, "error")} prohibited this member from being saved:" - %ul - - @member.errors.full_messages.each do |message| - %li= message - - .grid.grid-cols-2.m-20.gap-10 - .field - = f.label :name - = f.text_field :name - .field - = f.label :public - = f.check_box :public - .field - = f.label :picture - = f.file_field :picture - -if @member.picture - %div.overflow-hidden - .my-5 Currently - = image_tag @member.picture, class: "object-contain h-40" - - .field - = f.label :Bio - = f.rich_text_area :bio - .flex.justify-center.actions - = f.submit 'Save' diff --git a/app/views/members/edit.html.haml b/app/views/members/edit.html.haml index 1c8062d..9f33dd2 100644 --- a/app/views/members/edit.html.haml +++ b/app/views/members/edit.html.haml @@ -1,44 +1,28 @@ -= javascript_include_tag "merged/vue.min.js" -= javascript_include_tag "marked.min.js" +%script{:src => "https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"} +%script{:src => "https://cdn.jsdelivr.net/npm/marked/marked.min.js"} -.flex.justify-center.m-20 - .flex.flex-col - %h1.text-4xl Editing profile +.flex.justify-center.m-5.m-5.md:m-12.lg:m-20 + .flex.flex-col.text-center + %h1.text-4xl Edit your profile -= simple_form_for @member do |f| - = f.error_notification - - .grid.grid-cols-4.mx-20 - .info.mr-8 - = f.input :name - .grid.grid-cols-2.gap-10 - = f.input :arrived - = f.input :left - = f.input :public , label: "Public: (Click box below)" - = f.input :picture , as: :file , label: (@member.picture.blank? ? "Add picture" : "Change picture") - .flex.justify-center.actions.m-10 - = f.button :button, "Update", class: button_classes + " bg-cyan-200" - = link_to member_path(@member) do - %button.ml-10{type: :submit, class: button_classes} - Back - .field.flex.flex-col.pr-2.border-r-8.border-slate-600 - = f.text_area :bio ,rows: 18 , "v-model" => "markdown" , class: "appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" - %div.h-90 - -if @member.picture_url - %div.overflow-hidden.ml-2.mr-8 - = image_tag @member.picture_url, class: "object-contain w-full" - -else - No Picture - .preview.prose - %b.text-2xl Preview - %div{"v-html" => "compiledMarkdown"} -:ruby2js - class Mark < Vue - options el: '.grid' - def initialize - @markdown = "#{@member.bio.to_s.html_safe}" - end - def compiledMarkdown - marked.parse(@markdown) - end - end +.flex.justify-center.m-5.m-5.md:m-12.lg:m-20 + .flex.flex-col.text-center{class: "w-full md:w-10/12"} + = simple_form_for @member do |f| + .grid.grid-cols-1.md:grid-cols-2.gap-10 + = render "merged/form/editor" , object: @member , field: :bio, form: f + .info.mr-8 + .text-red-700= f.error_notification + = f.input :name + .grid.grid-cols-2.gap-10 + = f.input :arrived + = f.input :left + .flex.h-16.mt-2 + = image_tag(@member.picture_url , class: "align-middle mr-2") if @member.picture? + = f.input :picture , as: :file , input_html: {wrapper_class: "w-full"}, + label: (@member.picture.blank? ? "Add picture" : "Change picture") + = f.hidden_field :picture_cache + .flex.justify-center.actions.m-10 + = f.button :button, "Update", class: button_classes + " bg-cyan-200" + = link_to member_path(@member) do + %button.ml-10{type: :submit, class: button_classes} + Back diff --git a/app/views/members/index.html.haml b/app/views/members/index.html.haml index c1e9f7f..5b0a765 100644 --- a/app/views/members/index.html.haml +++ b/app/views/members/index.html.haml @@ -1,16 +1,15 @@ = paginate @members -.flex.justify-center - .grid.grid-cols-4 - - @members.each do |member| - .fex.flex-col.overflow-hidden.rounded-lg.border.border-gray-100.shadow-sm.m-10 - =link_to member do - = image_for( member , class: "h-60 w-full object-cover") - %h3.pt-5.text-2xl.bg-gray-100.text-black.font-bold.text-center - = member.name - .p-2.text-xs.bg-gray-50.text-black.font-bold.text-center - = stayed member - %div.h-full - .p-5.text-center - .m-2.text-sm.leading-relaxed.line-clamp-3{ prose_classes } - = shorten markdown(member.bio) +.grid.grid-cols-1.md:grid-cols-2.lg:grid-cols-4 + - @members.each do |member| + .fex.flex-col.overflow-hidden.rounded-lg.border.border-gray-100.shadow-sm.m-10 + =link_to member do + = image_for( member , class: "h-60 w-full object-cover") + %h3.pt-5.text-2xl.bg-gray-100.text-black.font-bold.text-center + = member.name + .p-2.text-xs.bg-gray-50.text-black.font-bold.text-center + = stayed member + %div.h-full + .p-5.text-center + .m-2.text-sm.leading-relaxed.line-clamp-3{ prose_classes } + = shorten markdown(member.bio) diff --git a/app/views/stories/_form.haml b/app/views/stories/_form.haml new file mode 100644 index 0000000..d3c2ec9 --- /dev/null +++ b/app/views/stories/_form.haml @@ -0,0 +1,20 @@ +%div + Story layout changes with the amount of text. + For short text a wide picture is best. Otherwise square, and for + longer text a high picture also works. += simple_form_for @story do |f| + = f.error_notification + .flex.h-16.mt-2 + = image_tag(@story.picture_url , class: "align-middle mr-2") if @story.picture? + = f.input :picture , as: :file , input_html: {wrapper_class: "w-full"}, + label: (@story.picture.blank? ? "Add picture" : "Change picture") + = f.hidden_field :picture_cache + = f.input :header + = render "merged/form/editor" , object: @story , field: :text, form: f + = f.input :happened , wrapper_class: "flex mt-4 align-center" + .flex.justify-between.mt-6 + %button.bg-cyan-200.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 + = f.submit 'Save' + = link_to member_path(current_member) do + %button.ml-20.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 + Back diff --git a/app/views/stories/_half.haml b/app/views/stories/_half.haml index 0a4b080..e8d32ce 100644 --- a/app/views/stories/_half.haml +++ b/app/views/stories/_half.haml @@ -7,6 +7,6 @@ = story.header %h4.text-xl.mt-10.md:text-2xl = distance_of_time_in_words_to_now story.happened - ago half + ago .mt-8{ prose_classes } = markdown(story.text) diff --git a/app/views/stories/_pic.haml b/app/views/stories/_pic.haml index 8b15553..00456fc 100644 --- a/app/views/stories/_pic.haml +++ b/app/views/stories/_pic.haml @@ -8,6 +8,6 @@ = story.header %h4.text-xl.mt-4.lg:mt-8.md:text-2xl = distance_of_time_in_words_to_now story.happened - ago pic + ago .mt-3{ prose_classes } = markdown(story.text) diff --git a/app/views/stories/edit.html.haml b/app/views/stories/edit.html.haml index ca3044e..0c469f4 100644 --- a/app/views/stories/edit.html.haml +++ b/app/views/stories/edit.html.haml @@ -1,16 +1,7 @@ -.grid.grid-cols-3 - %div - %div - %h1 Editing story - = simple_form_for @story do |f| - = f.error_notification - - = f.input :picture , as: :file , label: (@story.picture.blank? ? "Add picture" : "Change picture") - = f.input :header - = f.input :text , input_html: {rows: rows(@story.text)} - = f.input :happened , wrapper_class: "flex mt-4 align-center" - %button.mt-6.bg-cyan-200.mr-3.inline-block.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 - = f.submit 'Save' - %button.ml-20.mr-3.inline-block.rounded-lg.px-4.py-3.text-md.font-medium.border.border-gray-400 - = link_to 'Back', @story - %div +%script{:src => "https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"} +%script{:src => "https://cdn.jsdelivr.net/npm/marked/marked.min.js"} +.flex.justify-center + .column{class: "w-10/12 md:w-8/12 lg:w-7/12 xl:w-6/12"} + .text-2xl.font-bold.my-4 + Edit Story + = render 'form' diff --git a/app/views/stories/new.html.haml b/app/views/stories/new.html.haml index 80c3028..0c18074 100644 --- a/app/views/stories/new.html.haml +++ b/app/views/stories/new.html.haml @@ -1,20 +1,7 @@ - -.grid.grid-cols-3 - %div - %div - %h1 New story - = form_for @story do |f| - - if @story.errors.any? - #error_explanation - %h2= "#{pluralize(@story.errors.count, "error")} prohibited this story from being saved:" - %ul - - @story.errors.full_messages.each do |message| - %li= message - - = f.input :picture , as: :file - = f.input :header - = f.input :text - = f.input :happened , class: "flex" - = f.submit 'Save' - = link_to 'Back', stories_path - %div +%script{:src => "https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"} +%script{:src => "https://cdn.jsdelivr.net/npm/marked/marked.min.js"} +.flex.justify-center + .column{class: "w-10/12 md:w-8/12 lg:w-7/12 xl:w-6/12"} + .text-2xl.font-bold.my-4 + New Story + = render 'form' diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index 9bfb6e1..ba525a9 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -9,4 +9,4 @@ Rails.application.config.assets.version = "1.0" # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in the app/assets # folder are already added. -Rails.application.config.assets.precompile += %w( marked.min.js images/*.webp) +Rails.application.config.assets.precompile += %w( images/*.webp) diff --git a/config/initializers/heroicon.rb b/config/initializers/heroicon.rb new file mode 100644 index 0000000..db7d89e --- /dev/null +++ b/config/initializers/heroicon.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +Heroicon.configure do |config| + config.variant = :solid # Options are :solid, :outline and :mini + + ## + # You can set a default class, which will get applied to every icon with + # the given variant. To do so, un-comment the line below. + # config.default_class = {solid: "h-5 w-5", outline: "h-6 w-6", mini: "h-4 w-4"} +end diff --git a/config/initializers/lib.rb b/config/initializers/lib.rb new file mode 100644 index 0000000..905dcc7 --- /dev/null +++ b/config/initializers/lib.rb @@ -0,0 +1 @@ +require "form_handler" diff --git a/config/routes.rb b/config/routes.rb index 2cf0176..a2be4e2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -10,8 +10,9 @@ Rails.application.routes.draw do mount Thredded::Engine => '/forum' - mount Merged::Engine => "/merged" + mount Merged::Engine => "/merged" unless Rails.env.production? + post "/form" , to: "merged/form#post" , as: :post_form get "/news/:id" , to: "merged/view#page" , id: :id , as: :view_blog get ":id" , to: "merged/view#page" , id: :id , as: :view_page diff --git a/merged/sections.yml b/merged/sections.yml index 99427e0..38dc648 100644 --- a/merged/sections.yml +++ b/merged/sections.yml @@ -183,7 +183,7 @@ :image_id: 89 - :template: section_cards :index: 1 - :page_id: 9 + :page_id: 10 :updated_at: 2023-01-19 14:26:59.100565929 +02:00 :updated_by: torsten@villataika.fi :id: 50