backup
This commit is contained in:
parent
02f97c8dfa
commit
06ffc05e2b
@ -4,10 +4,11 @@
|
||||
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
|
||||
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
|
||||
|
||||
DATABASE_URL="postgresql://root:admin@localhost:5432/imk?schema=public"
|
||||
DATABASE_URL="postgresql://root:irina76@localhost:5432/imk?schema=public"
|
||||
JWT_SECRET=some-secret
|
||||
AWS_REGION=EU2
|
||||
AWS_ACCESS_KEY_ID=4d2f5655369a02100375e3247d7e1fe6
|
||||
AWS_SECRET_ACCESS_KEY=6d4723e14c0d799b89948c24dbe983e4
|
||||
AWS_S3_BUCKET_NAME=imk-data
|
||||
AWS_ENDPOINT_URL=https://eu2.contabostorage.com
|
||||
|
||||
|
||||
82
backend/imk-backend/prisma/seed.js
Normal file
82
backend/imk-backend/prisma/seed.js
Normal file
@ -0,0 +1,82 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
||||
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var client_1 = require("@prisma/client");
|
||||
var bcrypt = require("bcrypt");
|
||||
var prisma = new client_1.PrismaClient();
|
||||
function main() {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var hashedPassword, admin;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, bcrypt.hash('admin123', 10)];
|
||||
case 1:
|
||||
hashedPassword = _a.sent();
|
||||
return [4 /*yield*/, prisma.user.upsert({
|
||||
where: { email: 'admin@example.com' },
|
||||
update: {},
|
||||
create: {
|
||||
email: 'admin@example.com',
|
||||
name: 'Admin User',
|
||||
password: hashedPassword,
|
||||
isAdmin: true,
|
||||
},
|
||||
})];
|
||||
case 2:
|
||||
admin = _a.sent();
|
||||
console.log({ admin: admin });
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
main()
|
||||
.catch(function (e) {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, prisma.$disconnect()];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
@ -1,4 +1,13 @@
|
||||
import { Controller, Get, Param, Req, Res, UseGuards, Logger, Request } from '@nestjs/common';
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Param,
|
||||
Req,
|
||||
Res,
|
||||
UseGuards,
|
||||
Logger,
|
||||
Request,
|
||||
} from '@nestjs/common';
|
||||
import { Response } from 'express';
|
||||
import { DocumentsService } from './documents.service';
|
||||
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
|
||||
@ -17,7 +26,7 @@ export class DocumentsController {
|
||||
|
||||
constructor(
|
||||
private readonly documentsService: DocumentsService,
|
||||
private readonly s3Service: S3Service
|
||||
private readonly s3Service: S3Service,
|
||||
) {}
|
||||
|
||||
@Get('shared/:userId')
|
||||
@ -31,7 +40,7 @@ export class DocumentsController {
|
||||
async downloadDocument(
|
||||
@Param('key') key: string,
|
||||
@Request() req,
|
||||
@Res() res: Response
|
||||
@Res() res: Response,
|
||||
) {
|
||||
try {
|
||||
this.logger.debug(`Download request for key: ${key}`);
|
||||
@ -40,7 +49,8 @@ export class DocumentsController {
|
||||
this.logger.debug(`Decoded key: ${decodedKey}`);
|
||||
|
||||
// Get document from database first to verify access
|
||||
const document = await this.documentsService.findDocumentByS3Key(decodedKey);
|
||||
const document =
|
||||
await this.documentsService.findDocumentByS3Key(decodedKey);
|
||||
|
||||
if (!document) {
|
||||
return res.status(404).json({ message: 'Document not found' });
|
||||
@ -49,7 +59,7 @@ export class DocumentsController {
|
||||
// Verify user has access to this document
|
||||
const hasAccess = await this.documentsService.verifyDocumentAccess(
|
||||
document.id,
|
||||
req.user.id
|
||||
req.user.id,
|
||||
);
|
||||
|
||||
if (!hasAccess) {
|
||||
@ -74,7 +84,7 @@ export class DocumentsController {
|
||||
this.logger.error('Download error:', error);
|
||||
return res.status(500).json({
|
||||
message: 'Failed to download file',
|
||||
error: error.message
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
21
frontend/imk/package-lock.json
generated
21
frontend/imk/package-lock.json
generated
@ -11,10 +11,12 @@
|
||||
"@headlessui/react": "^1.7.17",
|
||||
"@heroicons/react": "^2.0.18",
|
||||
"axios": "^1.7.7",
|
||||
"date-fns": "^4.1.0",
|
||||
"framer-motion": "^11.11.10",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-icons": "^5.5.0",
|
||||
"react-router-dom": "^6.15.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -1453,6 +1455,16 @@
|
||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/date-fns": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
|
||||
"integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/kossnocorp"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
@ -3603,6 +3615,15 @@
|
||||
"react": "^18.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-icons": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
|
||||
"integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||
|
||||
@ -13,10 +13,12 @@
|
||||
"@headlessui/react": "^1.7.17",
|
||||
"@heroicons/react": "^2.0.18",
|
||||
"axios": "^1.7.7",
|
||||
"date-fns": "^4.1.0",
|
||||
"framer-motion": "^11.11.10",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-icons": "^5.5.0",
|
||||
"react-router-dom": "^6.15.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -1,178 +1,129 @@
|
||||
import { SectionHeader } from '../../shared/SectionHeader';
|
||||
import { Button } from '../../shared/Button';
|
||||
import { FiUsers, FiAward, FiCheckCircle, FiTrendingUp } from 'react-icons/fi';
|
||||
import { NavLink } from "react-router-dom";
|
||||
import { motion } from "framer-motion";
|
||||
import { SectionHeader } from "../../shared/SectionHeader";
|
||||
import { FiTrendingUp, FiAward, FiCheckCircle } from "react-icons/fi";
|
||||
|
||||
const milestones = [
|
||||
{ year: "2008", title: "Основање на компанијата" },
|
||||
{ year: "2012", title: "Проширување на лабораторијата" },
|
||||
{ year: "2015", title: "ISO сертификација" },
|
||||
{ year: "2018", title: "Воведување на нови услуги" },
|
||||
{ year: "2020", title: "Модернизација на опремата" },
|
||||
{ year: "2023", title: "Проширување на тимот" },
|
||||
];
|
||||
|
||||
export default function About() {
|
||||
const stats = [
|
||||
{ label: 'Години искуство', value: '15+' },
|
||||
{ label: 'Задоволни клиенти', value: '500+' },
|
||||
{ label: 'Завршени проекти', value: '1000+' },
|
||||
{ label: 'Експерти во тимот', value: '20+' }
|
||||
];
|
||||
|
||||
const milestones = [
|
||||
{ year: '2008', title: 'Основање на компанијата' },
|
||||
{ year: '2012', title: 'Проширување на лабораторијата' },
|
||||
{ year: '2015', title: 'ISO сертификација' },
|
||||
{ year: '2018', title: 'Воведување на нови услуги' },
|
||||
{ year: '2020', title: 'Модернизација на опремата' },
|
||||
{ year: '2023', title: 'Проширување на тимот' }
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gradient-to-b from-cyan-900 to-cyan-800">
|
||||
<div className="isolate bg-graymin-h-screen bg-gradient-to-b from-cyan-900 to-cyan-400">
|
||||
{/* Hero Section */}
|
||||
<div className="relative h-[80vh] overflow-hidden">
|
||||
<div className="relative h-screen overflow-hidden">
|
||||
<div className="absolute inset-0">
|
||||
<img
|
||||
src="/about-hero.webp"
|
||||
alt="Laboratory equipment"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-blue-900/90 to-blue-600/80" />
|
||||
</div>
|
||||
|
||||
<div className="relative container mx-auto px-4 h-full flex items-center">
|
||||
<div className="max-w-3xl">
|
||||
<h1 className="text-4xl md:text-6xl font-bold text-white mb-6">
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1, ease: "easeInOut" }}
|
||||
className="text-4xl md:text-6xl font-bold text-white mb-6"
|
||||
>
|
||||
За Нас
|
||||
</h1>
|
||||
<p className="text-xl text-gray-200 mb-8">
|
||||
</motion.h1>
|
||||
<motion.p
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1, delay: 0.2, ease: "easeIn" }}
|
||||
className="text-xl text-gray-200 mb-8"
|
||||
>
|
||||
Повеќе од 15 години искуство во обезбедување квалитет
|
||||
</p>
|
||||
</motion.p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Stats Section */}
|
||||
{/* <div className="container mx-auto px-4 py-16 -mt-20">
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 md:gap-8">
|
||||
{stats.map((stat, index) => (
|
||||
<div key={index} className="bg-white/10 backdrop-blur-lg rounded-xl p-6 text-center">
|
||||
<div className="text-3xl font-bold text-blue-400 mb-2">{stat.value}</div>
|
||||
<div className="text-gray-300">{stat.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
{/* Vision & Values Section */}
|
||||
<div className="container mx-auto px-4 py-16">
|
||||
<SectionHeader
|
||||
title="Нашата Мисија"
|
||||
subtitle="Посветени сме на обезбедување највисок квалитет во нашата работа"
|
||||
className="text-white"
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 mb-16">
|
||||
<div className="bg-white/10 backdrop-blur-lg rounded-xl p-8">
|
||||
<div className="flex items-center mb-4">
|
||||
<FiTrendingUp className="w-6 h-6 text-white mr-3" />
|
||||
<h3 className="text-2xl font-semibold text-white">
|
||||
Визија
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-white text-xl">
|
||||
Нашата визија е да бидеме водечка компанија во областа на испитување на материјали и контрола на квалитет во Македонија. Стремиме кон постојано унапредување на нашите услуги преку имплементација на најсовремени технологии и методологии. Сакаме да воспоставиме нови стандарди во индустријата и да допринесеме за развојот на градежништвото и инженерството во регионот.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-white/10 backdrop-blur-lg rounded-xl p-8">
|
||||
<div className="flex items-center mb-4">
|
||||
<FiAward className="w-6 h-6 text-white mr-3" />
|
||||
<h3 className="text-2xl font-semibold text-white">
|
||||
Вредности
|
||||
</h3>
|
||||
</div>
|
||||
<ul className="text-gray-300 space-y-3">
|
||||
<li className="flex items-start text-xl">
|
||||
<FiCheckCircle className="w-5 h-5 text-red mr-2 mt-1" />
|
||||
<div>
|
||||
<strong className="text-white">Квалитет</strong> - Посветени сме на обезбедување највисок квалитет во сите наши услуги
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start">
|
||||
<FiCheckCircle className="w-5 h-5 text-blue-400 mr-2 mt-1" />
|
||||
<div>
|
||||
<strong className="text-white">Интегритет</strong> - Работиме со целосна транспарентност и професионална етика
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start">
|
||||
<FiCheckCircle className="w-5 h-5 text-blue-400 mr-2 mt-1" />
|
||||
<div>
|
||||
<strong className="text-white">Иновација</strong> - Постојано инвестираме во нови технологии и методи
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start">
|
||||
<FiCheckCircle className="w-5 h-5 text-blue-400 mr-2 mt-1" />
|
||||
<div>
|
||||
<strong className="text-white">Експертиза</strong> - Нашиот тим се состои од високо квалификувани професионалци
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start">
|
||||
<FiCheckCircle className="w-5 h-5 text-blue-400 mr-2 mt-1" />
|
||||
<div>
|
||||
<strong className="text-white">Одговорност</strong> - Преземаме целосна одговорност за квалитетот на нашата работа
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Timeline Section */}
|
||||
<div className="mb-16 border rounded-xl border-red-900/20 p-10 bg-white/10 backdrop-blur-lg">
|
||||
<div className="bg-white py-24">
|
||||
<div className="container bg-gradient-to-b from-cyan-900 to-cyan-400 rounded-xl mx-auto p-20">
|
||||
<SectionHeader
|
||||
title="Нашиот Развој"
|
||||
subtitle="Клучни моменти во нашата историја"
|
||||
title="Нашата Мисија"
|
||||
subtitle="Посветени сме на обезбедување највисок квалитет во нашата работа"
|
||||
className="text-white"
|
||||
/>
|
||||
<div className="relative">
|
||||
<div className="absolute left-1/2 transform -translate-x-1/2 h-full w-px"></div>
|
||||
<div className="space-y-8">
|
||||
{milestones.map((milestone, index) => (
|
||||
<div key={index} className={`flex items-center ${index % 2 === 0 ? 'justify-start' : 'justify-end'}`}>
|
||||
<div className={`w-1/2 ${index % 2 === 0 ? 'pr-8 text-right' : 'pl-8'}`}>
|
||||
<div className="bg-white/80 backdrop-blur-lg rounded-xl p-6 text-blue-800">
|
||||
<div className="text-blue-400 font-bold text-xl mb-2">{milestone.year}</div>
|
||||
<div className="text-blue-700 text-xl">{milestone.title}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Team Section */}
|
||||
<div className="mb-16">
|
||||
<SectionHeader
|
||||
title="Нашиот Тим"
|
||||
subtitle="Запознајте се со нашите експерти"
|
||||
className="text-white"
|
||||
/>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{[1, 2, 3].map((member) => (
|
||||
<div key={member} className="bg-white backdrop-blur-lg rounded-xl p-6 text-center">
|
||||
<div className="w-24 h-24 mx-auto mb-4 rounded-full bg-blue-400/20 flex items-center justify-center">
|
||||
<FiUsers className="w-12 h-12 text-blue-400" />
|
||||
</div>
|
||||
<h4 className="text-white font-semibold mb-2">Име Презиме</h4>
|
||||
<p className="text-gray-400">Позиција</p>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 mb-16">
|
||||
<div className="bg-white/10 backdrop-blur-lg rounded-xl p-8">
|
||||
<div className="flex items-center mb-4">
|
||||
<FiTrendingUp className="w-6 h-6 text-white mr-3" />
|
||||
<h3 className="text-2xl font-semibold text-white">Визија</h3>
|
||||
</div>
|
||||
))}
|
||||
<p className="text-white text-xl">
|
||||
Нашата визија е да бидеме водечка компанија во областа на
|
||||
испитување на материјали и контрола на квалитет во Македонија.
|
||||
Стремиме кон постојано унапредување на нашите услуги преку
|
||||
имплементација на најсовремени технологии и методологии. Сакаме
|
||||
да воспоставиме нови стандарди во индустријата и да допринесеме
|
||||
за развојот на градежништвото и инженерството во регионот.
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-white/10 backdrop-blur-lg rounded-xl p-8">
|
||||
<div className="flex items-center mb-4">
|
||||
<FiAward className="w-6 h-6 text-white mr-3" />
|
||||
<h3 className="text-2xl font-semibold text-white">Вредности</h3>
|
||||
</div>
|
||||
<ul className="text-gray-300 space-y-3">
|
||||
<li className="flex items-start text-xl">
|
||||
<FiCheckCircle className="w-5 h-5 text-red mr-2 mt-1" />
|
||||
<div>
|
||||
<strong className="text-white">Квалитет</strong> - Посветени
|
||||
сме на обезбедување највисок квалитет во сите наши услуги
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start">
|
||||
<FiCheckCircle className="w-5 h-5 text-blue-400 mr-2 mt-1" />
|
||||
<div>
|
||||
<strong className="text-white">Интегритет</strong> -
|
||||
Работиме со целосна транспарентност и професионална етика
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start">
|
||||
<FiCheckCircle className="w-5 h-5 text-blue-400 mr-2 mt-1" />
|
||||
<div>
|
||||
<strong className="text-white">Иновација</strong> -
|
||||
Постојано инвестираме во нови технологии и методи
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start">
|
||||
<FiCheckCircle className="w-5 h-5 text-blue-400 mr-2 mt-1" />
|
||||
<div>
|
||||
<strong className="text-white">Експертиза</strong> - Нашиот
|
||||
тим се состои од високо квалификувани професионалци
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start">
|
||||
<FiCheckCircle className="w-5 h-5 text-blue-400 mr-2 mt-1" />
|
||||
<div>
|
||||
<strong className="text-white">Одговорност</strong> -
|
||||
Преземаме целосна одговорност за квалитетот на нашата работа
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* CTA Section */}
|
||||
<div className="bg-blue-600/20 backdrop-blur-lg py-24">
|
||||
<div className="isolate bg-gray bg-gradient-to-b from-blue-700 to-blue-500 text-white py-24">
|
||||
<div className="container mx-auto px-4 text-center">
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-white mb-8">
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-8">
|
||||
Започнете го вашиот проект со нас
|
||||
</h2>
|
||||
<Button variant="outline">
|
||||
<NavLink
|
||||
to="/contact"
|
||||
className="inline-block bg-white text-blue-600 px-8 py-3 rounded-full font-semibold hover:bg-gray-100 transition-colors duration-300"
|
||||
>
|
||||
Контактирајте нѐ
|
||||
</Button>
|
||||
</NavLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -5,7 +5,8 @@ import { SectionHeader } from "../../shared/SectionHeader";
|
||||
const serviceCards = [
|
||||
{
|
||||
title: "Лабораториски услуги",
|
||||
description: "Професионални лабораториски испитувања со најсовремена опрема",
|
||||
description:
|
||||
"Професионални лабораториски испитувања со најсовремена опрема",
|
||||
image: "labfinal.webp",
|
||||
link: "/lab",
|
||||
services: [
|
||||
@ -13,8 +14,8 @@ const serviceCards = [
|
||||
"Геотехнички испитувања",
|
||||
"Испитување на челик",
|
||||
"Испитување на руди, метали и троски",
|
||||
"Лабораториска екстракција од руди и троски"
|
||||
]
|
||||
"Лабораториска екстракција од руди и троски",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Ултразвучни испитувања",
|
||||
@ -26,8 +27,8 @@ const serviceCards = [
|
||||
"Дебелометрија",
|
||||
"Испитување на дефекти",
|
||||
"Контрола на квалитет",
|
||||
"Анализа и известување"
|
||||
]
|
||||
"Анализа и известување",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Консалтинг услуги",
|
||||
@ -39,18 +40,17 @@ const serviceCards = [
|
||||
"Проектен менаџмент",
|
||||
"Надзор на градба",
|
||||
"Техничка документација",
|
||||
"Анализа на материјали"
|
||||
]
|
||||
}
|
||||
"Анализа на материјали",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="isolate bg-graymin-h-screen bg-gradient-to-b from-cyan-900 to-cyan-400">
|
||||
{/* Hero Section with Parallax */}
|
||||
<div className="relative h-[90vh] overflow-hidden">
|
||||
<div className="relative h-screen overflow-hidden">
|
||||
<div className="absolute inset-0">
|
||||
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-blue-900/90 to-blue-600/80" />
|
||||
</div>
|
||||
|
||||
@ -69,7 +69,8 @@ export default function Home() {
|
||||
transition={{ delay: 0.2 }}
|
||||
className="text-xl text-gray-200 mb-8"
|
||||
>
|
||||
Професионални лабораториски услуги со најсовремена опрема и експертиза
|
||||
Професионални лабораториски услуги со најсовремена опрема и
|
||||
експертиза
|
||||
</motion.p>
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
@ -84,7 +85,7 @@ export default function Home() {
|
||||
Контактирајте нѐ
|
||||
</NavLink>
|
||||
<NavLink
|
||||
to="/services"
|
||||
to="/about"
|
||||
className="bg-white/10 hover:bg-white/20 text-white px-8 py-3 rounded-full font-semibold transition-colors duration-300"
|
||||
>
|
||||
Дознајте повеќе
|
||||
@ -213,3 +214,4 @@ export default function Home() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import { useState } from "react";
|
||||
import axios from "axios";
|
||||
|
||||
const FileUpload = () => {
|
||||
const [file, setFile] = useState(null);
|
||||
@ -16,25 +16,26 @@ const FileUpload = () => {
|
||||
if (!file) return;
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
formData.append('title', 'Your document title');
|
||||
// Add other fields as needed
|
||||
formData.append("file", file);
|
||||
formData.append("title", "Your document title");
|
||||
|
||||
try {
|
||||
await axios.post('/api/admin/document', formData, {
|
||||
await axios.post("/api/admin/document", formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
onUploadProgress: (progressEvent) => {
|
||||
const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
|
||||
const percentCompleted = Math.round(
|
||||
(progressEvent.loaded * 100) / progressEvent.total,
|
||||
);
|
||||
setProgress(percentCompleted);
|
||||
},
|
||||
});
|
||||
|
||||
console.log('Upload successful');
|
||||
console.log("Upload successful");
|
||||
setProgress(0);
|
||||
} catch (error) {
|
||||
console.error('Upload failed:', error);
|
||||
console.error("Upload failed:", error);
|
||||
setProgress(0);
|
||||
}
|
||||
};
|
||||
@ -54,3 +55,4 @@ const FileUpload = () => {
|
||||
};
|
||||
|
||||
export default FileUpload;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user