feat: visual polish, nav login link, pricing badge fix, cursor fix, button contrast
- Hero mockup: enhanced 3D perspective and shadow - Testimonials: illustrated SVG avatars - Growth pricing card: visual prominence (scale, gradient, badge) - Most Popular badge: repositioned to avoid overlapping heading - Nav: added Log In link next to Start Free Trial - Fixed btn-primary text colour on anchor tags (white on blue) - Fixed cursor: default on all non-interactive elements - Disabled user-select on non-form content to prevent text caret
This commit is contained in:
101
init-db.js.bak
Executable file
101
init-db.js.bak
Executable file
@@ -0,0 +1,101 @@
|
||||
import pg from 'pg';
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config();
|
||||
|
||||
async function setupDatabase() {
|
||||
try {
|
||||
// First connect as postgres to create tables
|
||||
const adminClient = new pg.Client({
|
||||
host: 'localhost',
|
||||
port: 5432,
|
||||
database: 'tenderpilot',
|
||||
user: 'tenderpilot',
|
||||
password: 'tenderpilot123'
|
||||
});
|
||||
|
||||
await adminClient.connect();
|
||||
console.log('Connected to tenderpilot database');
|
||||
|
||||
// Create tables
|
||||
await adminClient.query(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
company_name VARCHAR(255),
|
||||
tier VARCHAR(50) DEFAULT 'free',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
verified BOOLEAN DEFAULT false
|
||||
);
|
||||
`);
|
||||
console.log('Created users table');
|
||||
|
||||
await adminClient.query(`
|
||||
CREATE TABLE IF NOT EXISTS tenders (
|
||||
id SERIAL PRIMARY KEY,
|
||||
source VARCHAR(100) NOT NULL,
|
||||
source_id VARCHAR(255) UNIQUE NOT NULL,
|
||||
title VARCHAR(500) NOT NULL,
|
||||
description TEXT,
|
||||
summary TEXT,
|
||||
cpv_codes TEXT[],
|
||||
value_low DECIMAL(15,2),
|
||||
value_high DECIMAL(15,2),
|
||||
currency VARCHAR(3) DEFAULT 'GBP',
|
||||
published_date TIMESTAMP,
|
||||
deadline TIMESTAMP,
|
||||
authority_name VARCHAR(255),
|
||||
authority_type VARCHAR(100),
|
||||
location VARCHAR(255),
|
||||
documents_url TEXT,
|
||||
notice_url TEXT,
|
||||
status VARCHAR(50) DEFAULT 'open',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
`);
|
||||
console.log('Created tenders table');
|
||||
|
||||
await adminClient.query(`
|
||||
CREATE TABLE IF NOT EXISTS profiles (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER UNIQUE REFERENCES users(id) ON DELETE CASCADE,
|
||||
sectors TEXT[],
|
||||
keywords TEXT[],
|
||||
min_value DECIMAL(15,2),
|
||||
max_value DECIMAL(15,2),
|
||||
locations TEXT[],
|
||||
authority_types TEXT[],
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
`);
|
||||
console.log('Created profiles table');
|
||||
|
||||
await adminClient.query(`
|
||||
CREATE TABLE IF NOT EXISTS matches (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
||||
tender_id INTEGER REFERENCES tenders(id) ON DELETE CASCADE,
|
||||
sent BOOLEAN DEFAULT false,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(user_id, tender_id)
|
||||
);
|
||||
`);
|
||||
console.log('Created matches table');
|
||||
|
||||
// Create indexes
|
||||
await adminClient.query('CREATE INDEX IF NOT EXISTS idx_tenders_source_id ON tenders(source_id);');
|
||||
await adminClient.query('CREATE INDEX IF NOT EXISTS idx_tenders_deadline ON tenders(deadline);');
|
||||
await adminClient.query('CREATE INDEX IF NOT EXISTS idx_matches_user_id ON matches(user_id);');
|
||||
console.log('Created indexes');
|
||||
|
||||
await adminClient.end();
|
||||
console.log('Database setup complete!');
|
||||
} catch (error) {
|
||||
console.error('Error setting up database:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
setupDatabase();
|
||||
Reference in New Issue
Block a user