← back to Designerrepresentatives
routes/public.js
109 lines
const express = require('express');
const router = express.Router();
const { pool } = require('../lib/db');
const { sortReps, SORTS } = require('../lib/sort');
const SITE_TITLE = 'Designer Representatives';
const META_DESC = 'Designer Representatives — the canonical directory of independent sales reps serving interior designers, showrooms, contract specifiers, and the trade. Filter by territory, line, and vertical.';
router.use((req, res, next) => {
res.locals.site_title = SITE_TITLE;
res.locals.meta_desc = META_DESC;
res.locals.canonical = `https://designerrepresentatives.com${req.path}`;
res.locals.path = req.path;
next();
});
async function fetchReps(filter) {
const where = ['is_published = TRUE'];
const args = [];
if (filter && filter.territory) {
args.push(filter.territory.toUpperCase());
where.push(`$${args.length} = ANY(territories)`);
}
if (filter && filter.vertical) {
args.push(filter.vertical);
where.push(`$${args.length} = ANY(vertical)`);
}
if (filter && filter.q) {
args.push(`%${filter.q.toLowerCase()}%`);
where.push(
`(LOWER(name) LIKE $${args.length} OR LOWER(agency) LIKE $${args.length} OR LOWER(city) LIKE $${args.length})`
);
}
const { rows } = await pool.query(
`SELECT id, slug, name, agency, city, territories, lines, vertical, contact_url
FROM designer_reps
WHERE ${where.join(' AND ')}
ORDER BY id DESC
LIMIT 500`,
args
);
return rows;
}
router.get('/', async (req, res, next) => {
try {
const reps = await fetchReps({});
const sortKey = SORTS[req.query.sort] ? req.query.sort : 'newest';
res.render('public/home', {
title: 'Designer Representatives — Sales Reps for Designers, Showrooms, and Contract Specifiers',
reps: sortReps(reps, sortKey),
total: reps.length,
filter: {},
sortKey,
});
} catch (e) { next(e); }
});
router.get('/reps', async (req, res, next) => {
try {
const filter = {
territory: req.query.territory,
vertical: req.query.vertical,
q: req.query.q,
};
const reps = await fetchReps(filter);
const sortKey = SORTS[req.query.sort] ? req.query.sort : 'newest';
res.render('public/reps', {
title: 'Browse Sales Reps — Designer Representatives',
reps: sortReps(reps, sortKey),
total: reps.length,
filter,
sortKey,
});
} catch (e) { next(e); }
});
router.get('/reps/:slug', async (req, res, next) => {
try {
const { rows } = await pool.query(
`SELECT * FROM designer_reps WHERE slug = $1 AND is_published = TRUE LIMIT 1`,
[req.params.slug]
);
if (!rows.length) return res.status(404).render('public/404', { title: 'Not found' });
const rep = rows[0];
res.render('public/rep', {
title: `${rep.agency} — ${rep.name} | Designer Representatives`,
rep,
});
} catch (e) { next(e); }
});
router.get('/about', (req, res) => {
res.render('public/about', {
title: 'About — Designer Representatives',
});
});
router.get('/claim', (req, res) => {
res.render('public/claim', {
title: 'Claim or list your rep agency — Designer Representatives',
});
});
router.get('/healthz', (req, res) => res.type('text').send('ok'));
module.exports = router;