Refactor backend and frontend code for improved structure and functionality#29
Refactor backend and frontend code for improved structure and functionality#29Davictory2003 wants to merge 5 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors the cheat sheet creation flow by extracting frontend state/logic into reusable hooks and simplifying the main component, while also restructuring backend CRUD endpoints into DRF ViewSets and updating the Docker setup to use MySQL.
Changes:
- Frontend: extracted LaTeX compilation/download logic and formula selection logic into
useLatex/useFormulas, and splitCreateCheatSheetinto smaller subcomponents. - Backend: moved LaTeX-building helpers into
latex_utils.pyand replaced function-based CRUD endpoints with DRFModelViewSets + router URLs. - Ops: switched docker-compose DB image to MySQL 8.0 and added
migrateto backend container startup.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/hooks/latex.js | New hook encapsulating LaTeX title/content state + compile/generate/download actions. |
| frontend/src/hooks/formulas.js | New hook encapsulating class/category selection state and selected-formula extraction. |
| frontend/src/components/CreateCheatSheet.jsx | Refactored UI to use hooks and extracted subcomponents (selection/editor/preview/actions). |
| backend/api/latex_utils.py | New module for LaTeX document generation + (unused) PDF compilation helper. |
| backend/api/views.py | Uses shared LaTeX helpers; replaces CRUD function views with ViewSets + custom action. |
| backend/api/urls.py | Switches CRUD routing to a DRF DefaultRouter while keeping existing custom endpoints. |
| backend/Dockerfile | Adds python manage.py migrate to container startup command. |
| docker-compose.yml | Switches DB image to mysql:8.0 and renames the data volume. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export function useLatex(initialData) { | ||
| const [title, setTitle] = useState(initialData ? initialData.title : ''); | ||
| const [content, setContent] = useState(initialData ? initialData.content : ''); | ||
| const [pdfBlob, setPdfBlob] = useState(null); | ||
| const [isLoading, setIsLoading] = useState(false); | ||
| const [isCompiling, setIsCompiling] = useState(false); | ||
| const [isGenerating, setIsGenerating] = useState(false); | ||
|
|
||
| const isCompilingRef = useRef(false); | ||
| const isGeneratingRef = useRef(false); | ||
|
|
||
| useEffect(() => { | ||
| if (initialData) { | ||
| if (initialData.title) setTitle(initialData.title); | ||
| if (initialData.content) setContent(initialData.content); | ||
| } | ||
| }, [initialData]); |
There was a problem hiding this comment.
The initial state and the initialData sync effect use truthy checks (and direct property access) for title/content. If initialData is provided but missing fields (or fields are intentionally empty strings), this can set state to undefined or fail to sync to an empty value, causing controlled/uncontrolled input issues. Prefer nullish coalescing defaults (e.g., initialData?.title ?? '') and always assign the incoming value when initialData changes.
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Applied in commit 614a6c0. Changes made to frontend/src/hooks/latex.js:
- Initial state now uses
initialData?.title ?? ''andinitialData?.content ?? ''to safely handle missing fields and intentionally empty strings. - The
useEffectsync now unconditionally callssetTitle(initialData.title ?? '')andsetContent(initialData.content ?? '')wheneverinitialDatais provided, instead of gating on truthiness.
| try { | ||
| const response = await fetch('/api/compile/', { | ||
| method: 'POST', | ||
| headers: { 'Content-Type': 'application/json' }, | ||
| body: JSON.stringify({ content: contentToCompile }), | ||
| }); | ||
| if (!response.ok) throw new Error('Failed to compile LaTeX'); | ||
| const blob = await response.blob(); | ||
| setPdfBlob(URL.createObjectURL(blob)); |
There was a problem hiding this comment.
handlePreview creates a new object URL for each compiled PDF but never revokes the previous preview URL. Over time this can leak memory/blobs in the browser, especially if the user recompiles frequently. Track the previous URL and call URL.revokeObjectURL when replacing it and when unmounting/clearing.
There was a problem hiding this comment.
@copilot apply changes based on this feedback
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ils.py Agent-Logs-Url: https://github.com/ChicoState/cheat-sheet/sessions/16bd71ed-0f67-4e75-a0ef-92e4e62414ea Co-authored-by: Davictory2003 <68972845+Davictory2003@users.noreply.github.com>
No description provided.