Compare commits
4 Commits
335879a4b7
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| fe4d8b120c | |||
|
|
ff0730b6c6 | ||
| 0d0b71e749 | |||
|
|
1b8e0367f6 |
@@ -29,17 +29,15 @@ def create_app(config_name=None):
|
|||||||
db.create_all()
|
db.create_all()
|
||||||
_run_migrations()
|
_run_migrations()
|
||||||
|
|
||||||
@app.route('/', defaults={'path': ''})
|
@app.route('/')
|
||||||
@app.route('/<path:path>')
|
def index():
|
||||||
def serve_react(path):
|
return send_from_directory(app.static_folder, 'index.html')
|
||||||
static_folder = app.static_folder
|
|
||||||
if path and os.path.exists(os.path.join(static_folder, path)):
|
|
||||||
return send_from_directory(static_folder, path)
|
|
||||||
return send_from_directory(static_folder, 'index.html')
|
|
||||||
|
|
||||||
@app.errorhandler(404)
|
@app.errorhandler(404)
|
||||||
def not_found(e):
|
def handle_404(e):
|
||||||
|
if request.path.startswith('/api/'):
|
||||||
return jsonify({'error': 'Resource not found', 'message': str(e)}), 404
|
return jsonify({'error': 'Resource not found', 'message': str(e)}), 404
|
||||||
|
return send_from_directory(app.static_folder, 'index.html')
|
||||||
|
|
||||||
@app.errorhandler(400)
|
@app.errorhandler(400)
|
||||||
def bad_request(e):
|
def bad_request(e):
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { format, isToday } from 'date-fns'
|
|||||||
import useProjectStore from '../../store/useProjectStore'
|
import useProjectStore from '../../store/useProjectStore'
|
||||||
import useFocusStore from '../../store/useFocusStore'
|
import useFocusStore from '../../store/useFocusStore'
|
||||||
import useUIStore from '../../store/useUIStore'
|
import useUIStore from '../../store/useUIStore'
|
||||||
import { updateDeliverable as apiUpdate } from '../../api/deliverables'
|
|
||||||
import DeliverableModal from '../Deliverables/DeliverableModal'
|
import DeliverableModal from '../Deliverables/DeliverableModal'
|
||||||
|
|
||||||
const STATUS_KEYS = ['overdue', 'in_progress', 'upcoming', 'completed']
|
const STATUS_KEYS = ['overdue', 'in_progress', 'upcoming', 'completed']
|
||||||
@@ -46,8 +45,7 @@ export default function HeatmapDayPanel({ date, onClose }) {
|
|||||||
const next = STATUS_CYCLE[deliverable.status] || 'upcoming'
|
const next = STATUS_CYCLE[deliverable.status] || 'upcoming'
|
||||||
setCycling(deliverable.id)
|
setCycling(deliverable.id)
|
||||||
try {
|
try {
|
||||||
const updated = await apiUpdate(deliverable.id, { status: next })
|
await storeUpdate(deliverable.id, { status: next })
|
||||||
storeUpdate(updated)
|
|
||||||
} finally {
|
} finally {
|
||||||
setCycling(null)
|
setCycling(null)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import dayGridPlugin from '@fullcalendar/daygrid'
|
|||||||
import timeGridPlugin from '@fullcalendar/timegrid'
|
import timeGridPlugin from '@fullcalendar/timegrid'
|
||||||
import interactionPlugin from '@fullcalendar/interaction'
|
import interactionPlugin from '@fullcalendar/interaction'
|
||||||
import useProjectStore from '../../store/useProjectStore'
|
import useProjectStore from '../../store/useProjectStore'
|
||||||
|
import useFocusStore from '../../store/useFocusStore'
|
||||||
|
import useUIStore from '../../store/useUIStore'
|
||||||
|
import useToastStore from '../../store/useToastStore'
|
||||||
import DeliverableModal from '../Deliverables/DeliverableModal'
|
import DeliverableModal from '../Deliverables/DeliverableModal'
|
||||||
import ContextMenu from '../UI/ContextMenu'
|
import ContextMenu from '../UI/ContextMenu'
|
||||||
import EventTooltip from './EventTooltip'
|
import EventTooltip from './EventTooltip'
|
||||||
@@ -66,6 +69,7 @@ export default function MainCalendar({ onCalendarReady }) {
|
|||||||
}, [openFocus])
|
}, [openFocus])
|
||||||
|
|
||||||
const handleEventDrop = useCallback(async ({ event, oldEvent }) => {
|
const handleEventDrop = useCallback(async ({ event, oldEvent }) => {
|
||||||
|
const { deliverableId } = event.extendedProps
|
||||||
const newDate = event.startStr.substring(0, 10)
|
const newDate = event.startStr.substring(0, 10)
|
||||||
const oldDate = oldEvent.startStr.substring(0, 10)
|
const oldDate = oldEvent.startStr.substring(0, 10)
|
||||||
await storeUpdate(deliverableId, { due_date: newDate })
|
await storeUpdate(deliverableId, { due_date: newDate })
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import Button from '../UI/Button'
|
|||||||
import AgendaPanel from '../Calendar/AgendaPanel'
|
import AgendaPanel from '../Calendar/AgendaPanel'
|
||||||
import useProjectStore from '../../store/useProjectStore'
|
import useProjectStore from '../../store/useProjectStore'
|
||||||
import useUIStore from '../../store/useUIStore'
|
import useUIStore from '../../store/useUIStore'
|
||||||
import { deleteProject, fetchProjects } from '../../api/projects'
|
|
||||||
|
|
||||||
const VIEW_OPTIONS = [
|
const VIEW_OPTIONS = [
|
||||||
{ key: 'active', label: 'Active' },
|
{ key: 'active', label: 'Active' },
|
||||||
@@ -14,7 +13,7 @@ const VIEW_OPTIONS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
export default function ProjectList({ onRegisterNewProject }) {
|
export default function ProjectList({ onRegisterNewProject }) {
|
||||||
const { projects, removeProject, setProjects } = useProjectStore()
|
const { projects, deleteProject, loadProjects } = useProjectStore()
|
||||||
const { sidebarTab, setSidebarTab } = useUIStore()
|
const { sidebarTab, setSidebarTab } = useUIStore()
|
||||||
const [showModal, setShowModal] = useState(false)
|
const [showModal, setShowModal] = useState(false)
|
||||||
const [editing, setEditing] = useState(null)
|
const [editing, setEditing] = useState(null)
|
||||||
@@ -26,15 +25,13 @@ export default function ProjectList({ onRegisterNewProject }) {
|
|||||||
}, [onRegisterNewProject])
|
}, [onRegisterNewProject])
|
||||||
|
|
||||||
const refreshProjects = async () => {
|
const refreshProjects = async () => {
|
||||||
const data = await fetchProjects()
|
await loadProjects()
|
||||||
setProjects(data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleEdit = (p) => { setEditing(p); setShowModal(true) }
|
const handleEdit = (p) => { setEditing(p); setShowModal(true) }
|
||||||
const handleDelete = async (p) => {
|
const handleDelete = async (p) => {
|
||||||
if (window.confirm(`Delete "${p.name}" and all its deliverables?`)) {
|
if (window.confirm(`Delete "${p.name}" and all its deliverables?`)) {
|
||||||
await deleteProject(p.id)
|
await deleteProject(p.id)
|
||||||
removeProject(p.id)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const handleClose = () => { setShowModal(false); setEditing(null) }
|
const handleClose = () => { setShowModal(false); setEditing(null) }
|
||||||
|
|||||||
Reference in New Issue
Block a user