From 9aa88aa08094a34c54c30673c567a4decca827b0 Mon Sep 17 00:00:00 2001 From: "BOYA,CHIU" Date: Mon, 9 Aug 2021 18:03:32 +0800 Subject: [PATCH] add some changes --- active.gemspec | 17 +- app/assets/stylesheets/active_front.css.scss | 36 ++++ app/controllers/actives_controller.rb | 77 ++++---- app/controllers/admin/actives_controller.rb | 2 +- app/models/act.rb | 56 ++++++ app/views/actives/show_data.html.erb | 98 +++++----- app/views/admin/actives/_form.html.erb | 176 +++++++++++++++++- config/locales/en.yml | 7 + config/locales/zh_tw.yml | 9 +- module/active/active_index.html.erb | 29 +++ module/active/active_index1.html.erb | 25 +++ module/active/active_index2.html.erb | 32 ++++ module/active/info.json | 28 +++ module/active/thumbs/active_index1_thumbs.png | Bin 0 -> 2130 bytes module/active/thumbs/active_index2_thumbs.png | Bin 0 -> 3379 bytes module/active/thumbs/thumb.png | Bin 0 -> 4075 bytes 16 files changed, 501 insertions(+), 91 deletions(-) create mode 100644 app/assets/stylesheets/active_front.css.scss create mode 100644 module/active/active_index.html.erb create mode 100644 module/active/active_index1.html.erb create mode 100644 module/active/active_index2.html.erb create mode 100644 module/active/info.json create mode 100644 module/active/thumbs/active_index1_thumbs.png create mode 100644 module/active/thumbs/active_index2_thumbs.png create mode 100644 module/active/thumbs/thumb.png diff --git a/active.gemspec b/active.gemspec index 4a6e476..c65f810 100644 --- a/active.gemspec +++ b/active.gemspec @@ -2,7 +2,22 @@ $:.push File.expand_path("../lib", __FILE__) # Maintain your gem's version: require "active/version" - +bundle_update_flag = ARGV[0]=='update' || ARGV[0]=='install' +if bundle_update_flag + app_path = File.expand_path(__dir__) + template_path = ENV['PWD'] + '/app/templates' + all_template = Dir.glob(template_path+'/*/') + puts 'copying module' + all_template.each do |folder| + if folder.split('/')[-1] != 'mobile' + begin + system ('cp -r '+ app_path + '/modules/ ' + folder) + rescue + puts 'error copy' + end + end + end +end # Describe your gem and declare its dependencies: Gem::Specification.new do |s| s.name = "active" diff --git a/app/assets/stylesheets/active_front.css.scss b/app/assets/stylesheets/active_front.css.scss new file mode 100644 index 0000000..c570935 --- /dev/null +++ b/app/assets/stylesheets/active_front.css.scss @@ -0,0 +1,36 @@ +// Place all the styles related to the act controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ +.active-index2 li.col-md-4{ + float: left; + .active-meta{ + padding-left: 1em; + padding-top: 0.5em; + } + .active-img-wrap { + overflow: hidden; + height: 12.5em; + img { + max-height: 100%; + max-width: 100%; + height: auto; + width: auto; + } + } + a:hover .active-title{ + color: #0032b2; + font-size: 1.3em; + } + @media (min-width: 992px){ + width: 33.3333%; + } + @media (min-width: 577px) and (max-width: 991px){ + width: 50%; + } + @media (max-width: 576px){ + width: 100%; + .active-img-wrap { + height: auto; + } + } +} \ No newline at end of file diff --git a/app/controllers/actives_controller.rb b/app/controllers/actives_controller.rb index 63e9705..ba2a138 100644 --- a/app/controllers/actives_controller.rb +++ b/app/controllers/actives_controller.rb @@ -3,41 +3,58 @@ class ActivesController < ApplicationController helper MemberHelper def index - + begin time_now = Time.now - + OrbitHelper.render_css_in_head(["active_front"]) actives = Act.filter_by_categories.desc(:sign_start_date).page(OrbitHelper.params[:page_no]).per(OrbitHelper.page_data_count) acts = actives.collect do |a| - - title = ('' + a.title + '').html_safe - - if (!a.sign_up.blank? and a.sign_start_date <= time_now and ( a.sign_end_date >= time_now or a.sign_end_date.nil? ) rescue false) - sign_up = ('' + t('act.sign_up') + '').html_safe - elsif a.sign_up.blank? - sign_up = t('act.sign_up_not_open') - elsif (a.sign_start_date > time_now rescue false) - sign_up = t('act.sign_up_not_yet') - else - sign_up = t('act.sign_up_overdue') + link_to_show = OrbitHelper.url_to_show(a.to_param) + '?method=show_data' + title_text = a.title + title = "#{title_text}" + sign_up = a.signup_show + statuses = a.statuses_with_classname.collect do |status| + { + "status" => status["name"], + "status-class" => "status-#{status['classname']}" + } end + act_start_date = (a.act_start_date.blank? ? "" : a.act_start_date.strftime('%Y-%m-%d %H:%M') rescue "") + act_end_date = (a.act_end_date.blank? ? t(:no_deadline) : a.act_end_date.strftime('%Y-%m-%d %H:%M') rescue "") + act_duration_date = act_start_date.blank? ? act_end_date : "#{act_start_date} ~ #{act_end_date}" + + sign_start_date = (a.sign_start_date.blank? ? "" : a.sign_start_date.strftime('%Y-%m-%d %H:%M') rescue "") + sign_end_date = ((a.sign_end_date ? a.sign_end_date.strftime('%Y-%m-%d %H:%M') : t(:no_deadline)) rescue "") + sign_duration_date = sign_start_date.blank? ? sign_end_date : "#{sign_start_date} ~ #{sign_end_date}" + + desc = a.image_description + desc = (desc.blank? ? "active image" : desc) { + "link_to_show" => link_to_show, + "title_text" => title_text, + "statuses" => statuses, "title" => title, + "subtitle" => a.subtitle, + "img_src" => a.image.thumb.url || "/assets/announcement-default.jpg", + "img_description" => desc, "category" => a.category.title, - "sign_start_date" => (a.sign_start_date.strftime('%Y-%m-%d %H:%M') rescue ""), - "sign_end_date" => ((a.sign_end_date ? a.sign_end_date.strftime('%Y-%m-%d %H:%M') : t(:no_deadline)) rescue ""), - "act_start_date" => (a.act_start_date.strftime('%Y-%m-%d %H:%M') rescue ""), - "act_end_date" => (a.act_end_date ? a.act_end_date.strftime('%Y-%m-%d %H:%M') : t(:no_deadline) rescue ""), - 'sign_up_time_range' => (Act.time_range(a.sign_start_date, a.sign_end_date) rescue ""), - 'sign_up_time_range' => (Act.time_range(a.sign_start_date, a.sign_end_date) rescue ""), - 'act_time_range' => (Act.time_range(a.act_start_date, a.act_end_date) rescue ""), - 'sign_up' => sign_up + "sign_duration_date" => sign_duration_date, + "sign_start_date" => sign_start_date, + "sign_end_date" => sign_end_date, + "act_duration_date" => act_duration_date, + "act_start_date" => act_start_date, + "act_end_date" => act_end_date, + 'sign_up_time_range' => (Act.time_range(a.sign_start_date, a.sign_end_date) rescue ""), + 'act_time_range' => (Act.time_range(a.act_start_date, a.act_end_date) rescue ""), + 'sign_up' => sign_up } end + _display = acts.count == 0 ? "hide" : '' { "acts" => acts, "extras" => { + "display" => _display, "widget-title"=>t('act.active'), "th_title" => t('act.title'), "th_act_time_range" => t('act.act_time_range'), @@ -47,7 +64,9 @@ class ActivesController < ApplicationController }, "total_pages" => actives.total_pages } - + rescue => e + puts [e,e.backtrace] + end end def show_privacy @@ -73,19 +92,9 @@ class ActivesController < ApplicationController act = Act.find_by(uid: params[:uid]) - if (!act.sign_up.blank? and act.sign_start_date <= time_now and ( act.sign_end_date >= time_now or act.sign_end_date.nil? ) rescue false) - sign_up = ('' + t('act.sign_up') + '').html_safe - elsif act.sign_up.blank? - sign_up = t('act.sign_up_not_open') - elsif (act.sign_start_date > time_now rescue false) - sign_up = t('act.sign_up_not_yet') - else - sign_up = t('act.sign_up_overdue') - end - { 'act' => act, - 'sign_up' => sign_up, + 'sign_up' => act.signup_show, 'time_now' => time_now, 'sign_up_time_range' => (Act.time_range(act.sign_start_date, act.sign_end_date) rescue ""), 'act_time_range' => (Act.time_range(act.act_start_date, act.act_end_date) rescue "") @@ -102,7 +111,7 @@ class ActivesController < ApplicationController act = Act.find_by(uid: params[:uid]) - act_signup = ActSignup.new + act_signup = ActSignup.new(id: nil) time_now = Time.now diff --git a/app/controllers/admin/actives_controller.rb b/app/controllers/admin/actives_controller.rb index 6f55f7e..c397dd8 100644 --- a/app/controllers/admin/actives_controller.rb +++ b/app/controllers/admin/actives_controller.rb @@ -43,7 +43,7 @@ class Admin::ActivesController < OrbitAdminController def new @tags = @module_app.tags - @act = Act.new + @act = Act.new(id: nil) end def create diff --git a/app/models/act.rb b/app/models/act.rb index 51d0a11..0c41a70 100644 --- a/app/models/act.rb +++ b/app/models/act.rb @@ -8,11 +8,22 @@ class Act include OrbitCategory::Categorizable include Slug + include OrbitModel::Status + field :image_description, type: String, localize: true + field :top_end_date, :type => DateTime + mount_uploader :image, ImageUploader + field :is_external_link, type: Boolean, default: false + field :external_link, type: String, default: "" + field :title, as: :slug_title, type: String, localize: true + field :subtitle, type: String, localize: true + field :content, localize: true field :place, localize: true field :create_user_id field :update_user_id + field :postdate , :type => DateTime, :default => Time.now + field :end_date , :type => DateTime, :default => Time.now field :act_start_date , :type => DateTime, :default => Time.now field :act_end_date , :type => DateTime, :default => Time.now field :sign_start_date , :type => DateTime, :default => Time.now @@ -93,5 +104,50 @@ class Act end end + + def self.remove_expired_status + self.where(:is_top => true, :top_end_date.ne => nil, :top_end_date.lt => Time.now).each do |act| + act.is_top = false + act.top_end_date = nil + act.save + end + end + + def top_text + I18n.t("top") + end + def hot_text + I18n.t("hot") + end + def hidden_text + I18n.t("hidden") + end + + def statuses_with_classname + statuses = [] + statuses << {"name" => top_text, "classname" => "top"} if is_top? + statuses << {"name" => hot_text, "classname" => "hot"} if is_hot? + statuses << {"name" => hidden_text, "classname" => "hidden"} if is_hidden? + statuses + end + + def can_sign_up? + (self.sign_up && (self.sign_start_date.blank? || self.sign_start_date <= time_now) && ( self.sign_end_date.blank? || self.sign_end_date >= time_now )) rescue false + end + + def is_external_link? + self.is_external_link && !self.external_link.blank? + end + def signup_show + if self.can_sign_up? + sign_up = ('' + I18n.t('act.sign_up') + '').html_safe + elsif self.sign_up + sign_up = I18n.t('act.sign_up_not_open') + elsif (self.sign_start_date > time_now rescue false) + sign_up = I18n.t('act.sign_up_not_yet') + else + sign_up = I18n.t('act.sign_up_overdue') + end + end end diff --git a/app/views/actives/show_data.html.erb b/app/views/actives/show_data.html.erb index 6349988..b758ec1 100644 --- a/app/views/actives/show_data.html.erb +++ b/app/views/actives/show_data.html.erb @@ -8,70 +8,68 @@ @act_time_range = data["act_time_range"] %> - +

<%= @act.title %>

- + - + - - - + + + - <% if !@act.content.blank? %> - - - - - <% end %> - + <% if !@act.sign_start_date.blank? || !@act.sign_end_date.blank? %> + - <% if !@act.place.blank? %> - - - - <% end %> - <% if !@act.act_files.blank? %> - - - - - <% end %> - <% if !@act.act_links.blank? %> - - - - - <% end %> - <% if !@act.note.blank? %> - - - - - <% end %> - + <% if @act.sign_up %> + - + + <% end %>
<%= t(:category) %> <%= @act.category.title %>
<%= t('act.act_time_range') %> <%= @act_time_range %>
<%= t('act.title') %><%= @act.title %>
<%= t('act.place') %><%= @act.place %>
<%= t('act.content') %><%= nl2br(@act.content) %>
<%= t('act.place') %><%= @act.place %>
<%= t(:file_) %> - <% @act.act_files.map do |file| %> - <%= link_to (file.title.blank? ? File.basename(file.file.path) : file.title) , file.file.url, {:target => '_blank', :title => file.description} if file.file.file %> - <% end %> -
<%= t(:link) %> - <% @act.act_links.map do |link| %> - <%= link_to (link.title.blank? ? link.url : link.title), link.url, :target => '_blank' %> - <% end %> -
<%= t('act.note') %><%= @act.note %>
- -
- -<%= link_to t(:close), 'javascript:window.close();', :class => 'btn btn-primary' %> +
+<%= nl2br(@act.content.to_s).html_safe %> +
+ +<% if !@act.note.blank? %> +

<%= @act.note %>

+<% end %> +<%# link_to t(:close), 'javascript:window.close();', :class => 'btn btn-primary' %> diff --git a/app/views/admin/actives/_form.html.erb b/app/views/admin/actives/_form.html.erb index 4e3d76e..8eb496d 100644 --- a/app/views/admin/actives/_form.html.erb +++ b/app/views/admin/actives/_form.html.erb @@ -19,7 +19,10 @@ @@ -36,6 +39,22 @@ + +
+ +
+ <%= f.datetime_picker :postdate, :no_label => true, :new_record => @act.new_record? %> +
+
+ + +
+ +
+ <%= f.datetime_picker :end_date, :no_label => true, :new_record => @act.new_record? %> +
+
+
@@ -74,6 +93,22 @@
+ + + + +
@@ -82,7 +117,7 @@
@@ -318,6 +353,84 @@
+ + + +
+ +
+ +
+ + + +
+
+
" data-for="is_top"> + +
+ <%= f.datetime_picker :top_end_date, :no_label => true, :new_record => @act.new_record? %> +
+
+
+ + +
+
+ + <%= select_tags(f, @module_app) %> +
+
+ + +
+ + +
+ +
+
+
+ <% if @act.image.file %> + <%= image_tag @act.image %> + <% else %> + + <% end %> +
+
+ + <%= t(:select_image) %> + <%= t(:change) %> + <%= f.file_field :image %> + + <%= t(:cancel) %> +
+ +
+
+
+
+ <% @site_in_use_locales.each do |locale| %> + <%= f.fields_for :image_description_translations do |f| %> +
+ +
+ <%= f.text_field locale, value: (@act.image_description_translations[locale.to_s] rescue nil) %> +
+
+ <% end %> + <% end %> + +
+ @@ -342,7 +455,17 @@
<%= f.fields_for :title_translations do |f| %> - <%= f.text_field locale, class: "input-block-level", placeholder: t(:title), value: (@act.title_translations[locale] rescue nil) %> + <%= f.text_area locale, class: "ckeditor_reduce input-block-level", placeholder: t(:title), value: (@act.title_translations[locale] rescue nil) %> + <% end %> +
+ + + +
+ +
+ <%= f.fields_for :subtitle_translations do |f| %> + <%= f.text_area locale, class: "ckeditor input-block-level", placeholder: t(:subtitle), value: (@act.subtitle_translations[locale] rescue nil) %> <% end %>
@@ -457,6 +580,16 @@ <% content_for :page_specific_javascript do %> <% end %> \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 1c9be07..efd62e1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -11,6 +11,13 @@ en: verification_failed: Verification Failed act: + is_external_link: Enable External Link + external_link: External Link + external_link_hint: "Make sure URL starts with http://" + top_end_date: Top end date + postdate: Post date + end_date: End date + image: Cover Image active: Active title: Event Title content: Content diff --git a/config/locales/zh_tw.yml b/config/locales/zh_tw.yml index c343011..a84f711 100644 --- a/config/locales/zh_tw.yml +++ b/config/locales/zh_tw.yml @@ -11,6 +11,13 @@ zh_tw: verification_failed: 驗證碼錯誤 act: + is_external_link: 連結外部網址 + external_link: 外部連結 + external_link_hint: "確定連結開頭為http://" + top_end_date: 至頂結束時間 + postdate: 張貼日期 + end_date: 下架日期 + image: 封面圖片 active: 活動報名 title: 活動標題 content: 活動說明 @@ -34,7 +41,7 @@ zh_tw: sign_up_not_yet: 報名時間未開始 sign_up_not_open: 未開放報名 sign_up_overdue: 報名時間已過 - settings: Activity Settings + settings: 活動報名設定 has_idno: 報名是否需填寫身分證字號 has_birthday: 出生年月日 has_sex: 性別 diff --git a/module/active/active_index.html.erb b/module/active/active_index.html.erb new file mode 100644 index 0000000..3bb4e90 --- /dev/null +++ b/module/active/active_index.html.erb @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + +
+

{{page-title}}

+
{{th_category}}{{th_act_time_range}}{{th_title}}{{th_sign_up_time_range}}{{th_sign_up}}
{{category}}{{act_duration_date}} + + {{status}} + + {{title}} + {{sign_duration_date}}{{sign_up}}
+{{pagination_goes_here}} \ No newline at end of file diff --git a/module/active/active_index1.html.erb b/module/active/active_index1.html.erb new file mode 100644 index 0000000..49fe82a --- /dev/null +++ b/module/active/active_index1.html.erb @@ -0,0 +1,25 @@ +
+

{{page-title}}

+ + + + + + + + + + + + + + + +
{{th_act_time_range}}{{th_title}}{{th_sign_up}}
{{act_duration_date}} + + {{status}} + + {{title}} + {{sign_up}}
+
+{{pagination_goes_here}} diff --git a/module/active/active_index2.html.erb b/module/active/active_index2.html.erb new file mode 100644 index 0000000..99f9a19 --- /dev/null +++ b/module/active/active_index2.html.erb @@ -0,0 +1,32 @@ +
+

{{page-title}}

+ +
+{{pagination_goes_here}} \ No newline at end of file diff --git a/module/active/info.json b/module/active/info.json new file mode 100644 index 0000000..aa5f20c --- /dev/null +++ b/module/active/info.json @@ -0,0 +1,28 @@ +{ + "frontend": [ + { + "filename" : "active_index", + "name" : { + "zh_tw" : "1. 列表 (類別, 活動期間, 狀態, 活動標題, 報名期間, 線上報名)", + "en" : "1. List (Category, Event Period, status, Event Title, Registration Period, Register)" + }, + "thumbnail" : "thumb.png" + }, + { + "filename" : "active_index1", + "name" : { + "zh_tw" : "2. 精簡表格列表-2 ( 模組標題, 活動期間, 狀態, 標題, 線上報名)", + "en" : "2. Simple Table List (widget-title, Event Period, status, title, Register)" + }, + "thumbnail" : "active_index1_thumbs.png" + }, + { + "filename" : "active_index2", + "name" : { + "zh_tw" : "3. 三欄圖文 ( 模組標題, 圖片, 狀態, 活動期間, 類別, 標題, 副標題, 線上報名)", + "en" : "3. 3-Column Standard Image + Text (widget-title, image, status, postdate, category, title, subtitle, Register)" + }, + "thumbnail" : "active_index2_thumbs.png" + } + ] +} \ No newline at end of file diff --git a/module/active/thumbs/active_index1_thumbs.png b/module/active/thumbs/active_index1_thumbs.png new file mode 100644 index 0000000000000000000000000000000000000000..0a58044bcab1badab10347049e79a10fdef28201 GIT binary patch literal 2130 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 literal 0 HcmV?d00001 diff --git a/module/active/thumbs/thumb.png b/module/active/thumbs/thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..266af5606742714c262a949cd58aedc2b84b1959 GIT binary patch literal 4075 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