Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions app/assets/stylesheets/_kanban.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
.kanban-board-wrapper {
background-color: #f8f9fa;
border-radius: 8px;
padding: 16px;
min-height: 80vh;

.kanban-search input {
max-width: 300px;
}
}

.kanban-board-columns {
display: flex;
gap: 16px;
align-items: flex-start;
overflow-x: auto;
padding-bottom: 12px;

/* Mobile scroll snap styling */
@media (max-width: 768px) {
scroll-snap-type: x mandatory;
-webkit-overflow-scrolling: touch;
}
}

.kanban-column {
flex: 1;
min-width: 280px;
background-color: #ebecf0;
border-radius: 8px;
padding: 12px;
border: 2px dashed transparent;
transition: background-color 0.15s ease, border-color 0.15s ease;

@media (max-width: 768px) {
scroll-snap-align: center;
min-width: 85vw;
max-width: 85vw;
}

&.is-drag-over {
background-color: #e2e4e6;
border-color: #0079bf;
}
}

.kanban-column-header {
margin-bottom: 12px;

.kanban-column-title {
font-size: 1.05rem;
font-weight: 600;
color: #172b4d;
}
}

.kanban-column-cards {
display: flex;
flex-direction: column;
gap: 10px;
min-height: 120px;
}

.kanban-card {
background-color: #ffffff;
border: none;
border-radius: 6px;
box-shadow: 0 1px 3px rgba(9, 30, 66, 0.15);
cursor: grab;
transition: transform 0.15s ease, box-shadow 0.15s ease, opacity 0.15s ease;
user-select: none;
touch-action: none; /* Prevent default touch scrolling when dragging cards */

&:hover {
box-shadow: 0 4px 8px rgba(9, 30, 66, 0.2);
transform: translateY(-2px);
}

&:active {
cursor: grabbing;
}

&.is-dragging {
opacity: 0.4;
}

.btn-xs {
font-size: 0.72rem;
padding: 1px 5px;
}
}

.kanban-empty-state {
border: 1px dashed #cccccc;
border-radius: 6px;
background: rgba(255, 255, 255, 0.5);
}

.kanban-touch-avatar {
background: #ffffff;
border-left: 4px solid #0079bf;
border-radius: 6px;
}
1 change: 1 addition & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
@import "garden_cards";
@import "garden_layout";
@import "inactive_gardens";
@import "kanban";
@import "photos";
@import "posts";
@import "seeds";
Expand Down
14 changes: 12 additions & 2 deletions app/controllers/activities_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# frozen_string_literal: true

class ActivitiesController < DataController
skip_load_and_authorize_resource only: :mine

def mine
@activities = current_member.activities.includes(:garden, planting: :crop).order(due_date: :asc, created_at: :desc)
respond_with @activities
end

def index
@show_all = params[:all] == '1'

Expand Down Expand Up @@ -88,7 +95,10 @@ def create

def update
@activity.update(activity_params)
respond_with @activity
respond_to do |format|
format.html { respond_with @activity }
format.json { render json: @activity }
end
end

def destroy
Expand All @@ -100,7 +110,7 @@ def destroy

def activity_params
params.require(:activity).permit(
:name, :description, :category, :finished,
:name, :description, :category, :finished, :status,
:garden_id, :planting_id, :due_date,
:repeat_times, :repeat_weeks
)
Expand Down
25 changes: 25 additions & 0 deletions app/helpers/activities_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

module ActivitiesHelper
def activities_kanban_props(activities)
initial_activities = activities.map do |activity|
{
id: activity.id,
slug: activity.slug,
name: activity.name,
category: activity.category,
status: activity.status || (activity.finished? ? 'done' : 'planned'),
due_date: activity.due_date&.strftime('%b %d, %Y'),
garden_name: activity.garden&.name,
planting_name: activity.planting&.crop&.name,
description: activity.description,
url: activity_path(activity)
}
end

{
initialActivities: initial_activities,
newActivityUrl: new_activity_path
}
end
end
Loading
Loading