Skip to content

feat: add history and favourites system#38

Merged
djleamen merged 2 commits into
mainfrom
djleamen-feat-history-and-favourites
Jun 30, 2026
Merged

feat: add history and favourites system#38
djleamen merged 2 commits into
mainfrom
djleamen-feat-history-and-favourites

Conversation

@djleamen

Copy link
Copy Markdown
Owner

Closes #9

Summary

Implements a history and favourites system for Modelcules, persisted to localStorage.

What's new

Auto-save History

Every successful molecule lookup is automatically saved to a browsing history (capped at 50 entries). Duplicate molecules (matched by SMILES / InChI / CAS Number) are moved to the top instead of duplicated.

Favourites

Users can star any loaded molecule to save it to a persistent favourites list. Stars can be toggled from the Search tab header or directly from the History/Favourites list.

Tabbed Panel UI

The existing dropdown panel now has three tabs:

  • Search — the existing identifier form, now with a ⭐ star button in the header when a molecule is loaded
  • History — chronological list of past lookups with timestamps
  • Favourites — bookmarked molecules

Each list entry has:

  • A restore button to reload that molecule into the viewer
  • A star button to toggle favourites
  • A × remove button (visible on hover) to delete from the list
  • A Clear all button for bulk removal

Files changed

File Change
src/types/molecule.ts Added MoleculeEntry interface
src/utils/storage.ts New — localStorage helpers + display name logic
src/hooks/useMoleculeHistory.ts New — history state management hook
src/hooks/useFavourites.ts New — favourites state management hook
src/components/HistoryFavouritesPanel.tsx New — shared list UI for history and favourites
src/App.tsx Tab state, hook wiring, save history on successful lookup
src/components/InputForm.tsx Favourite star button in header

- Add MoleculeEntry type to src/types/molecule.ts
- Create src/utils/storage.ts with localStorage helpers and display name logic
- Create src/hooks/useMoleculeHistory.ts (max 50 entries, deduplication, addEntry/removeEntry/clearHistory)
- Create src/hooks/useFavourites.ts (toggleFavourite, isFavourite, clearFavourites)
- Create src/components/HistoryFavouritesPanel.tsx with restore, star, and remove actions
- Update App.tsx: tabbed panel (Search / History / Favourites), wire hooks, save history on successful lookup
- Update InputForm.tsx: favourite star button in header when molecule is loaded

Resolves #9

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 30, 2026 19:10
@github-actions

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a persistent “History” and “Favourites” feature to Modelcules by storing molecule entries in localStorage and exposing them via new React hooks and a tabbed dropdown panel UI.

Changes:

  • Introduces MoleculeEntry plus localStorage helpers for history/favourites persistence.
  • Adds useMoleculeHistory and useFavourites hooks to manage entry lists and toggling logic.
  • Updates the dropdown panel to a 3-tab UI (Search/History/Favourites) and adds star controls in the Search header and list items.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/types/molecule.ts Adds MoleculeEntry to represent persisted history/favourite items.
src/utils/storage.ts Adds localStorage load/save helpers plus display-name and key derivation utilities.
src/hooks/useMoleculeHistory.ts New hook for capped, de-duplicated history list persisted to storage.
src/hooks/useFavourites.ts New hook for favourites persistence and toggle logic.
src/components/HistoryFavouritesPanel.tsx New shared list UI for history/favourites entries with restore/star/remove actions.
src/App.tsx Wires hooks into the main app, adds tabbed panel UI, and saves successful lookups to history.
src/components/InputForm.tsx Adds a header star button to toggle favourites from the Search tab.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +17 to +35
const toggleFavourite = useCallback((identifiers: ChemicalIdentifiers) => {
const key = getMoleculeKey(identifiers);
setFavourites(prev => {
let next: MoleculeEntry[];
if (key && prev.some(e => getMoleculeKey(e.identifiers) === key)) {
next = prev.filter(e => getMoleculeKey(e.identifiers) !== key);
} else {
const entry: MoleculeEntry = {
id: key || crypto.randomUUID(),
displayName: getDisplayName(identifiers),
identifiers,
timestamp: Date.now(),
};
next = [entry, ...prev];
}
saveFavourites(next);
return next;
});
}, []);
Comment thread src/App.tsx
Comment on lines +245 to +247
isFavourite={isFavourite(identifiers)}
onToggleFavourite={() => toggleFavourite(identifiers)}
/>
Comment thread src/components/InputForm.tsx
Comment thread src/components/HistoryFavouritesPanel.tsx
Comment on lines +86 to +90
<button
onClick={() => onRemove(entry.id)}
className="flex-shrink-0 p-0.5 text-gray-300 hover:text-red-400 transition-colors opacity-0 group-hover:opacity-100"
title="Remove"
>
- useFavourites: guard toggleFavourite against empty key to prevent unstable favourites
- App.tsx: only pass onToggleFavourite when a stable key exists and not loading
- InputForm.tsx: add aria-label to favourite star button
- HistoryFavouritesPanel.tsx: add aria-label to star and remove buttons; make remove visible on keyboard focus

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@djleamen
djleamen merged commit 635a804 into main Jun 30, 2026
4 of 7 checks passed
@djleamen
djleamen deleted the djleamen-feat-history-and-favourites branch June 30, 2026 19:24
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
B Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

history or favourites system

2 participants