Skip to content

Commit

Permalink
Add project priorities
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisvel committed Nov 27, 2024
1 parent 71d0834 commit 768e5cb
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 21 deletions.
49 changes: 37 additions & 12 deletions app/frontend/components/Project/ProjectModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import ConfirmDialog from "../Shared/ConfirmDialog";
import { useToast } from "../Shared/ToastContext";
import TagInput from "../Tag/TagInput";
import useFetchTags from "../../hooks/useFetchTags";
import PriorityDropdown from "../Shared/PriorityDropdown";
import { PriorityType } from "../../entities/Task";
import Switch from "../Shared/Switch";

interface ProjectModalProps {
isOpen: boolean;
Expand All @@ -30,12 +33,19 @@ const ProjectModal: React.FC<ProjectModalProps> = ({
area_id: null,
active: true,
tags: [],
priority: "low",
}
);

const [tags, setTags] = useState<string[]>(project?.tags?.map(tag => tag.name) || []);
const [tags, setTags] = useState<string[]>(
project?.tags?.map((tag) => tag.name) || []
);

const { tags: availableTags, isLoading: isTagsLoading, isError: isTagsError } = useFetchTags();
const {
tags: availableTags,
isLoading: isTagsLoading,
isError: isTagsError,
} = useFetchTags();

const modalRef = useRef<HTMLDivElement>(null);
const [isClosing, setIsClosing] = useState(false);
Expand All @@ -49,7 +59,7 @@ const ProjectModal: React.FC<ProjectModalProps> = ({
...project,
tags: project.tags || [],
});
setTags(project.tags?.map(tag => tag.name) || []);
setTags(project.tags?.map((tag) => tag.name) || []);
} else {
setFormData({
name: "",
Expand Down Expand Up @@ -127,7 +137,7 @@ const ProjectModal: React.FC<ProjectModalProps> = ({
}, []);

const handleSubmit = () => {
onSave({ ...formData, tags: tags.map(name => ({ name })) });
onSave({ ...formData, tags: tags.map((name) => ({ name })) });
showSuccessToast(
project
? "Project updated successfully!"
Expand All @@ -154,7 +164,14 @@ const ProjectModal: React.FC<ProjectModalProps> = ({
setTimeout(() => {
onClose();
setIsClosing(false);
}, 300);
}, 300);
};

const handleToggleActive = () => {
setFormData((prev) => ({
...prev,
active: !prev.active,
}));
};

if (!isOpen) return null;
Expand Down Expand Up @@ -232,6 +249,18 @@ const ProjectModal: React.FC<ProjectModalProps> = ({
></textarea>
</div>

<div className="pb-3">
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-3">
Priority
</label>
<PriorityDropdown
value={formData.priority || "medium"}
onChange={(value: PriorityType) =>
setFormData({ ...formData, priority: value })
}
/>
</div>

{/* Tags */}
<div className="pb-3">
<label className="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-2">
Expand Down Expand Up @@ -269,13 +298,9 @@ const ProjectModal: React.FC<ProjectModalProps> = ({

{/* Active Checkbox */}
<div className="flex items-center">
<input
type="checkbox"
id="active"
name="active"
checked={formData.active}
onChange={handleChange}
className="h-5 w-5 appearance-none border border-gray-300 rounded-md bg-white dark:bg-gray-700 checked:bg-blue-600 checked:border-transparent focus:outline-none focus:ring-2 focus:ring-blue-500"
<Switch
isChecked={formData.active}
onToggle={handleToggleActive}
/>
<label
htmlFor="active"
Expand Down
30 changes: 30 additions & 0 deletions app/frontend/components/Shared/Switch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Switch.tsx
import React from 'react';

interface SwitchProps {
isChecked: boolean;
onToggle: () => void;
}

const Switch: React.FC<SwitchProps> = ({ isChecked, onToggle }) => {
return (
<div
className="flex items-center space-x-2"
>
<div
className={`w-12 h-6 flex items-center rounded-full p-1 cursor-pointer transition-all duration-300 ${
isChecked ? 'bg-blue-600' : 'bg-gray-300'
}`}
onClick={onToggle}
>
<div
className={`bg-white w-4 h-4 rounded-full shadow-md transform transition-transform duration-300 ${
isChecked ? 'translate-x-6' : ''
}`}
></div>
</div>
</div>
);
};

export default Switch;
2 changes: 2 additions & 0 deletions app/frontend/entities/Project.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Area } from "./Area";
import { Tag } from "./Tag";
import { PriorityType } from "./Task";

export interface Project {
id?: number;
Expand All @@ -10,4 +11,5 @@ export interface Project {
area?: Area;
area_id?: number | null;
tags?: Tag[];
priority?: PriorityType;
}
2 changes: 2 additions & 0 deletions app/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ class Project < ActiveRecord::Base
has_many :notes, dependent: :destroy
has_and_belongs_to_many :tags

enum priority: { low: 0, medium: 1, high: 2 }

scope :with_incomplete_tasks, -> { joins(:tasks).where.not(tasks: { status: Task.statuses[:done] }).distinct }
scope :with_complete_tasks, -> { joins(:tasks).where(tasks: { status: Task.statuses[:done] }).distinct }

Expand Down
8 changes: 6 additions & 2 deletions app/routes/projects_routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,15 @@ def update_project_tags(project, tags_data)
halt 400, { error: 'Invalid JSON format.' }.to_json
end

project_data['priority'] = Project.priorities[project_data['priority']] if project_data['priority'].is_a?(String)

project = current_user.projects.new(
name: project_data['name'],
description: project_data['description'] || '',
area_id: project_data['area_id'],
active: true,
pin_to_sidebar: false
pin_to_sidebar: false,
priority: project_data['priority']
)

if project.save
Expand Down Expand Up @@ -102,7 +105,8 @@ def update_project_tags(project, tags_data)
description: project_data['description'],
area_id: project_data['area_id'],
active: project_data['active'],
pin_to_sidebar: project_data['pin_to_sidebar']
pin_to_sidebar: project_data['pin_to_sidebar'],
priority: project_data ['priority']
)

if project.save
Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20241126095028_add_priority_to_projects.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddPriorityToProjects < ActiveRecord::Migration[7.1]
def change
add_column :projects, :priority, :integer
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.1].define(version: 2024_11_21_113756) do
ActiveRecord::Schema[7.1].define(version: 2024_11_26_095028) do
create_table "areas", force: :cascade do |t|
t.string "name"
t.integer "user_id", null: false
Expand Down Expand Up @@ -47,6 +47,7 @@
t.text "description"
t.boolean "active", default: false
t.boolean "pin_to_sidebar", default: false
t.integer "priority"
t.index ["area_id"], name: "index_projects_on_area_id"
t.index ["user_id"], name: "index_projects_on_user_id"
end
Expand Down
23 changes: 17 additions & 6 deletions public/js/bundle.js

Large diffs are not rendered by default.

0 comments on commit 768e5cb

Please sign in to comment.