feat: Simplify home page and remove tracking form
- Remove complex tracking form from home page
- Replace with clean 'Analyze URL Redirects' call-to-action button
- Remove announcement badge '🚀 URL Tracker Tool V2 - Now Available'
- Clean up unused imports and form-related code
- Direct users to dedicated /track page for full functionality
- Improve user experience with cleaner, more focused home page
Changes:
- Simplified HomePage component with single CTA button
- Removed form validation, mutation handling, and result display
- Maintained all tracking functionality on /track page
- Professional appearance without promotional clutter
This commit is contained in:
373
apps/api/dist/routes/projects.routes.js
vendored
Normal file
373
apps/api/dist/routes/projects.routes.js
vendored
Normal file
@@ -0,0 +1,373 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const express_1 = __importDefault(require("express"));
|
||||
const zod_1 = require("zod");
|
||||
const auth_middleware_1 = require("../middleware/auth.middleware");
|
||||
const client_1 = require("@prisma/client");
|
||||
const logger_1 = require("../lib/logger");
|
||||
const router = express_1.default.Router();
|
||||
const prisma = new client_1.PrismaClient();
|
||||
const createProjectSchema = zod_1.z.object({
|
||||
name: zod_1.z.string().min(1, 'Project name is required').max(100, 'Project name too long'),
|
||||
description: zod_1.z.string().optional(),
|
||||
settings: zod_1.z.object({
|
||||
defaultMethod: zod_1.z.enum(['GET', 'POST', 'HEAD']).default('GET'),
|
||||
defaultTimeout: zod_1.z.number().min(1000).max(30000).default(15000),
|
||||
defaultMaxHops: zod_1.z.number().min(1).max(20).default(10),
|
||||
enableSSLAnalysis: zod_1.z.boolean().default(true),
|
||||
enableSEOAnalysis: zod_1.z.boolean().default(true),
|
||||
enableSecurityAnalysis: zod_1.z.boolean().default(true),
|
||||
}).optional(),
|
||||
});
|
||||
const updateProjectSchema = zod_1.z.object({
|
||||
name: zod_1.z.string().min(1).max(100).optional(),
|
||||
description: zod_1.z.string().optional(),
|
||||
settings: zod_1.z.object({
|
||||
defaultMethod: zod_1.z.enum(['GET', 'POST', 'HEAD']).optional(),
|
||||
defaultTimeout: zod_1.z.number().min(1000).max(30000).optional(),
|
||||
defaultMaxHops: zod_1.z.number().min(1).max(20).optional(),
|
||||
enableSSLAnalysis: zod_1.z.boolean().optional(),
|
||||
enableSEOAnalysis: zod_1.z.boolean().optional(),
|
||||
enableSecurityAnalysis: zod_1.z.boolean().optional(),
|
||||
}).optional(),
|
||||
});
|
||||
const projectParamsSchema = zod_1.z.object({
|
||||
projectId: zod_1.z.string().min(1),
|
||||
});
|
||||
router.get('/', auth_middleware_1.requireAuth, async (req, res) => {
|
||||
try {
|
||||
const user = req.user;
|
||||
const orgId = user.memberships[0]?.orgId;
|
||||
if (!orgId) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'No organization found',
|
||||
message: 'User must belong to an organization to access projects'
|
||||
});
|
||||
}
|
||||
const projects = await prisma.project.findMany({
|
||||
where: {
|
||||
orgId: orgId,
|
||||
},
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
checks: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'desc',
|
||||
},
|
||||
});
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
projects: projects.map(project => ({
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
description: project.settingsJson?.description || null,
|
||||
settings: project.settingsJson,
|
||||
trackingCount: project._count.checks,
|
||||
createdAt: project.createdAt,
|
||||
})),
|
||||
},
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
logger_1.logger.error('Failed to get projects:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to get projects',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
});
|
||||
}
|
||||
});
|
||||
router.post('/', auth_middleware_1.requireAuth, async (req, res) => {
|
||||
try {
|
||||
const user = req.user;
|
||||
const orgId = user.memberships[0]?.orgId;
|
||||
if (!orgId) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'No organization found',
|
||||
message: 'User must belong to an organization to create projects'
|
||||
});
|
||||
}
|
||||
const validatedData = createProjectSchema.parse(req.body);
|
||||
const project = await prisma.project.create({
|
||||
data: {
|
||||
name: validatedData.name,
|
||||
orgId: orgId,
|
||||
settingsJson: {
|
||||
description: validatedData.description || '',
|
||||
...validatedData.settings,
|
||||
},
|
||||
},
|
||||
});
|
||||
logger_1.logger.info(`Project created: ${project.id}`, {
|
||||
userId: user.id,
|
||||
orgId,
|
||||
projectName: project.name,
|
||||
});
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: {
|
||||
project: {
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
description: validatedData.description || null,
|
||||
settings: project.settingsJson,
|
||||
trackingCount: 0,
|
||||
createdAt: project.createdAt,
|
||||
},
|
||||
},
|
||||
message: 'Project created successfully',
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
logger_1.logger.error('Failed to create project:', error);
|
||||
if (error instanceof zod_1.z.ZodError) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Validation failed',
|
||||
details: error.errors,
|
||||
});
|
||||
}
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to create project',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
});
|
||||
}
|
||||
});
|
||||
router.get('/:projectId', auth_middleware_1.requireAuth, async (req, res) => {
|
||||
try {
|
||||
const user = req.user;
|
||||
const { projectId } = projectParamsSchema.parse(req.params);
|
||||
const orgId = user.memberships[0]?.orgId;
|
||||
if (!orgId) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'No organization found',
|
||||
});
|
||||
}
|
||||
const project = await prisma.project.findFirst({
|
||||
where: {
|
||||
id: projectId,
|
||||
orgId: orgId,
|
||||
},
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
checks: true,
|
||||
},
|
||||
},
|
||||
checks: {
|
||||
take: 10,
|
||||
orderBy: {
|
||||
startedAt: 'desc',
|
||||
},
|
||||
include: {
|
||||
hops: {
|
||||
select: {
|
||||
url: true,
|
||||
statusCode: true,
|
||||
redirectType: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!project) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'Project not found',
|
||||
message: 'Project does not exist or you do not have access to it',
|
||||
});
|
||||
}
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
project: {
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
description: project.settingsJson?.description || null,
|
||||
settings: project.settingsJson,
|
||||
trackingCount: project._count.checks,
|
||||
recentChecks: project.checks.map(check => ({
|
||||
id: check.id,
|
||||
inputUrl: check.inputUrl,
|
||||
finalUrl: check.finalUrl,
|
||||
status: check.status,
|
||||
startedAt: check.startedAt,
|
||||
hopCount: check.hops.length,
|
||||
})),
|
||||
createdAt: project.createdAt,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
logger_1.logger.error('Failed to get project:', error);
|
||||
if (error instanceof zod_1.z.ZodError) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid project ID',
|
||||
});
|
||||
}
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to get project',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
});
|
||||
}
|
||||
});
|
||||
router.put('/:projectId', auth_middleware_1.requireAuth, async (req, res) => {
|
||||
try {
|
||||
const user = req.user;
|
||||
const { projectId } = projectParamsSchema.parse(req.params);
|
||||
const orgId = user.memberships[0]?.orgId;
|
||||
if (!orgId) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'No organization found',
|
||||
});
|
||||
}
|
||||
const validatedData = updateProjectSchema.parse(req.body);
|
||||
const existingProject = await prisma.project.findFirst({
|
||||
where: {
|
||||
id: projectId,
|
||||
orgId: orgId,
|
||||
},
|
||||
});
|
||||
if (!existingProject) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'Project not found',
|
||||
message: 'Project does not exist or you do not have access to it',
|
||||
});
|
||||
}
|
||||
const currentSettings = existingProject.settingsJson || {};
|
||||
const project = await prisma.project.update({
|
||||
where: {
|
||||
id: projectId,
|
||||
},
|
||||
data: {
|
||||
...(validatedData.name && { name: validatedData.name }),
|
||||
settingsJson: {
|
||||
...currentSettings,
|
||||
...(validatedData.description !== undefined && { description: validatedData.description }),
|
||||
...validatedData.settings,
|
||||
},
|
||||
},
|
||||
});
|
||||
logger_1.logger.info(`Project updated: ${project.id}`, {
|
||||
userId: user.id,
|
||||
orgId,
|
||||
changes: validatedData,
|
||||
});
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
project: {
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
description: project.settingsJson?.description || null,
|
||||
settings: project.settingsJson,
|
||||
createdAt: project.createdAt,
|
||||
},
|
||||
},
|
||||
message: 'Project updated successfully',
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
logger_1.logger.error('Failed to update project:', error);
|
||||
if (error instanceof zod_1.z.ZodError) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Validation failed',
|
||||
details: error.errors,
|
||||
});
|
||||
}
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to update project',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
});
|
||||
}
|
||||
});
|
||||
router.delete('/:projectId', auth_middleware_1.requireAuth, async (req, res) => {
|
||||
try {
|
||||
const user = req.user;
|
||||
const { projectId } = projectParamsSchema.parse(req.params);
|
||||
const orgId = user.memberships[0]?.orgId;
|
||||
if (!orgId) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'No organization found',
|
||||
});
|
||||
}
|
||||
const existingProject = await prisma.project.findFirst({
|
||||
where: {
|
||||
id: projectId,
|
||||
orgId: orgId,
|
||||
},
|
||||
include: {
|
||||
_count: {
|
||||
select: {
|
||||
checks: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!existingProject) {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
error: 'Project not found',
|
||||
message: 'Project does not exist or you do not have access to it',
|
||||
});
|
||||
}
|
||||
if (existingProject._count.checks > 0) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Cannot delete project with tracking data',
|
||||
message: `This project has ${existingProject._count.checks} tracking records. Please archive or move the data first.`,
|
||||
});
|
||||
}
|
||||
await prisma.project.delete({
|
||||
where: {
|
||||
id: projectId,
|
||||
},
|
||||
});
|
||||
logger_1.logger.info(`Project deleted: ${projectId}`, {
|
||||
userId: user.id,
|
||||
orgId,
|
||||
projectName: existingProject.name,
|
||||
});
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Project deleted successfully',
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
logger_1.logger.error('Failed to delete project:', error);
|
||||
if (error instanceof zod_1.z.ZodError) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
error: 'Invalid project ID',
|
||||
});
|
||||
}
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: 'Failed to delete project',
|
||||
message: error instanceof Error ? error.message : 'Unknown error',
|
||||
});
|
||||
}
|
||||
});
|
||||
exports.default = router;
|
||||
//# sourceMappingURL=projects.routes.js.map
|
||||
Reference in New Issue
Block a user