diff --git a/frontend/src/components/ui/DataBar/AddButton.jsx b/frontend/src/components/ui/DataBar/AddButton.jsx index 4060d63..546e49d 100644 --- a/frontend/src/components/ui/DataBar/AddButton.jsx +++ b/frontend/src/components/ui/DataBar/AddButton.jsx @@ -5,10 +5,21 @@ const AddButton = ({onClick, label = 'Add New'}) => { return ( ); }; diff --git a/frontend/src/components/ui/DataBar/DataBar.jsx b/frontend/src/components/ui/DataBar/DataBar.jsx index 3ebcafe..1d69c09 100644 --- a/frontend/src/components/ui/DataBar/DataBar.jsx +++ b/frontend/src/components/ui/DataBar/DataBar.jsx @@ -91,14 +91,14 @@ const DataBar = ({ allTags={allTags} /> + {showAddButton && !isSelectionMode && ( + + )} + - - {showAddButton && !isSelectionMode && ( - - )} ); diff --git a/frontend/src/components/ui/DataBar/FilterMenu.jsx b/frontend/src/components/ui/DataBar/FilterMenu.jsx index b7e300d..63b3b37 100644 --- a/frontend/src/components/ui/DataBar/FilterMenu.jsx +++ b/frontend/src/components/ui/DataBar/FilterMenu.jsx @@ -1,97 +1,142 @@ -// FilterMenu.jsx -import { useState, useRef, useEffect } from 'react'; -import PropTypes from 'prop-types'; +import React, {useRef, useEffect} from 'react'; +import {Filter} from 'lucide-react'; -function FilterMenu({ filterType, setFilterType, filterValue, setFilterValue, allTags }) { - const [isOpen, setIsOpen] = useState(false); - const dropdownRef = useRef(null); +function FilterMenu({ + filterType, + setFilterType, + filterValue, + setFilterValue, + allTags +}) { + const [isOpen, setIsOpen] = React.useState(false); + const dropdownRef = useRef(null); - const options = [ - { value: 'none', label: 'No Filter' }, - { value: 'tag', label: 'Filter by Tag' }, - { value: 'date', label: 'Filter by Date' }, - ]; + const options = [ + {value: 'none', label: 'No Filter'}, + {value: 'tag', label: 'Filter by Tag'}, + {value: 'date', label: 'Filter by Date'} + ]; - useEffect(() => { - function handleClickOutside(event) { - if (dropdownRef.current && !dropdownRef.current.contains(event.target)) { - setIsOpen(false); - } - } - document.addEventListener('mousedown', handleClickOutside); - return () => document.removeEventListener('mousedown', handleClickOutside); - }, []); + useEffect(() => { + function handleClickOutside(event) { + if ( + dropdownRef.current && + !dropdownRef.current.contains(event.target) + ) { + setIsOpen(false); + } + } + document.addEventListener('mousedown', handleClickOutside); + return () => + document.removeEventListener('mousedown', handleClickOutside); + }, []); - return ( -
-
-
- + const hasActiveFilter = filterType !== 'none' && filterValue; + + return ( +
+ + + {isOpen && ( +
+
+ {options.map(option => ( + + ))} +
+ + {filterType === 'tag' && ( +
+ +
+ )} + + {filterType === 'date' && ( +
+ setFilterValue(e.target.value)} + className='w-full px-2 py-1.5 text-sm rounded-md + bg-gray-50 dark:bg-gray-700 + text-gray-700 dark:text-gray-300 + border border-gray-200 dark:border-gray-600 + focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500' + /> +
+ )} +
+ )}
- - {isOpen && ( -
-
- {options.map((option) => ( - - ))} -
-
- )} -
- - {filterType === 'tag' && ( - - )} - {filterType === 'date' && ( - setFilterValue(e.target.value)} - className="bg-gray-700 text-white py-2 px-4 rounded-md border border-gray-600 leading-tight focus:outline-none focus:bg-gray-600 focus:border-white cursor-pointer" - /> - )} -
- ); + ); } -FilterMenu.propTypes = { - filterType: PropTypes.string.isRequired, - setFilterType: PropTypes.func.isRequired, - filterValue: PropTypes.string.isRequired, - setFilterValue: PropTypes.func.isRequired, - allTags: PropTypes.arrayOf(PropTypes.string).isRequired, -}; - -export default FilterMenu; \ No newline at end of file +export default FilterMenu; diff --git a/frontend/src/components/ui/DataBar/SearchBar.jsx b/frontend/src/components/ui/DataBar/SearchBar.jsx index 1d9cc21..967f275 100644 --- a/frontend/src/components/ui/DataBar/SearchBar.jsx +++ b/frontend/src/components/ui/DataBar/SearchBar.jsx @@ -52,29 +52,47 @@ const SearchBar = ({ }; return ( -
- +
+
{activeSearch ? ( -
+
{activeSearch}
@@ -87,8 +105,9 @@ const SearchBar = ({ onFocus={() => setIsFocused(true)} onBlur={() => setIsFocused(false)} placeholder={placeholder} - className='w-full bg-transparent text-gray-900 dark:text-gray-100 - placeholder:text-gray-500 dark:placeholder:text-gray-400 + className='w-full bg-transparent + text-gray-900 dark:text-gray-100 + placeholder:text-gray-500 dark:placeholder:text-gray-400 focus:outline-none' /> )} @@ -97,8 +116,13 @@ const SearchBar = ({ {searchTerm && !activeSearch && ( )}
diff --git a/frontend/src/components/ui/DataBar/SortDropdown.jsx b/frontend/src/components/ui/DataBar/SortDropdown.jsx index 8edb30c..df9eb9f 100644 --- a/frontend/src/components/ui/DataBar/SortDropdown.jsx +++ b/frontend/src/components/ui/DataBar/SortDropdown.jsx @@ -1,6 +1,5 @@ import React from 'react'; -import PropTypes from 'prop-types'; -import {ArrowDown} from 'lucide-react'; +import {ArrowDownUp} from 'lucide-react'; export const SortDropdown = ({ options, @@ -23,20 +22,41 @@ export const SortDropdown = ({
+ {isOpen && ( -
+
{options.map(option => ( ); }; diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index 9f0c6d2..63e2c4e 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -26,12 +26,24 @@ module.exports = { opacity: '1', transform: 'translate3d(0, 0, 0)' } + }, + wiggle: { + '0%, 100%': {transform: 'rotate(0deg)'}, + '25%': {transform: 'rotate(-20deg)'}, + '75%': {transform: 'rotate(20deg)'} + }, + 'check-bounce': { + '0%, 100%': {transform: 'scale(1) rotate(0deg)'}, + '30%': {transform: 'scale(1.15) rotate(-10deg)'}, + '60%': {transform: 'scale(0.9) rotate(5deg)'} } }, animation: { 'modal-open': 'modal-open 0.3s ease-out forwards', 'fade-in': 'fade-in 0.5s ease-in-out forwards', - 'slide-down': 'slide-down 0.4s cubic-bezier(0.16, 1, 0.3, 1)' + 'slide-down': 'slide-down 0.4s cubic-bezier(0.16, 1, 0.3, 1)', + wiggle: 'wiggle 0.3s ease-in-out', + 'check-bounce': 'check-bounce 0.3s ease-in-out' }, colors: { 'dark-bg': '#1a1c23',