Skip to content

Commit

Permalink
Implemented Add to Favorites
Browse files Browse the repository at this point in the history
Restructured the Database
Changed light theme background from White to Gray-200
  • Loading branch information
umairayub79 committed Oct 28, 2022
1 parent 929790d commit dbf0759
Show file tree
Hide file tree
Showing 16 changed files with 137 additions and 42 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ npm run electron:package:linux
- [x] Search
- [x] Search History
- [x] Copy to Clipboard
- [ ] Restructure Database
- [ ] Favorites
- [x] Restructure Database
- [x] Favorites
- [x] Dark Mode
- [ ] Virtual Keyboard

Expand Down
Binary file modified db/dev.db
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sayad-ganj",
"version": "0.1.3",
"version": "0.1.4",
"description": "Balochi Dictionary",
"private": true,
"main": "public/electron.js",
Expand Down
8 changes: 4 additions & 4 deletions public/electron.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ function createWindow() {
// IPC handlers

ipcMain.handle('findAll', async (event, arg) => {
const sql = `SELECT * FROM sayad WHERE full_word LIKE ? `;
const sql = `SELECT * FROM sayadganj WHERE full_word LIKE ? OR full_word_with_symbols LIKE ? `;
return new Promise(function (resolve, reject) {
database.all(sql, [`${arg}%`], function (err, result) {
database.all(sql, [`${arg}%`, `${arg}%`], function (err, result) {
if (err) {
console.log(err)
reject(err)
Expand All @@ -112,7 +112,7 @@ ipcMain.handle('findAll', async (event, arg) => {


ipcMain.handle('findOne', async (event, arg) => {
const sql = `SELECT * FROM sayad WHERE id = ? `;
const sql = `SELECT * FROM sayadganj WHERE id = ? `;
return new Promise(function (resolve, reject) {
database.all(sql, [arg], function (err, result) {
if (err) {
Expand All @@ -126,7 +126,7 @@ ipcMain.handle('findOne', async (event, arg) => {
});

ipcMain.handle('randomWord', async (event, arg) => {
const sql = "SELECT * FROM sayad ORDER BY RANDOM() LIMIT 1";
const sql = "SELECT * FROM sayadganj ORDER BY RANDOM() LIMIT 1";
return new Promise(function (resolve, reject) {
database.all(sql, [], function (err, result) {
if (err) {
Expand Down
4 changes: 3 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import History from './components/History/History';
import Navigation from './components/Navigation/Navigation';
import SearchResults from './components/Search/SearchResults';
import WordDetail from './components/WordDetail/WordDetail';
import Favorites from './components/Favorites/Favorites';

const App = () => {
const prefersDarkMode = window.matchMedia(
Expand Down Expand Up @@ -37,13 +38,14 @@ const App = () => {

return (
<div className='ُmin-h-screen relative'>
<div className='min-h-[calc(100vh-28px)] h-[calc(100vh-28px)] absolute top-0 bottom-0 right-0 border-l dark:border-gray-700 w-12'>
<div className='min-h-[calc(100vh-28px)] h-[calc(100vh-28px)] absolute top-0 bottom-0 right-0 border-l border-gray-300 dark:border-gray-700 w-12'>
<Navigation isDarkMode={isDarkMode} handleDarkMode={handleDarkMode} />
</div>
<div className='h-[calc(100vh-28px)] absolute top-0 bottom-0 left-0 right-12 overflow-auto'>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/history" element={<History />} />
<Route path="/favorites" element={<Favorites />} />
<Route path="/search/:query" element={<SearchResults />} />
<Route path="/word/:id" element={<WordDetail />} />
</Routes>
Expand Down
47 changes: 47 additions & 0 deletions src/components/Favorites/Favorites.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, { useState } from 'react'
import { useNavigate } from 'react-router-dom';
import { FiArrowLeft, FiTrash } from 'react-icons/fi';
import { HiChevronRight } from 'react-icons/hi';
import { deleteFavorite, deleteFavorites, getFavorites } from '../../util/localStorage';

const Favorites = () => {
const [favorites, setFavorites] = useState(getFavorites())
const navigate = useNavigate()

const ListItem = ({ word }) => {
return (
<div className='flex justify-between items-center mb-1 border-b border-gray-300 dark:border-gray-700'>
<div className='w-[90%] overflow-hidden'>
<h3>{word.full_word_with_symbols}</h3>
<p className='p-2 item mask'>{word.definition}</p>
</div>
<div className='flex-col'>
<FiTrash className='inline-flex w-10 h-10 mt-1 cursor-pointer self-center text-gray-600 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg p-1' onClick={() => { deleteFavorite(word.id); setFavorites(getFavorites()) }} />
<FiArrowLeft className='inline-flex w-10 h-10 mt-1 cursor-pointer self-center text-gray-600 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg p-1' onClick={() => { navigate(`/word/${word.id}`) }} />
</div>

</div>
)
}
return (
<div className='flex flex-col'>
<div className='sticky top-0 z-50 flex flex-row justify-between bg-blue-500 dark:bg-gray-800 text-white items-center'>
<div>
<HiChevronRight className='w-14 h-14 inline-flex self-center hover:cursor-pointer hover:text-gray-300' onClick={() => { navigate('/') }} />
</div>
<div>
<h2>درپینتگیں</h2>
</div>
<div className='ml-2'>
<FiTrash className='w-10 h-10 inline-flex self-center hover:cursor-pointer hover:text-gray-300' onClick={() => { deleteFavorites(); setFavorites(getFavorites()) }} />
</div>
</div>

<div className='flex flex-col p-5'>
{favorites.length > 0 ? favorites.map((item) => <ListItem key={item.id} word={item} />) : <h2 className='self-center text-center dark:text-gray-200'>چیزے پہ پیش کنگ ءَ دست نہ کَپت</h2>}
</div>
</div>
)
}

export default Favorites
6 changes: 3 additions & 3 deletions src/components/History/History.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const History = () => {

const ListItem = ({ text }) => {
return (
<div className='flex justify-between items-center mb-1 border-b border-gray-200 dark:border-gray-700'>
<div className='flex justify-between items-center mb-1 border-b border-gray-300 dark:border-gray-700'>
<h3>{text}</h3>
<FiArrowLeft className='inline-flex w-10 h-10 mt-1 cursor-pointer self-center text-gray-600 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg p-1' onClick={() => { navigate(`/search/${text}`) }} />
</div>
Expand All @@ -20,7 +20,7 @@ const History = () => {
<div className='flex flex-col'>
<div className='sticky top-0 z-50 flex flex-row justify-between bg-blue-500 dark:bg-gray-800 text-white items-center'>
<div>
<HiChevronRight className='w-14 h-14 inline-flex self-center hover:cursor-pointer hover:text-gray-300' onClick={() => { navigate(-1) }} />
<HiChevronRight className='w-14 h-14 inline-flex self-center hover:cursor-pointer hover:text-gray-300' onClick={() => { navigate('/') }} />
</div>
<div>
<h2>گوستانک</h2>
Expand All @@ -31,7 +31,7 @@ const History = () => {
</div>

<div className='flex flex-col p-5'>
{history.length > 0 ? history.map((item) => <ListItem key={item.id} text={item.query} />) : <h2 className='self-center text-center dark:text-gray-200'>چیزے پہ پیش کنگ ءَ زاھر نہ بیت</h2>}
{history.length > 0 ? history.map((item) => <ListItem key={item.id} text={item.query} />) : <h2 className='self-center text-center dark:text-gray-200'>چیزے پہ پیش کنگ ءَ دست نہ کَپت</h2>}
</div>
</div>
)
Expand Down
5 changes: 2 additions & 3 deletions src/components/Home/Searchbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,17 @@ const Searchbar = () => {
if (isNotEmpty()) {
addToHistory(word)
navigate(`/search/${word}`)
// navigate('/history')
}
}
return (
<div className='flex flex-col items-center justify-center'>
<form onSubmit={onFormSubmit} className="flex items-center text-gray-900 bg-gray-50 rounded-full border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
<form onSubmit={onFormSubmit} className="flex items-center text-gray-900 bg-gray-100 rounded-full border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
<input
onChange={({ target: { value } }) => setWord(value)}
value={word}
placeholder="لبزءِدرگیجگ ءَ اداں نبشتہ بہ کن اِت"
type="text"
className="text-xl leading-[3rem] p-2 text-gray-900 flex-grow focus:outline-none w-full bg-gray-50 rounded-full dark:bg-gray-700 dark:placeholder-gray-400 dark:text-white" />
className="text-xl leading-[3rem] p-2 text-gray-900 flex-grow focus:outline-none w-full bg-gray-100 rounded-full dark:bg-gray-700 dark:placeholder-gray-400 dark:text-white" />

<button type="submit" className="bg-gray-200 dark:bg-gray-500 text-blue-500 dark:text-gray-200 p-2 rounded-full ring-gray-400 hover:ring-1 focus:outline-none active:ring-gray-400 hover:shadow-md">
<HiSearch className='w-8 h-8' />
Expand Down
12 changes: 9 additions & 3 deletions src/components/Navigation/Navigation.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { HiHome, HiMoon, HiSun } from 'react-icons/hi'
import { MdHistory } from 'react-icons/md'
import { MdHistory, MdFavorite } from 'react-icons/md'
import React from 'react'
import { useNavigate, useLocation } from 'react-router-dom'
import cx from 'classnames'
Expand All @@ -11,12 +11,18 @@ const Navigation = ({ isDarkMode, handleDarkMode }) => {
<div className='h-full items-center text-center flex flex-col justify-between'>
<div className='mt-1'>
<HiHome className={cx('inline-flex w-10 h-10 mt-1 cursor-pointer self-center text-gray-600 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg p-1', {
'text-black dark:text-white bg-gray-200 dark:bg-gray-600 hover:bg-gray-300 dark:hover:bg-gray-500': location.pathname === "/"
'text-black dark:text-white bg-gray-300 dark:bg-gray-600 hover:bg-gray-300 dark:hover:bg-gray-500': location.pathname === "/"
})} onClick={() => { location.pathname !== "/" && navigate("/") }} />

<MdFavorite className={cx('inline-flex w-10 h-10 mt-1 cursor-pointer self-center text-gray-600 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg p-1', {
'text-black dark:text-white bg-gray-300 dark:bg-gray-600 hover:bg-gray-300 dark:hover:bg-gray-500': location.pathname === "/favorites"
})} onClick={() => { location.pathname !== "/favorites" && navigate("/favorites") }} />

<MdHistory className={cx('inline-flex w-10 h-10 mt-1 cursor-pointer self-center text-gray-600 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg p-1', {
'text-black dark:text-white bg-gray-200 dark:bg-gray-600 hover:bg-gray-300 dark:hover:bg-gray-500': location.pathname === "/history"
'text-black dark:text-white bg-gray-300 dark:bg-gray-600 hover:bg-gray-300 dark:hover:bg-gray-500': location.pathname === "/history"
})} onClick={() => { location.pathname !== "/history" && navigate("/history") }} />


</div>
<div className='mb-1'>
{isDarkMode ? <HiSun className='inline-flex w-10 h-10 cursor-pointer self-center text-gray-400 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg p-1' onClick={() => { handleDarkMode(false) }} />
Expand Down
3 changes: 3 additions & 0 deletions src/components/Search/SearchResults.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ const SearchResults = () => {
response.length > 0 ? (
<div>
<div className='overflow-auto'>
<div className='text-center text-2xl p-5 text-gray-800 dark:text-gray-200'>
<p>{response.length} رکارڈ دست کپتگ </p>
</div>
{response.map((word) => <Word key={word.id} word={word} />)}
</div>
</div>
Expand Down
8 changes: 4 additions & 4 deletions src/components/Table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const Table = ({ columns, data }) => {
return (
<div>
<table className='w-full table-auto border-collapse border'>
<thead class="border-b">
<thead className="border-b">
<tr>
{columns.map((header, key) => {
return (
Expand All @@ -17,9 +17,9 @@ export const Table = ({ columns, data }) => {
{data.map((val, key) => {
return (
<tr key={key} className="border-b">
<td class="text-sm text-gray-900 dark:text-gray-200 font-light px-4 py-2 border-r">{val.num}</td>
<td class="text-sm text-gray-900 dark:text-gray-200 font-light px-4 py-2 border-r">{val.short}</td>
<td class="text-sm text-gray-900 dark:text-gray-200 font-light px-4 py-2 border-r">{val.long}</td>
<td className="text-sm text-gray-900 dark:text-gray-200 font-light px-4 py-2 border-r">{val.num}</td>
<td className="text-sm text-gray-900 dark:text-gray-200 font-light px-4 py-2 border-r">{val.short}</td>
<td className="text-sm text-gray-900 dark:text-gray-200 font-light px-4 py-2 border-r">{val.long}</td>
</tr>
)
})}
Expand Down
10 changes: 5 additions & 5 deletions src/components/Word.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { useNavigate } from 'react-router-dom'
const Word = ({ word }) => {
const navigate = useNavigate()

function createMarkup() {
return { __html: `<div>${word.definition}</div>` }
}
return (
<div onClick={() => { navigate(`/word/${word.id}`) }} className='dark:bg-gray-800 cursor-pointer relative overflow-hidden items-center w-[600px] min-w-[400px] tracking-wider leading-10 m-2 p-4 max-w-sm rounded-lg border dark:text-gray-300 dark:border-gray-600 dark:hover:bg-gray-700 border-gray-200 shadow-md hover:bg-gray-100'>
<div className='item ' dangerouslySetInnerHTML={createMarkup()}></div>
<div onClick={() => { navigate(`/word/${word.id}`) }} className='bg-gray-100 dark:bg-gray-800 cursor-pointer relative overflow-hidden items-center w-[600px] min-w-[400px] tracking-wider leading-10 m-2 p-4 max-w-sm rounded-lg border dark:text-gray-300 dark:border-gray-600 dark:hover:bg-gray-700 border-gray-300 shadow-md hover:bg-gray-200'>
<div className='item mask '>
<h1>{word.full_word_with_symbols}</h1>
<p>{word.definition}</p>
</div>
</div>
)
}
Expand Down
25 changes: 13 additions & 12 deletions src/components/WordDetail/WordDetail.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { useState, useEffect } from 'react'
import { useParams, useNavigate } from 'react-router-dom';
import { HiChevronRight } from 'react-icons/hi';
import { MdContentCopy, MdInfoOutline } from 'react-icons/md';
import { MdContentCopy, MdFavorite, MdFavoriteBorder, MdInfoOutline } from 'react-icons/md';
import Skeleton from '../Skeleton';
import { InfoModal } from '../modals/InfoModal';
import { useToast } from '../../hooks/useToast'

import { addToFavorites, deleteFavorite, isInFavorites } from '../../util/localStorage'

const WordDetail = () => {
const showToast = useToast(1000)
Expand All @@ -14,6 +14,7 @@ const WordDetail = () => {
const [loading, setLoading] = useState(true)
const navigate = useNavigate()
const { id } = useParams()
const [isFavorite, setIsFavorite] = useState(isInFavorites(id))

async function findOne() {
setLoading(true)
Expand All @@ -26,13 +27,8 @@ const WordDetail = () => {
}, [id]);


function createMarkup(word) {
return { __html: `<div>${word.definition}</div>` }
}

function copyToClipboard() {
const definition = response.definition.replace(/[<h1></h1>]/g, "")
navigator.clipboard.writeText(definition)
navigator.clipboard.writeText(response.definition)
showToast('success', 'کاپی بوت')
}
return (
Expand All @@ -46,8 +42,10 @@ const WordDetail = () => {
</div>

<div className='ml-2'>
<MdContentCopy className='w-10 h-10 ml-1 inline-flex self-center hover:cursor-pointer hover:text-gray-300' onClick={() => { copyToClipboard() }} />
<MdInfoOutline className='w-10 h-10 inline-flex self-center hover:cursor-pointer hover:text-gray-300' onClick={() => { setIsOpen(true) }} />
{!isFavorite ? <MdFavoriteBorder className='w-10 h-10 ml-1 inline-flex self-center hover:cursor-pointer hover:text-gray-100' onClick={() => { addToFavorites(response); setIsFavorite(true) }} /> :
<MdFavorite className='w-10 h-10 ml-1 inline-flex self-center hover:cursor-pointer hover:text-gray-100' onClick={() => { deleteFavorite(id); setIsFavorite(false) }} />}
<MdContentCopy className='w-10 h-10 ml-1 inline-flex self-center hover:cursor-pointer hover:text-gray-100' onClick={() => { copyToClipboard() }} />
<MdInfoOutline className='w-10 h-10 inline-flex self-center hover:cursor-pointer hover:text-gray-100' onClick={() => { setIsOpen(true) }} />
</div>
</div>
<div className='ُflex flex-col items-center justify-center dark:text-gray-100'>
Expand All @@ -58,7 +56,10 @@ const WordDetail = () => {
</div>) : (
<div className='m-8'>
<div className='text-2xl leading-relaxed'>
<div dangerouslySetInnerHTML={createMarkup(response)}></div>
<div>
<h1>{response.full_word_with_symbols}</h1>
<p className='whitespace-pre-line'>{response.definition}</p>
</div>
</div>
</div>)
}
Expand All @@ -68,4 +69,4 @@ const WordDetail = () => {
</div>
)
}
export default WordDetail
export default WordDetail
3 changes: 2 additions & 1 deletion src/components/modals/BaseModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { RiCloseCircleLine } from 'react-icons/ri'

export const BaseModal = ({ title, children, isOpen, handleClose }) => {
let closeButtonRef = useRef(null)

return (
<Transition.Root
as={Fragment}
Expand All @@ -27,7 +28,7 @@ export const BaseModal = ({ title, children, isOpen, handleClose }) => {
leaveTo="opacity-0 translate-y-4 sm:translate-0 sm:scale-95">
<div className="w-full h-[calc(100vh-70px)] inline-block align-bottom bg-white rounded-lg text-left overflow-auto shadow-xl transform translate-all sm:align-middle sm:max-w-xl sm:w-full dark:bg-gray-800">
<div className="absolute sticky top-0 p-2 bg-white dark:bg-gray-800">
<RiCloseCircleLine ref={closeButtonRef} className="h-6 w-6 cursor-pointer dark:stroke-white" onClick={() => handleClose()} />
<RiCloseCircleLine className="h-6 w-6 cursor-pointer dark:stroke-white" onClick={() => handleClose()} />
</div>
<div className='p-2'>
<div className="text-center">
Expand Down
Loading

0 comments on commit dbf0759

Please sign in to comment.