Skip to content

Commit

Permalink
refactor db.getPhotos() to use knex.modify()
Browse files Browse the repository at this point in the history
  • Loading branch information
adamshand committed Jul 17, 2022
1 parent 9efe984 commit cf1363b
Show file tree
Hide file tree
Showing 12 changed files with 257 additions and 37 deletions.
2 changes: 2 additions & 0 deletions client/components/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Routes, Route, NavLink } from 'react-router-dom'
import ByTag from './ByTag.jsx'
import ByGroup from './ByGroup.jsx'
import LightBox from './LightBox.jsx'
import Edit from './Edit.jsx'
import Sort from './Sort.jsx'
import NotFound from './NotFound.jsx'

Expand All @@ -26,6 +27,7 @@ function App() {
<Route path="/tag/:tag" element={<ByTag />} />
<Route path="/group/:group" element={<ByGroup />} />
<Route path="/photo/:id" element={<LightBox />} />
<Route path="/edit/:id" element={<Edit />} />
<Route path="*" element={<NotFound />} />
</Routes>
</main>
Expand Down
1 change: 0 additions & 1 deletion client/components/ByGroup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ function ByGroup() {

return (
<section className="byGroup">
{console.log(groups[group])}
{groups[group]?.map((tag, i) => (
<figure key={i}>
{/* <Thumbnail photo={randomPhotoByGroupTag(`${group}/${tag}`)} /> */}
Expand Down
5 changes: 3 additions & 2 deletions client/components/ByTag.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react'
import { useParams, Link } from 'react-router-dom'
import { useParams } from 'react-router-dom'
import { useSelector } from 'react-redux'

import request from 'superagent'
Expand All @@ -11,7 +11,7 @@ function ByTag() {
const { tag } = useParams()
const [{ loading, failed, message, photos }, setPhotos] = useState({
loading: true,
photos: {},
photos: '',
})

const { order } = useSelector((state) => state.sort)
Expand Down Expand Up @@ -42,6 +42,7 @@ function ByTag() {

return (
<section className="byTag">
{console.log(photos[tag])}
{photos[tag]?.map((photo, i) => (
<figure key={i}>
<Thumbnail photo={photo} />
Expand Down
82 changes: 82 additions & 0 deletions client/components/Edit.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, { useState, useEffect } from 'react'
import { useParams } from 'react-router-dom'

import request from 'superagent'

function Edit() {
const { id } = useParams()
const [{ loading, photo }, setPhoto] = useState({
loading: true,
photos: {},
})

function handleChange(e) {}

useEffect(() => {
setPhoto({ loading: true })
return request
.get(`/api/v1/photos/${id}`)
.then((res) => {
setPhoto({ loading: false, photo: res.body })
})
.catch((err) => {
setPhoto({ failed: true, message: err.message })
})
}, [id])

if (loading) {
return <p>Loading...</p>
}

return (
<section className="edit">
<figure>
<img src={`/images/${photo.id}.jpeg`} alt={photo.title} />
</figure>

{/* https://react-hook-form.com/get-started */}

<form>
<h2>Edit Details</h2>
<input onChange={handleChange} type="date" value={photo.date} />
<textarea
onChange={handleChange}
rows="3"
columns="50"
value={photo.title}
/>
<h2>Add Tags</h2>
<div className="selects">
<select onChange={handleChange} value="name">
<option value="name/adam">name/adam</option>
<option value="name/adam">name/tink</option>
</select>
<select onChange={handleChange} value="species">
<option value="name/adam">species/cat</option>
<option value="name/adam">species/dog</option>
</select>
<select onChange={handleChange} value="contains">
<option value="">with/beach</option>
<option value="">with/teeth</option>
</select>
</div>
<h2>Delete Tags</h2>
<p>
{photo.tags.split(' ').map((tag, i) => (
<button key={i}>
{tag}{' '}
<img
style={{ width: '16px', height: '16px' }}
alt="delete icon"
src="/icon-delete.png"
/>
</button>
))}
</p>
<button>Update database</button>
</form>
</section>
)
}

export default Edit
3 changes: 3 additions & 0 deletions client/components/LightBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ function Photo() {

return (
<figure className="photo">
<a href={`/edit/${photo.id}`}>
<img alt="edit icon" src="/edit.png" />
</a>
<img src={`/images/${photo.id}.jpeg`} alt={photo.title} />
<FigCaption tags={photo.tags} />
</figure>
Expand Down
6 changes: 5 additions & 1 deletion client/components/NotFound.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import React from 'react'
function NotFound() {
return (
<section className="notFound">
<img className="notFound" alt="404 Error, page not found" src="404.jpg" />
<img
className="notFound"
alt="404 Error, page not found"
src="/404.jpg"
/>
</section>
)
}
Expand Down
98 changes: 68 additions & 30 deletions server/db/db.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,34 @@
const config = require('./knexfile').development
const connection = require('knex')(config)

function getPhotos(limit, search, sort = 'random', db = connection) {
let sortRaw
switch (sort) {
case 'views':
sortRaw = 'views desc'
break
case 'date':
sortRaw = 'date desc'
break
case 'rdate':
sortRaw = 'date asc'
break
default:
sortRaw = 'random()'
break
}

return db('photos').modify((query) => {
search &&
query
.where('tags', 'like', `%${search}%`)
.orWhere('title', 'like', `%${search}%`)
limit && query.limit(limit)
sort && query.orderByRaw(sortRaw)
return query
})
}

function incrementPhotoCounter(id, db = connection) {
return db('photos').where('id', id).increment('views', 1)
}
Expand Down Expand Up @@ -35,6 +63,7 @@ function getGroupTags(group, db = connection) {
})
}

// limit, search, sort, tag
function getPhotosByTag(tag, sort = 'random', limit = 9999, db = connection) {
switch (sort) {
case 'views':
Expand All @@ -60,36 +89,6 @@ function getPhotosByTag(tag, sort = 'random', limit = 9999, db = connection) {
}
}

function getPhotos(
sort = 'random',
limit = 9999,
filter = '/', // all tags contain '/'
db = connection
) {
switch (sort) {
case 'views':
return db('photos')
.where('tags', 'like', `%${filter}%`)
.orderBy('views', 'desc')
.limit(limit)
case 'date':
return db('photos')
.where('tags', 'like', `%${filter}%`)
.orderBy('date', 'desc')
.limit(limit)
case 'rdate':
return db('photos')
.where('tags', 'like', `%${filter}%`)
.orderBy('date', 'asc')
.limit(limit)
default:
return db('photos')
.where('tags', 'like', `%${filter}%`)
.orderByRaw('random()')
.limit(limit)
}
}

module.exports = {
incrementPhotoCounter,
getPhoto,
Expand All @@ -98,3 +97,42 @@ module.exports = {
getGroupTags,
getRandomPhotoByTag,
}

// deprecating for the moment and using getPhotos with .orWhere()
// function searchPhotos(s, db = connection) {
// return db('photos').where('title', s).orWhere('tags', s)
// }

// function getPhotos(
// sort = 'random',
// limit = 9999,
// filter = '/', // all tags contain '/'
// db = connection
// ) {
// switch (sort) {
// case 'views':
// return db('photos')
// .where('tags', `%${filter}%`)
// .orWhere('title', `%${filter}%`)
// .orderBy('views', 'desc')
// .limit(limit)
// case 'date':
// return db('photos')
// .where('tags', `%${filter}%`)
// .orWhere('title', `%${filter}%`)
// .orderBy('date', 'desc')
// .limit(limit)
// case 'rdate':
// return db('photos')
// .where('tags', `%${filter}%`)
// .orWhere('title', `%${filter}%`)
// .orderBy('date', 'asc')
// .limit(limit)
// default:
// return db('photos')
// .where('tags', `%${filter}%`)
// .orWhere('title', `%${filter}%`)
// .orderByRaw('random()')
// .limit(limit)
// }
// }
Binary file added server/public/404.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added server/public/icon-delete.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added server/public/icon-edit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 59 additions & 0 deletions server/public/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,65 @@ figure.photo > figcaption {
width: calc(78vw - 10px);
font-size: 3rem;
}
figure.photo a > img {
position: absolute;
/* border: 1px solid red; */
width: 31px;
height: 31px;
bottom: 5px;
right: 0px;
}

/*** <Edit /> ***/
section.edit {
display: flex;
/* grid-auto-flow: column; */
flex-direction: row;
flex-wrap: wrap;
}
section.edit figure {
width: 512px;
border: 2px solid var(--accent);
}
section.edit form {
width: 512px;
margin: 1rem;
}
section.edit form * {
width: 100%;
padding: 1rem;
margin-bottom: 2rem;
border: 1px solid var(--accent);
background-color: var(--dark);
color: var(--accent);
font-size: 1.5rem;
text-align: center;
}
section.edit form h2 {
margin: 0;
border: 0;
font-size: 3rem;
color: var(--hover);
}
section.edit form textarea {
text-align: left;
}
section.edit form input {
}
section.edit div.selects {
display: flex;
flex-direction: row;
justify-content: space-between;
border: 1px solid salmon;
}
section.edit form select {
border: 1px solid teal;
text-align: left;
}
section.edit form button {
background-color: var(--accent);
color: var(--dark);
}

/*** <NavLink /> ***/
span.currentTag {
Expand Down
38 changes: 35 additions & 3 deletions server/routes/photos.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const express = require('express')
const router = express.Router()
const { check, validationResult } = require('express-validator')
// const { check, validationResult } = require('express-validator')

const path = require('path')

Expand All @@ -9,8 +9,10 @@ const db = require('../db/db')
// Base API Route: /api/v1

router.get('/photos', (req, res) => {
const { sort, limit, filter } = req.query
db.getPhotos(sort, limit, filter)
// const { limit, search, sort, tag } = req.query
const { limit, search, sort } = req.query
// db.getPhotos(limit, search, sort, tag)
db.getPhotos(limit, search, sort)
.then((data) => {
res.json(data)
})
Expand Down Expand Up @@ -86,3 +88,33 @@ router.get('/ping(/:msg)?', (req, res) => {
})

module.exports = router

// router.get('/searches', (req, res) => {
// possible restful endpoint fo saved searches
// })

// still messing with endpoints
//
// /groups all groups
// /tags/:group all tags with :group (or /groups/:group)
// /photos all photos
// /photos?tag=:tag all photos with tag xxx
// /photos?limit=3 first three photos
// /photos?sort=random orders photos randomly
// /photos?search=:str all photos with tag or title containing :str
// /photos/:id photo with :id

// /garages
// Returns list of garages (think JSON array here)
// /garages/yyy
// Returns specific garage
// /garage/yyy/cars
// Returns list of cars in garage
// /garages/cars
// Returns list of all cars in all garages (may not be practical of course)
// /cars
// Returns list of all cars
// /cars/xxx
// Returns specific car
// /cars/colors
// Returns lists of all posible colors for cars

0 comments on commit cf1363b

Please sign in to comment.