This commit is contained in:
Nguyen Trung Nghia 2025-05-08 16:36:17 +07:00
commit 6074e31003
73 changed files with 9635 additions and 0 deletions

View File

@ -0,0 +1,63 @@
name: Build and Push Docker Image
on:
push:
branches: ["deploy"]
pull_request:
branches: ["deploy"]
env:
REGISTRY: docker.io
IMAGE_NAME: ${{ secrets.DOCKER_HUB_USERNAME }}/landing_929
DOCKERFILE_PATH: ./Dockerfile # Đặt Dockerfile ở thư mục gốc
CONTEXT: . # Đặt context là thư mục gốc
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest
type=raw,value=${{ github.sha }}
type=raw,value=${{ github.ref_name }}-${{ github.run_number }}
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: ${{ env.CONTEXT }}
file: ${{ env.DOCKERFILE_PATH }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

24
.gitignore vendored Normal file
View File

@ -0,0 +1,24 @@
# Nuxt dev/build outputs
.output
.data
.nuxt
.nitro
.cache
dist
# Node dependencies
node_modules
# Logs
logs
*.log
# Misc
.DS_Store
.fleet
.idea
# Local env files
.env
.env.*
!.env.example

12
.prettierrc.json Normal file
View File

@ -0,0 +1,12 @@
{
"semi": true,
"trailingComma": "all",
"singleQuote": false,
"tabWidth": 2,
"useTabs": false,
"arrowParens": "avoid",
"jsxBracketSameLine": true,
"html.format.wrapAttributes": "auto",
"html.format.wrapLineLength": 0,
"printWidth": 1000
}

12
Dockerfile Normal file
View File

@ -0,0 +1,12 @@
FROM node:18-alpine AS nodebuilder
WORKDIR /app
COPY package.json .
COPY yarn.lock .
RUN yarn install
COPY . .
RUN yarn build
FROM node:18-alpine AS bin
COPY --from=nodebuilder /app/.output ./.output
CMD ["node", ".output/server/index.mjs"]

75
README.md Normal file
View File

@ -0,0 +1,75 @@
# Nuxt Minimal Starter
Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
## Setup
Make sure to install dependencies:
```bash
# npm
npm install
# pnpm
pnpm install
# yarn
yarn install
# bun
bun install
```
## Development Server
Start the development server on `http://localhost:3000`:
```bash
# npm
npm run dev
# pnpm
pnpm dev
# yarn
yarn dev
# bun
bun run dev
```
## Production
Build the application for production:
```bash
# npm
npm run build
# pnpm
pnpm build
# yarn
yarn build
# bun
bun run build
```
Locally preview production build:
```bash
# npm
npm run preview
# pnpm
pnpm preview
# yarn
yarn preview
# bun
bun run preview
```
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.

7
app.vue Normal file
View File

@ -0,0 +1,7 @@
<template>
<a-extract-style>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</a-extract-style>
</template>

3
assets/css/tailwind.css Normal file
View File

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@ -0,0 +1,69 @@
<template>
<div class="bg-blue-50 py-12 md:py-16">
<div class="container mx-auto px-4">
<h2 class="text-2xl md:text-3xl font-bold text-center text-blue-800 mb-12">Lĩnh vực hoạt động</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div class="bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow">
<div class="text-blue-600 mb-4">
<svg class="w-10 h-10" fill="currentColor" viewBox="0 0 20 20">
<path d="M9 4.804A7.968 7.968 0 005.5 4c-1.255 0-2.443.29-3.5.804v10A7.969 7.969 0 015.5 14c1.669 0 3.218.51 4.5 1.385A7.962 7.962 0 0114.5 14c1.255 0 2.443.29 3.5.804v-10A7.968 7.968 0 0014.5 4c-1.255 0-2.443.29-3.5.804V12a1 1 0 11-2 0V4.804z"></path>
</svg>
</div>
<h3 class="text-xl font-semibold mb-3">Đo đạc & Quy hoạch</h3>
<p class="text-gray-700">Đo vẽ bản đồ địa hình, lập quy hoạch chung đô thị, quy hoạch chi tiết các khu dân , khu chức năng đô thị, khu công nghiệp.</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow">
<div class="text-blue-600 mb-4">
<svg class="w-10 h-10" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z" clip-rule="evenodd"></path>
</svg>
</div>
<h3 class="text-xl font-semibold mb-3">Thiết kế xây dựng</h3>
<p class="text-gray-700">Lập dự án đầu , khảo sát, thiết kế xây dựng các công trình giao thông, nông nghiệp, dân dụng - công nghiệp hạ tầng kỹ thuật.</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow">
<div class="text-blue-600 mb-4">
<svg class="w-10 h-10" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M6 6V5a3 3 0 013-3h2a3 3 0 013 3v1h2a2 2 0 012 2v3.57A22.952 22.952 0 0110 13a22.95 22.95 0 01-8-1.43V8a2 2 0 012-2h2zm2-1a1 1 0 011-1h2a1 1 0 011 1v1H8V5zm1 5a1 1 0 011-1h.01a1 1 0 110 2H10a1 1 0 01-1-1z" clip-rule="evenodd"></path>
<path d="M2 13.692V16a2 2 0 002 2h12a2 2 0 002-2v-2.308A24.974 24.974 0 0110 15c-2.796 0-5.487-.46-8-1.308z"></path>
</svg>
</div>
<h3 class="text-xl font-semibold mb-3">Giám sát thi công</h3>
<p class="text-gray-700"> vấn giám sát thi công xây dựng, đảm bảo chất lượng công trình theo đúng thiết kế tiêu chuẩn kỹ thuật.</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow">
<div class="text-blue-600 mb-4">
<svg class="w-10 h-10" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M11.17 3.5c.63-.24 1.29-.16 1.8.19.7.51 1.03 1.36.83 2.15-.2.8-.89 1.42-1.7 1.56-.8.14-1.62-.2-2.03-.9-.4-.7-.32-1.58.22-2.18.5-.57 1.3-.7 1.88-.42zm-4.85 2.03c.2-.8.89-1.42 1.7-1.56.8-.13 1.62.2 2.03.9.4.7.32 1.58-.22 2.18-.5.57-1.3.7-1.88.42-.63-.24-1.29-.16-1.8.19-.7.51-1.03 1.36-.83 2.15.2.8.89 1.42 1.7 1.56.8.14 1.62-.2 2.03-.9.4-.7.32-1.58-.22-2.18-.5-.57-1.3-.7-1.88-.42-.63.24-1.29.16-1.8-.19-.7-.51-1.03-1.36-.83-2.15zM15.85 8.62c.2-.8.89-1.42 1.7-1.56.8-.13 1.62.2 2.03.9.4.7.32 1.58-.22 2.18-.5.57-1.3.7-1.88.42-.63-.24-1.29-.16-1.8.19-.7.51-1.03 1.36-.83 2.15.2.8.89 1.42 1.7 1.56.8.14 1.62-.2 2.03-.9.4-.7.32-1.58-.22-2.18-.5-.57-1.3-.7-1.88-.42-.63.24-1.29.16-1.8-.19-.7-.51-1.03-1.36-.83-2.15z" clip-rule="evenodd"></path>
</svg>
</div>
<h3 class="text-xl font-semibold mb-3">Hệ thống kỹ thuật</h3>
<p class="text-gray-700">Thiết kế hệ thống cứu hỏa, PCCC, tín hiệu giao thông, hệ thống điện ngoại thất & nội thất công trình.</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow">
<div class="text-blue-600 mb-4">
<svg class="w-10 h-10" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l-3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"></path>
</svg>
</div>
<h3 class="text-xl font-semibold mb-3">Thẩm định & Thẩm tra</h3>
<p class="text-gray-700"> vấn thẩm định, thẩm tra thiết kế, tổng dự toán, dự toán các công trình xây dựng.</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow">
<div class="text-blue-600 mb-4">
<svg class="w-10 h-10" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd"></path>
</svg>
</div>
<h3 class="text-xl font-semibold mb-3">Quản dự án</h3>
<p class="text-gray-700"> vấn quản điều hành dự án, thẩm định kết quả đấu thầu, lập hồ mời thầu.</p>
</div>
</div>
</div>
</div>
</template>

View File

@ -0,0 +1,17 @@
<template>
<div class="bg-blue-600 text-white py-16">
<div class="container mx-auto px-4 text-center">
<h2 class="text-3xl font-bold mb-6">Bạn cần vấn về dự án xây dựng?</h2>
<p class="text-xl mb-8 max-w-2xl mx-auto">Liên hệ ngay với chúng tôi để được hỗ trợ vấn miễn phí</p>
<div class="flex flex-col sm:flex-row justify-center gap-4">
<NuxtLink to="/contact" class="px-6 py-3 bg-white text-blue-800 rounded-lg hover:bg-gray-100 transition-colors font-semibold"> Gửi yêu cầu </NuxtLink>
<div class="flex items-center justify-center px-6 py-3 border border-white rounded-lg">
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path d="M2 3a1 1 0 011-1h2.153a1 1 0 01.986.836l.74 4.435a1 1 0 01-.54 1.06l-1.548.773a11.037 11.037 0 006.105 6.105l.774-1.548a1 1 0 011.059-.54l4.435.74a1 1 0 01.836.986V17a1 1 0 01-1 1h-2C7.82 18 2 12.18 2 5V3z"></path>
</svg>
<span>0986 108 999</span>
</div>
</div>
</div>
</div>
</template>

View File

@ -0,0 +1,48 @@
<template>
<div class="container mx-auto px-4 py-12 md:py-16">
<div class="flex flex-col md:flex-row gap-8">
<div class="md:w-1/2">
<h2 class="text-2xl md:text-3xl font-bold text-blue-800 mb-6">Giới thiệu công ty</h2>
<p class="text-gray-700 mb-4">
Công ty cổ phần vấn xây dựng 929 đơn vị hoạt động đa chức năng trong lĩnh vực vấn, thiết kế, giám sát thi công xây dựng công trình.
</p>
<p class="text-gray-700 mb-4">
Với đội ngũ cán bộ công nhân viên giàu kinh nghiệm, năng động, không ngừng học hỏi trau dồi kiến thức, chúng tôi luôn tiếp cận các công nghệ mới để mang đến giải pháp tối ưu cho khách hàng.
</p>
<div class="bg-blue-50 p-6 rounded-lg border border-blue-100">
<h3 class="text-lg font-semibold text-blue-800 mb-3">Thông tin công ty</h3>
<ul class="space-y-2">
<li class="flex items-start">
<svg class="w-5 h-5 text-blue-600 mt-1 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"></path>
</svg>
<span>Tổ 7 đường 3-2, phường Tân Lập, TP Thái Nguyên</span>
</li>
<li class="flex items-start">
<svg class="w-5 h-5 text-blue-600 mt-1 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path d="M2 3a1 1 0 011-1h2.153a1 1 0 01.986.836l.74 4.435a1 1 0 01-.54 1.06l-1.548.773a11.037 11.037 0 006.105 6.105l.774-1.548a1 1 0 011.059-.54l4.435.74a1 1 0 01.836.986V17a1 1 0 01-1 1h-2C7.82 18 2 12.18 2 5V3z"></path>
</svg>
<span>Điện thoại: 0986108999</span>
</li>
<li class="flex items-start">
<svg class="w-5 h-5 text-blue-600 mt-1 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z"></path>
<path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z"></path>
</svg>
<span>Email: congty929@gmail.com.vn</span>
</li>
<li class="flex items-start">
<svg class="w-5 h-5 text-blue-600 mt-1 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M4 4a2 2 0 00-2 2v4a2 2 0 002 2V6h10a2 2 0 00-2-2H4zm2 6a2 2 0 012-2h8a2 2 0 012 2v4a2 2 0 01-2 2H8a2 2 0 01-2-2v-4zm6 4a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"></path>
</svg>
<span>Tài khoản: 8500201002857 tại Ngân hàng Nông nghiệp PTNT tỉnh Thái Nguyên</span>
</li>
</ul>
</div>
</div>
<div class="md:w-1/2">
<NuxtImg placeholder="/placeholder.png" src="/home.jpg" alt="Trụ sở công ty" class="rounded-lg shadow-lg w-full h-auto object-cover"/>
</div>
</div>
</div>
</template>

48
components/About_Team.vue Normal file
View File

@ -0,0 +1,48 @@
<template>
<div class="bg-gray-100 py-12 md:py-16">
<div class="container mx-auto px-4">
<h2 class="text-2xl md:text-3xl font-bold text-center text-blue-800 mb-12">Đội ngũ nhân sự</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
<div class="bg-white rounded-lg overflow-hidden shadow-md text-center p-6">
<!-- <div class="w-32 h-32 mx-auto rounded-full overflow-hidden mb-4 border-4 border-blue-100">
<NuxtImg placeholder="/placeholder.png" src="/images/team-1.png" alt="Đào Đình Dũng" class="w-full h-full object-cover"/>
</div> -->
<h3 class="text-xl font-semibold">Ông. Đào Đình Dũng</h3>
<p class="text-blue-600 mb-2">Chủ tịch HĐQT - Giám đốc</p>
<p class="text-gray-600">Kỹ cầu đường</p>
<p class="text-gray-500 text-sm mt-2">Hơn 15 năm kinh nghiệm</p>
</div>
<div class="bg-white rounded-lg overflow-hidden shadow-md text-center p-6">
<!-- <div class="w-32 h-32 mx-auto rounded-full overflow-hidden mb-4 border-4 border-blue-100">
<NuxtImg placeholder="/placeholder.png" src="/images/team-2.png" alt="Vũ Hồng Phong" class="w-full h-full object-cover"/>
</div> -->
<h3 class="text-xl font-semibold">Ông. Hồng Phong</h3>
<p class="text-blue-600 mb-2">Thành viên HĐQT</p>
<p class="text-gray-600">Kỹ cầu đường</p>
<p class="text-gray-500 text-sm mt-2">Hơn 15 năm kinh nghiệm</p>
</div>
<div class="bg-white rounded-lg overflow-hidden shadow-md text-center p-6">
<!-- <div class="w-32 h-32 mx-auto rounded-full overflow-hidden mb-4 border-4 border-blue-100">
<NuxtImg placeholder="/placeholder.png" src="/images/team-3.png" alt="Trần Thị Thu Hiền" class="w-full h-full object-cover"/>
</div> -->
<h3 class="text-xl font-semibold">. Trần Thị Thu Hiền</h3>
<p class="text-blue-600 mb-2">Thành viên HĐQT</p>
<p class="text-gray-600">Kỹ cầu đường bộ</p>
<p class="text-gray-500 text-sm mt-2">Hơn 7 năm kinh nghiệm</p>
</div>
<div class="bg-white rounded-lg overflow-hidden shadow-md text-center p-6">
<!-- <div class="w-32 h-32 mx-auto rounded-full overflow-hidden mb-4 border-4 border-blue-100">
<NuxtImg placeholder="/placeholder.png" src="/images/team-4.png" alt="Nguyễn Thị Thu Hằng" class="w-full h-full object-cover"/>
</div> -->
<h3 class="text-xl font-semibold">. Nguyễn Thị Thu Hằng</h3>
<p class="text-blue-600 mb-2">Trưởng phòng kế toán</p>
<p class="text-gray-600">Kế toán trưởng</p>
<p class="text-gray-500 text-sm mt-2">Hơn 8 năm kinh nghiệm</p>
</div>
</div>
</div>
</div>
</template>

View File

@ -0,0 +1,39 @@
<template>
<div class="container mx-auto px-4 py-12 md:py-16">
<h2 class="text-2xl md:text-3xl font-bold text-center text-blue-800 mb-12">Phương châm làm việc</h2>
<div class="max-w-4xl mx-auto">
<div class="bg-white rounded-xl shadow-md overflow-hidden">
<div class="md:flex">
<div class="md:w-1/2 bg-blue-600 p-8 text-white">
<h3 class="text-xl font-bold mb-4">Cam kết của chúng tôi</h3>
<ul class="space-y-4">
<li class="flex items-start">
<svg class="w-5 h-5 mt-1 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path>
</svg>
<span>Tìm hiểu kỹ yêu cầu khách hàng để cung cấp dịch vụ giải pháp tối ưu</span>
</li>
<li class="flex items-start">
<svg class="w-5 h-5 mt-1 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path>
</svg>
<span>Không ngừng nâng cao năng lực chuyên môn, tích lũy kinh nghiệm thực tế</span>
</li>
<li class="flex items-start">
<svg class="w-5 h-5 mt-1 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path>
</svg>
<span>Đảm bảo đúng tiến độ theo hợp đồng</span>
</li>
</ul>
</div>
<div class="md:w-1/2 p-8">
<h3 class="text-xl font-bold mb-4 text-blue-800">Chất lượng ưu tiên hàng đầu</h3>
<p class="text-gray-700 mb-4">Chúng tôi coi chất lượng nhiệm vụ hàng đầu trong lĩnh vực hoạt động sản xuất kinh doanh của mình.</p>
<p class="text-gray-700">Sẵn sàng liên danh, hợp tác với các đơn vị vấn trong ngoài nước nhằm nâng cao chất lượng sản phẩm vấn, sản phẩm xây dựng yêu cầu kỹ thuật cao.</p>
</div>
</div>
</div>
</div>
</div>
</template>

84
components/Footer.vue Normal file
View File

@ -0,0 +1,84 @@
<template>
<footer class="bg-[url('/bgfooter.png')] bg-center bg-cover bg-no-repeat w-screen">
<div class="container mx-auto px-4 sm:px-[50px] py-6 sm:py-10 text-white">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-2 sm:gap-8">
<div>
<h3 class="font-roboto font-bold text-base sm:text-lg mb-2 sm:mb-4">DỊCH VỤ CHÍNH</h3>
<ul class="space-y-1 sm:space-y-2">
<li class="font-roboto flex items-start text-sm sm:text-base">
<nuxt-link to="/">
<Icon name="material-symbols:arrow-forward-ios-rounded" class="text-white mt-0.5 mr-1 flex-shrink-0" size="14" />
<span> vấn thiết kế xây dựng</span>
</nuxt-link>
</li>
<li class="font-roboto flex items-start text-sm sm:text-base">
<nuxt-link to="/">
<Icon name="material-symbols:arrow-forward-ios-rounded" class="text-white mt-0.5 mr-1 flex-shrink-0" size="14" />
<span>Giám sát thi công</span>
</nuxt-link>
</li>
<li class="font-roboto flex items-start text-sm sm:text-base">
<nuxt-link to="/">
<Icon name="material-symbols:arrow-forward-ios-rounded" class="text-white mt-0.5 mr-1 flex-shrink-0" size="14" />
<span>Thi công xây dựng</span>
</nuxt-link>
</li>
</ul>
</div>
<div>
<h3 class="font-roboto font-bold text-base sm:text-lg mb-2 sm:mb-4">LĨNH VỰC HOẠT ĐỘNG</h3>
<ul class="space-y-1 sm:space-y-2">
<li class="font-roboto flex items-start text-sm sm:text-base">
<nuxt-link to="/">
<Icon name="material-symbols:arrow-forward-ios-rounded" class="text-white mt-0.5 mr-1 flex-shrink-0" size="14" />
<span>Quy hoạch đô thị</span>
</nuxt-link>
</li>
<li class="font-roboto flex items-start text-sm sm:text-base">
<nuxt-link to="/">
<Icon name="material-symbols:arrow-forward-ios-rounded" class="text-white mt-0.5 mr-1 flex-shrink-0" size="14" />
<span>Công trình giao thông</span>
</nuxt-link>
</li>
<li class="font-roboto flex items-start text-sm sm:text-base">
<nuxt-link to="/">
<Icon name="material-symbols:arrow-forward-ios-rounded" class="text-white mt-0.5 mr-1 flex-shrink-0" size="14" />
<span>Hệ thống điện</span>
</nuxt-link>
</li>
</ul>
</div>
<div class="col-span-1 md:col-span-2">
<h3 class="font-roboto font-bold text-base sm:text-lg mb-2 sm:mb-4">CÔNG TY CỔ PHẦN VẤN XÂY DỰNG 929</h3>
<ul class="space-y-1 sm:space-y-2 text-sm sm:text-base">
<li class="font-roboto flex flex-col sm:flex-row sm:items-start gap-1">
<div class="flex items-start">
<Icon name="mdi:map-marker" class="text-base mt-0.5 mr-1 flex-shrink-0" />
<span class="font-bold">Trụ sở chính: </span>
</div>
<span>Tổ 7 đường 3-2 phường Tân Lập, TP Thái Nguyên, Tỉnh Thái Nguyên</span>
</li>
<li class="flex-col grid grid-cols-1 md:grid-cols-2 sm:flex-row sm:items-center gap-1 sm:gap-2">
<div class="">
<Icon name="mdi:phone" class="text-base mr-1 flex-shrink-0" />
<span>Điện thoại: 0986108999</span>
</div>
<div class="">
<Icon name="mdi:email" class="text-base mr-1 flex-shrink-0" />
<span>Email: congty929@gmail.com</span>
</div>
</li>
<li class="flex items-center">
<Icon name="mdi:web" class="text-base mr-1 flex-shrink-0" />
<span> số thuế: 4600796888</span>
</li>
<li class="flex items-center">
<Icon name="mdi:bank" class="text-base mr-1 flex-shrink-0" />
<span>Tài khoản: 8500201002857 tại Ngân hàng Nông nghiệp PTNT tỉnh Thái Nguyên</span>
</li>
</ul>
</div>
</div>
</div>
</footer>
</template>

168
components/Header.vue Normal file
View File

@ -0,0 +1,168 @@
<template>
<header class="h-[70px] md:h-[80px] w-full bg-white z-[100] border-b border-gray-300 fixed">
<div class="container mx-auto h-full flex justify-between items-center px-4">
<NuxtLink to="/" class="group flex items-center gap-1 hover:opacity-90 transition-opacity" aria-label="Trang chủ">
<div class="text-center">
<span class="block text-xl md:text-2xl font-bold text-gray-900 leading-tight group-hover:text-primary transition-colors"> CÔNG TY CỔ PHẦN VẤN </span>
<span class="block text-lg md:text-xl font-extrabold text-primary tracking-wider mt-[-2px] relative">
<span class="relative z-10">XÂY DỰNG 929</span>
<span class="absolute bottom-0 left-0 right-0 h-1 bg-yellow-400 z-0 opacity-70 transform translate-y-1"></span>
</span>
<div class="h-[3px] bg-gradient-to-r from-blue-500 to-teal-400 mt-1 w-full transition-transform origin-left"></div>
</div>
</NuxtLink>
<!-- Mobile Menu Button -->
<button @click="toggleMobileMenu" class="md:hidden p-2 focus:outline-none" aria-label="Menu mobile" aria-expanded="isMobileMenuOpen">
<div class="w-6 h-6 relative">
<span
class="block absolute h-0.5 w-full bg-gray-800 rounded-full transition-all duration-300 ease-out"
:class="{
'rotate-45 top-1/2 -translate-y-1/2': isMobileMenuOpen,
'top-1': !isMobileMenuOpen,
}"
></span>
<span
class="block absolute h-0.5 w-full bg-gray-800 rounded-full transition-all duration-300 ease-out"
:class="{
'opacity-0': isMobileMenuOpen,
'top-1/2 -translate-y-1/2': !isMobileMenuOpen,
}"
></span>
<span
class="block absolute h-0.5 w-full bg-gray-800 rounded-full transition-all duration-300 ease-out"
:class="{
'-rotate-45 top-1/2 -translate-y-1/2': isMobileMenuOpen,
'bottom-1': !isMobileMenuOpen,
}"
></span>
</div>
</button>
<!-- Desktop Menu -->
<nav class="hidden md:flex items-center h-full">
<ul class="flex h-full">
<li v-for="(item, index) in mainMenuItems" :key="index" class="relative group h-full">
<NuxtLink :to="item.url" class="h-full relative flex items-center px-3 lg:px-4 hover:text-primary transition-colors after:absolute after:bottom-0 after:left-0 after:right-0 after:h-[3px] after:bg-gradient-to-r after:from-blue-500 after:to-teal-400 after:transition-all after:duration-300 after:scale-x-0 after:origin-left hover:after:scale-x-100" active-class="text-primary after:scale-x-100" exact-active-class="text-primary after:scale-x-100">
<span class="font-medium text-sm lg:text-base">
{{ item.label }}
</span>
</NuxtLink>
<div v-if="item.children.length > 0" class="absolute left-1/2 transform -translate-x-1/2 mt-0 w-48 bg-white shadow-lg rounded-b-md py-1 z-10 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-300 ease-out">
<NuxtLink v-for="(child, childIndex) in item.children" :key="childIndex" :to="child.url" class="block px-4 py-2 text-sm text-gray-800 hover:bg-blue-50 transition-colors duration-200" active-class="bg-blue-50 font-medium">
{{ child.label }}
</NuxtLink>
</div>
</li>
</ul>
</nav>
</div>
<!-- Mobile Menu -->
<transition enter-active-class="transition-all duration-300 ease-out" leave-active-class="transition-all duration-200 ease-in" enter-from-class="opacity-0 -translate-y-4" enter-to-class="opacity-100 translate-y-0" leave-from-class="opacity-100 translate-y-0" leave-to-class="opacity-0 -translate-y-4">
<div v-show="isMobileMenuOpen" class="md:hidden absolute top-full left-0 right-0 bg-white shadow-lg z-[9999] overflow-hidden max-h-[calc(100vh-70px)] overflow-y-auto" @click.self="isMobileMenuOpen = false">
<ul class="py-2">
<li v-for="(item, index) in mainMenuItems" :key="index" class="border-b border-gray-100 last:border-0">
<div v-if="item.children.length > 0" @click="toggleMobileSubmenu(index)" class="flex justify-between items-center px-4 py-3 hover:bg-gray-50 cursor-pointer transition-colors">
<span class="text-sm font-medium">{{ item.label }}</span>
<svg class="w-4 h-4 transition-transform duration-300" :class="{ 'rotate-90': activeMobileSubmenu === index }" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
</div>
<NuxtLink v-else :to="item.url" @click="isMobileMenuOpen = false" class="flex justify-between items-center px-4 py-3 hover:bg-gray-50 transition-colors text-sm font-medium" active-class="bg-gray-50">
{{ item.label }}
</NuxtLink>
<transition @before-enter="beforeSubmenuEnter" @enter="submenuEnter" @leave="submenuLeave" :css="false">
<ul v-if="item.children.length > 0 && activeMobileSubmenu === index" class="bg-gray-50 pl-6 overflow-hidden">
<li v-for="(child, childIndex) in item.children" :key="childIndex" class="border-b border-gray-100 last:border-0">
<NuxtLink :to="child.url" @click="isMobileMenuOpen = false" class="block px-4 py-3 hover:bg-gray-100 transition-colors text-sm" active-class="bg-gray-100 font-medium">
{{ child.label }}
</NuxtLink>
</li>
</ul>
</transition>
</li>
</ul>
</div>
</transition>
</header>
</template>
<script setup>
const isMobileMenuOpen = ref(false);
const activeMobileSubmenu = ref(null);
const toggleMobileMenu = () => {
isMobileMenuOpen.value = !isMobileMenuOpen.value;
if (!isMobileMenuOpen.value) {
activeMobileSubmenu.value = null;
}
};
const toggleMobileSubmenu = index => {
activeMobileSubmenu.value = activeMobileSubmenu.value === index ? null : index;
};
// Animation functions for submenu
const beforeSubmenuEnter = el => {
el.style.height = "0";
el.style.overflow = "hidden";
};
const submenuEnter = (el, done) => {
const height = el.scrollHeight;
el.style.transition = "height 0.3s ease-out";
el.style.height = `${height}px`;
el.addEventListener("transitionend", done, { once: true });
};
const submenuLeave = (el, done) => {
el.style.transition = "height 0.2s ease-in";
el.style.height = "0";
el.addEventListener("transitionend", done, { once: true });
};
// Menu data
const mainMenuItems = ref([
{
label: "Trang chủ",
url: "/",
children: [],
},
{
label: "Giới thiệu",
url: "/introduce",
children: [
{ label: "Về chúng tôi", url: "/introduce/about_us" },
{ label: "Lịch sử hình thành", url: "/introduce/history" },
],
},
{
label: "Dự án",
url: "/project",
children: [
// { label: "D án đã hoàn thành", url: "/project/hoan-thanh" },
// { label: "D án đang thc hin", url: "/project/dang-thuc-hien" },
],
},
{
label: "Liên hệ",
url: "/contact",
children: [],
},
]);
// Close menu when route changes
const route = useRoute();
watch(
() => route.path,
() => {
isMobileMenuOpen.value = false;
activeMobileSubmenu.value = null;
},
);
</script>

View File

@ -0,0 +1,30 @@
<template>
<div class="bg-gray-100 py-16">
<div class="container mx-auto px-4">
<div class="flex flex-col md:flex-row items-center">
<div class="md:w-1/2 mb-8 md:mb-0 md:pr-8">
<NuxtImg placeholder="/placeholder.png" src="/home.jpg" alt="Về công ty" class="rounded-lg shadow-lg w-full" />
</div>
<div class="md:w-1/2">
<h2 class="text-3xl font-bold text-blue-800 mb-4">Công Ty Cổ Phần Vấn Xây Dựng 929</h2>
<p class="text-gray-700 mb-6">Với giấy chứng nhận kinh doanh số 4600796888 do Sở kế hoạch đầu tỉnh Thái Nguyên cấp, chúng tôi tự hào đơn vị vấn xây dựng uy tín tại Thái Nguyên các tỉnh lân cận.</p>
<div class="space-y-4">
<div class="flex items-start">
<svg class="w-6 h-6 text-blue-600 mt-1 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path>
</svg>
<span>Đăng lần đầu ngày 27/02/2010, đăng thay đổi lần 5 ngày 12/3/2025</span>
</div>
<div class="flex items-start">
<svg class="w-6 h-6 text-blue-600 mt-1 mr-2 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path>
</svg>
<span>Đội ngũ hơn 20 kỹ , kiến trúc giàu kinh nghiệm</span>
</div>
</div>
<NuxtLink to="/introduce/about_us" class="mt-8 px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-semibold inline-block"> Tìm hiểu thêm về chúng tôi </NuxtLink>
</div>
</div>
</div>
</div>
</template>

View File

@ -0,0 +1,41 @@
<template>
<div class="bg-blue-800 text-white py-16">
<div class="container mx-auto px-4">
<div class="text-center mb-12">
<h2 class="text-3xl font-bold mb-4">Tại sao chọn chúng tôi?</h2>
<p class="text-xl max-w-2xl mx-auto">Những giá trị khác biệt Công ty Cổ Phần vấn Xây dựng 929 mang lại</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<div class="text-center">
<div class="bg-blue-700 w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-10 h-10" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M6.267 3.455a3.066 3.066 0 001.745-.723 3.066 3.066 0 013.976 0 3.066 3.066 0 001.745.723 3.066 3.066 0 012.812 2.812c.051.643.304 1.254.723 1.745a3.066 3.066 0 010 3.976 3.066 3.066 0 00-.723 1.745 3.066 3.066 0 01-2.812 2.812 3.066 3.066 0 00-1.745.723 3.066 3.066 0 01-3.976 0 3.066 3.066 0 00-1.745-.723 3.066 3.066 0 01-2.812-2.812 3.066 3.066 0 00-.723-1.745 3.066 3.066 0 010-3.976 3.066 3.066 0 00.723-1.745 3.066 3.066 0 012.812-2.812zm7.44 5.252a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path>
</svg>
</div>
<h3 class="text-xl font-semibold mb-3">Chuyên môn cao</h3>
<p>Đội ngũ kỹ , kiến trúc hơn 15 năm kinh nghiệm trong ngành xây dựng</p>
</div>
<div class="text-center">
<div class="bg-blue-700 w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-10 h-10" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M12.316 3.051a1 1 0 01.633 1.265l-4 12a1 1 0 11-1.898-.632l4-12a1 1 0 011.265-.633zM5.707 6.293a1 1 0 010 1.414L3.414 10l2.293 2.293a1 1 0 11-1.414 1.414l-3-3a1 1 0 010-1.414l3-3a1 1 0 011.414 0zm8.586 0a1 1 0 011.414 0l3 3a1 1 0 010 1.414l-3 3a1 1 0 11-1.414-1.414L16.586 10l-2.293-2.293a1 1 0 010-1.414z" clip-rule="evenodd"></path>
</svg>
</div>
<h3 class="text-xl font-semibold mb-3">Quy trình chuyên nghiệp</h3>
<p>Áp dụng quy trình làm việc khoa học, đảm bảo tiến độ chất lượng công trình</p>
</div>
<div class="text-center">
<div class="bg-blue-700 w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-4">
<svg class="w-10 h-10" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z" clip-rule="evenodd"></path>
</svg>
</div>
<h3 class="text-xl font-semibold mb-3">Cam kết chất lượng</h3>
<p>Chất lượng nhiệm vụ hàng đầu trong mọi hoạt động sản xuất kinh doanh</p>
</div>
</div>
</div>
</div>
</template>

View File

@ -0,0 +1,51 @@
<template>
<div class="container mx-auto px-4 py-16">
<div class="text-center mb-12">
<h2 class="text-3xl font-bold text-blue-800 mb-4">Dịch vụ chính</h2>
<p class="text-gray-600 max-w-2xl mx-auto">Cung cấp các giải pháp toàn diện từ khảo sát, thiết kế đến thi công giám sát công trình</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
<div class="bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow">
<div class="text-blue-600 mb-4">
<svg class="w-12 h-12 mx-auto" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z" clip-rule="evenodd"></path>
</svg>
</div>
<h3 class="text-xl font-semibold text-center mb-3"> vấn thiết kế</h3>
<p class="text-gray-700 text-center">Lập dự án, khảo sát, thiết kế các công trình giao thông, dân dụng, công nghiệp hạ tầng kỹ thuật</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow">
<div class="text-blue-600 mb-4">
<svg class="w-12 h-12 mx-auto" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M6 6V5a3 3 0 013-3h2a3 3 0 013 3v1h2a2 2 0 012 2v3.57A22.952 22.952 0 0110 13a22.95 22.95 0 01-8-1.43V8a2 2 0 012-2h2zm2-1a1 1 0 011-1h2a1 1 0 011 1v1H8V5zm1 5a1 1 0 011-1h.01a1 1 0 110 2H10a1 1 0 01-1-1z" clip-rule="evenodd"></path>
<path d="M2 13.692V16a2 2 0 002 2h12a2 2 0 002-2v-2.308A24.974 24.974 0 0110 15c-2.796 0-5.487-.46-8-1.308z"></path>
</svg>
</div>
<h3 class="text-xl font-semibold text-center mb-3">Giám sát thi công</h3>
<p class="text-gray-700 text-center">Đảm bảo chất lượng công trình theo đúng thiết kế tiêu chuẩn kỹ thuật</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow">
<div class="text-blue-600 mb-4">
<svg class="w-12 h-12 mx-auto" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M11.17 3.5c.63-.24 1.29-.16 1.8.19.7.51 1.03 1.36.83 2.15-.2.8-.89 1.42-1.7 1.56-.8.14-1.62-.2-2.03-.9-.4-.7-.32-1.58.22-2.18.5-.57 1.3-.7 1.88-.42zm-4.85 2.03c.2-.8.89-1.42 1.7-1.56.8-.13 1.62.2 2.03.9.4.7.32 1.58-.22 2.18-.5.57-1.3.7-1.88.42-.63-.24-1.29-.16-1.8.19-.7.51-1.03 1.36-.83 2.15.2.8.89 1.42 1.7 1.56.8.14 1.62-.2 2.03-.9.4-.7.32-1.58-.22-2.18-.5-.57-1.3-.7-1.88-.42-.63.24-1.29.16-1.8-.19-.7-.51-1.03-1.36-.83-2.15zM15.85 8.62c.2-.8.89-1.42 1.7-1.56.8-.13 1.62.2 2.03.9.4.7.32 1.58-.22 2.18-.5.57-1.3.7-1.88.42-.63-.24-1.29-.16-1.8.19-.7.51-1.03 1.36-.83 2.15.2.8.89 1.42 1.7 1.56.8.14 1.62-.2 2.03-.9.4-.7.32-1.58-.22-2.18-.5-.57-1.3-.7-1.88-.42-.63.24-1.29.16-1.8-.19-.7-.51-1.03-1.36-.83-2.15z" clip-rule="evenodd"></path>
</svg>
</div>
<h3 class="text-xl font-semibold text-center mb-3">Hệ thống kỹ thuật</h3>
<p class="text-gray-700 text-center">Thiết kế hệ thống PCCC, tín hiệu giao thông, điện nội ngoại thất công trình</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md hover:shadow-lg transition-shadow">
<div class="text-blue-600 mb-4">
<svg class="w-12 h-12 mx-auto" fill="currentColor" viewBox="0 0 20 20">
<path d="M10 12a2 2 0 100-4 2 2 0 000 4z"></path>
<path fill-rule="evenodd" d="M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z" clip-rule="evenodd"></path>
</svg>
</div>
<h3 class="text-xl font-semibold text-center mb-3">Thẩm định dự án</h3>
<p class="text-gray-700 text-center">Thẩm tra, thẩm định thiết kế, tổng dự toán, dự toán các công trình xây dựng</p>
</div>
</div>
</div>
</template>

View File

@ -0,0 +1,63 @@
<template>
<ClientOnly>
<swiper-container ref="containerRef" :init="false">
<swiper-slide v-for="(slide, idx) in props.data" :key="idx">
<NuxtLink :to="slide.url" class="w-full h-full flex items-center justify-center">
<NuxtImg
:src="slide.img"
:alt="slide.img"
class="w-full h-full object-cover"
/>
</NuxtLink>
</swiper-slide>
</swiper-container>
</ClientOnly>
</template>
<script setup>
const props = defineProps({
data: {
type: Object,
// required: true,
default: () => [
{
img: 'https://fe.nguyenanh-est.com/Slide/Hocvathitructuyen.png',
alt: 'Slide 1',
url: '/Slide/bannertet.png',
},
{
img: 'https://fe.nguyenanh-est.com/Slide/Hocvathitructuyen.png',
alt: 'Slide 2',
url: '/Slide/Congthongtin.png',
},
{
img: 'https://fe.nguyenanh-est.com//Slide/Hocvathitructuyen.png',
alt: 'Slide 3',
url: '/Slide/Hocvathitructuyen.png',
},
{
img: 'https://fe.nguyenanh-est.com/Slide/Hocvathitructuyen.png',
alt: 'Slide 4',
url: '/Slide/Thediemdanhthongminh.png',
},
{
img: 'https://fe.nguyenanh-est.com/Slide/Hocvathitructuyen.png',
alt: 'Slide 5',
url: '/Slide/Thongtingiaoduc.png',
},
],
},
})
const containerRef = ref(null)
const swiper = useSwiper(containerRef, {
effect: 'Pagination',
loop: true,
autoplay: {
delay: 5000,
},
})
onMounted(() => {
console.log(swiper.instance)
})
</script>

11
docker-compose.yml Normal file
View File

@ -0,0 +1,11 @@
version: '3.8'
services:
fontend:
image: trungnghia1996/landing_page:deploy
environment:
HOST: 0.0.0.0
PORT: 3000
NUXT_PUBLIC_BASE_URL: https://api.nguyenanh-est.com
ports:
- 3000:3000

17
layouts/default.vue Normal file
View File

@ -0,0 +1,17 @@
<template>
<div class="w-full flex flex-col">
<!-- Header -->
<Header/>
<!-- Content Area -->
<div class="w-full flex overflow-hidden pt-[70px] md:pt-[80px]">
<div class=" overflow-y-auto">
<slot/>
<Footer />
</div>
</div>
</div>
</template>
<script setup>
</script>

15
nuxt.config.ts Normal file
View File

@ -0,0 +1,15 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: "2024-11-01",
devtools: { enabled: true },
modules: ["@nuxt/icon", "@nuxt/image", "@nuxtjs/tailwindcss", "nuxt-swiper", "@pinia/nuxt", "pinia-plugin-persistedstate/nuxt", "@ant-design-vue/nuxt"],
css: ["~/assets/css/tailwind.css"],
antd: { extractStyle: true },
pinia: { storesDirs: ["./stores/**"] },
runtimeConfig: {
mongodbUri: process.env.NUXT_PRIVATE_MONGODB_URI || "mongodb://localhost:27017",
mongodbName: process.env.NUXT_PRIVATE_MONGODB_NAME || "nuxt_app",
jwtSecret: process.env.NUXT_PRIVATE_JWT_SECRET || "default-secret",
jwtExpiresIn: process.env.NUXT_PRIVATE_JWT_EXPIRES_IN || "1d",
},
});

34
package.json Normal file
View File

@ -0,0 +1,34 @@
{
"name": "nuxt-app",
"private": true,
"type": "module",
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"dependencies": {
"@ant-design-vue/nuxt": "1.4.6",
"@iconify-json/material-symbols": "^1.2.20",
"@iconify-json/mdi": "^1.2.3",
"@nuxt/icon": "1.12.0",
"@nuxt/image": "1.10.0",
"@nuxtjs/tailwindcss": "6.14.0",
"@pinia/nuxt": "^0.11.0",
"@tailwindcss/line-clamp": "^0.4.4",
"@types/node": "^22.15.3",
"ant-design-vue": ">=4",
"bcryptjs": "^3.0.2",
"jsonwebtoken": "^9.0.2",
"mongodb": "^6.16.0",
"nuxt": "^3.17.0",
"nuxt-swiper": "2.0.0",
"pinia": "^3.0.2",
"pinia-plugin-persistedstate": "^4.2.0",
"vue": "^3.5.13",
"vue-router": "^4.5.1"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}

74
pages/contact.vue Normal file
View File

@ -0,0 +1,74 @@
<template>
<div class="min-h-screen bg-gray-50 flex items-center justify-center p-4">
<div class="bg-white rounded-2xl shadow-lg w-full max-w-7xl overflow-hidden">
<div class="grid grid-cols-1 md:grid-cols-2">
<!-- Thông tin công ty -->
<div class="bg-blue-600 text-white p-6 md:p-10 flex flex-col justify-center">
<h2 class="text-2xl md:text-3xl font-bold mb-4">Liên hệ với chúng tôi</h2>
<p class="mb-2 text-base md:text-lg"><strong>Tên công ty:</strong> Công ty Cổ Phần vấn Xây dựng 929</p>
<p class="mb-2 text-base md:text-lg"><strong>Địa chỉ:</strong> Tổ 7, đường 3-2, phường Tân Lập, TP Thái Nguyên</p>
<p class="mb-2 text-base md:text-lg"><strong>Điện thoại:</strong> 0986 108 999</p>
<p class="mb-2 text-base md:text-lg"><strong>Email:</strong> congty929@gmail.com.vn</p>
</div>
<!-- Form liên hệ -->
<div class="p-6 md:p-10">
<form class="space-y-6" @submit.prevent="handleSubmit">
<div>
<label class="block text-sm md:text-base font-medium text-gray-700">Họ tên</label>
<input v-model="form.name" type="text" class="mt-1 w-full px-4 py-2 md:px-5 md:py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Nhập họ và tên">
</div>
<div>
<label class="block text-sm md:text-base font-medium text-gray-700">Email</label>
<input v-model="form.email" type="email" class="mt-1 w-full px-4 py-2 md:px-5 md:py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Nhập email">
</div>
<div>
<label class="block text-sm md:text-base font-medium text-gray-700">Số điện thoại</label>
<input v-model="form.phone" type="text" class="mt-1 w-full px-4 py-2 md:px-5 md:py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Nhập số điện thoại">
</div>
<div>
<label class="block text-sm md:text-base font-medium text-gray-700">Nội dung</label>
<textarea v-model="form.message" rows="5" class="mt-1 w-full px-4 py-2 md:px-5 md:py-3 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="Nhập nội dung cần liên hệ"></textarea>
</div>
<button type="submit" class="w-full bg-blue-600 hover:bg-blue-700 text-white text-base md:text-lg font-semibold py-2 md:py-3 rounded-lg transition">Gửi liên hệ</button>
</form>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const form = ref({
name: '',
email: '',
phone: '',
message: ''
})
const handleSubmit = async () => {
try {
// Gi s gi đến API đây, ví d:
// await $fetch('/api/contact', {
// method: 'POST',
// body: form.value
// })
console.log('Dữ liệu gửi:', form.value)
alert('Gửi liên hệ thành công!')
form.value = { name: '', email: '', phone: '', message: '' }
} catch (err) {
console.error('Gửi thất bại:', err)
alert('Đã xảy ra lỗi, vui lòng thử lại.')
}
}
</script>
<style scoped>
/* Responsive điều chỉnh thêm nếu cần */
</style>

167
pages/index.vue Normal file
View File

@ -0,0 +1,167 @@
<template>
<div class="">
<!-- Hero Section -->
<div class="bg-blue-800 text-white overflow-hidden relative">
<div class="container mx-auto px-4 py-20 md:py-32">
<div class="z-10 max-w-2xl relative">
<h1 class="text-4xl md:text-5xl font-bold mb-4">Giải pháp xây dựng toàn diện</h1>
<p class="text-xl md:text-2xl mb-8">Với hơn 15 năm kinh nghiệm trong lĩnh vực vấn, thiết kế giám sát xây dựng</p>
<div class="flex flex-col sm:flex-row gap-4">
<NuxtLink to="/introduce/about_us" class="px-6 py-3 bg-white text-blue-800 rounded-lg hover:bg-gray-100 transition-colors font-semibold text-center"> Dịch vụ của chúng tôi </NuxtLink>
<NuxtLink to="/contact" class="px-6 py-3 border border-white text-white rounded-lg hover:bg-blue-700 transition-colors font-semibold text-center"> Liên hệ ngay </NuxtLink>
</div>
</div>
<div class="absolute right-0 top-0 h-full w-1/2 bg-blue-700 transform skew-x-12 origin-top-right hidden lg:block"></div>
</div>
</div>
<!-- Services Section -->
<Index_Services />
<!-- About Section -->
<Index_About />
<!-- Projects Section -->
<div class="container mx-auto px-4 py-16">
<div class="text-center mb-12">
<h2 class="text-3xl font-bold text-blue-800 mb-4">Dự án tiêu biểu</h2>
<p class="text-gray-600 max-w-2xl mx-auto">Chúng tôi đã thực hiện hơn 100 dự án từ quy nhỏ đến lớn tại Thái Nguyên các tỉnh lân cận</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div v-for="(project, index) in projects" :key="index" class="bg-white rounded-lg overflow-hidden shadow-md hover:shadow-lg transition-shadow cursor-pointer" @click="openModal(project)">
<NuxtImg placeholder="/placeholder.png" :src="project.images[0]" :alt="project.name" class="w-full h-48 object-cover" />
<div class="p-6">
<h3 class="text-xl font-semibold mb-2">{{ project.name }}</h3>
<p class="text-gray-600 mb-3">{{ project.location }}</p>
<p class="text-gray-700 mb-4">{{ project.description }}</p>
<div class="flex justify-between items-center">
<span class="text-sm text-blue-600">{{ project.year }}</span>
<span class="text-blue-600 hover:text-blue-800 font-medium">Xem chi tiết </span>
</div>
</div>
</div>
</div>
<div class="text-center mt-10">
<NuxtLink to="/project" class="px-6 py-3 border border-blue-600 text-blue-600 rounded-lg hover:bg-blue-50 transition-colors font-semibold inline-block"> Xem tất cả dự án </NuxtLink>
</div>
</div>
<!-- Why Choose Us Section -->
<Index_Choose/>
<!-- CTA Section -->
<div class="bg-blue-600 text-white py-16">
<div class="container mx-auto px-4 text-center">
<h2 class="text-3xl font-bold mb-6">Bạn cần vấn về dự án xây dựng?</h2>
<p class="text-xl mb-8 max-w-2xl mx-auto">Liên hệ ngay với chúng tôi để được hỗ trợ vấn miễn phí</p>
<div class="flex flex-col sm:flex-row justify-center gap-4">
<NuxtLink to="/contact" class="px-6 py-3 bg-white text-blue-800 rounded-lg hover:bg-gray-100 transition-colors font-semibold"> Gửi yêu cầu </NuxtLink>
<NuxtLink to="/contact" class="flex items-center justify-center px-6 py-3 border border-white rounded-lg hover:bg-blue-500 transition-colors">
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path d="M2 3a1 1 0 011-1h2.153a1 1 0 01.986.836l.74 4.435a1 1 0 01-.54 1.06l-1.548.773a11.037 11.037 0 006.105 6.105l.774-1.548a1 1 0 011.059-.54l4.435.74a1 1 0 01.836.986V17a1 1 0 01-1 1h-2C7.82 18 2 12.18 2 5V3z"></path>
</svg>
<span>0986 108 999</span>
</NuxtLink>
</div>
</div>
</div>
<!-- Project Modal using Ant Design -->
<a-modal v-model:open="isModalOpen" :title="selectedProject?.name" width="80%" :footer="null" @cancel="closeModal">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<a-carousel arrows autoplay>
<div v-for="(image, index) in selectedProject?.images" :key="index">
<NuxtImg placeholder="/placeholder.png" :src="image" :alt="`${selectedProject?.name} - Ảnh ${index + 1}`" class="w-full h-auto rounded-lg" />
</div>
</a-carousel>
</div>
<div>
<div class="mb-6">
<h4 class="text-lg font-semibold text-blue-700 mb-2">Thông tin dự án</h4>
<div class="space-y-2">
<p class="text-gray-700"><span class="font-medium">Địa điểm:</span> {{ selectedProject?.location }}</p>
<!-- <p class="text-gray-700"><span class="font-medium">Năm thực hiện:</span> {{ selectedProject?.year }}</p> -->
<!-- <p class="text-gray-700"><span class="font-medium">Chủ đầu :</span> {{ selectedProject?.investor }}</p> -->
</div>
</div>
<div class="mb-6">
<h4 class="text-lg font-semibold text-blue-700 mb-2"> tả dự án</h4>
<p class="text-gray-700">{{ selectedProject?.description }}</p>
</div>
<div>
<h4 class="text-lg font-semibold text-blue-700 mb-2">Dịch vụ cung cấp</h4>
<p class="text-gray-700">{{ selectedProject?.services }}</p>
</div>
</div>
</div>
</a-modal>
</div>
</template>
<script setup>
import { ref } from "vue";
import { Modal as AModal, Carousel as ACarousel } from "ant-design-vue";
const isModalOpen = ref(false);
const selectedProject = ref(null);
const projects = ref([
{
name: "Cải tạo, nâng cấp đường Hương Sơn, TP Thái Nguyên",
location: "Thái Nguyên",
year: "",
investor: "UBND P.Hương Sơn",
description: "Dự án cải tạo, nâng cấp đường Hương Sơn với chiều dài 1.2km, mặt đường rộng 7m. Bao gồm các hạng mục: san lấp mặt bằng, hệ thống thoát nước, chiếu sáng công cộng.",
services: "Tư vấn thiết kế",
images: ["/images/projects/duong-huong-son.jpg", "/images/projects/duong-huong-son-1.jpg"],
},
{
name: "Xử lý đất thừa, kè ốp mái ta luy dương và bổ sung rãnh thoát nước nút giao Tân Lập trên QL3 mới tỉnh Thái Nguyên",
location: "Thái Nguyên",
year: "",
investor: "Sở Giao thông vận tải Thái Nguyên",
description: "Dự án xử lý đất thừa, kè ốp mái taluy dương và bổ sung rãnh thoát nước tại nút giao Tân Lập trên QL3, giúp cải thiện an toàn giao thông và hệ thống thoát nước.",
services: "Tư vấn thiết kế",
images: ["/images/projects/tan-lap-ql3.jpg", "/images/projects/tan-lap-ql3-1.jpg", "/images/projects/tan-lap-ql3-2.jpg"],
},
{
name: "Các công trình cải tạo đường GTNT, cầu bê tông cốt thép tại Thái Nguyên, Bắc Kạn",
location: "Thành phố Thái Nguyên - Bắc Kạn",
year: "",
investor: "Ban CHQS huyện Phú Lương",
description: "Các công trình cải tạo đường GTNT, cầu bê tông cốt thép tại Thái Nguyên, Bắc Kạn",
services: "Tư vấn thiết kế",
images: ["/images/projects/gtnt-bac-kan-2.jpg", "/images/projects/gtnt-bac-kan-3.jpg", "/images/projects/gtnt-bac-kan-4.jpg"],
},
]);
const openModal = project => {
selectedProject.value = project;
isModalOpen.value = true;
};
const closeModal = () => {
isModalOpen.value = false;
};
</script>
<style>
/* Custom styles for Ant Design components */
.ant-modal-title {
@apply text-2xl font-bold text-blue-800;
}
.ant-carousel .slick-slide {
@apply px-2;
}
.ant-carousel .slick-arrow {
@apply text-blue-600;
}
.ant-carousel .slick-arrow:hover {
@apply text-blue-800;
}
</style>

View File

@ -0,0 +1,156 @@
<template>
<div class="bg-gray-50">
<!-- Hero Section -->
<div class="bg-gradient-to-r from-blue-800 to-blue-600 text-white py-16 md:py-24">
<div class="container mx-auto px-4">
<h1 class="text-3xl md:text-5xl font-bold mb-4">Công Ty Cổ Phần Vấn Xây Dựng 929</h1>
<p class="text-xl md:text-2xl max-w-3xl">Uy tín - Chất lượng - Tiến độ - Giá thành hiệu quả</p>
</div>
</div>
<!-- About Section -->
<About_Section />
<About_Activity />
<!-- Experience Section -->
<div class="container mx-auto px-4 py-12 md:py-16">
<h2 class="text-2xl md:text-3xl font-bold text-center text-blue-800 mb-12">Dự án tiêu biểu</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div v-for="project in projects" :key="project.TT" class="bg-white rounded-lg overflow-hidden shadow-md hover:shadow-lg transition-shadow cursor-pointer" @click="openModal(project)">
<NuxtImg placeholder="/placeholder.png" :src="project.image" :alt="project.project" class="w-full h-48 object-cover" />
<div class="p-6">
<h3 class="text-xl font-semibold mb-2">{{ project.project }}</h3>
<p class="text-gray-600 mb-3">{{ project.investor }}</p>
<p class="text-gray-700">{{ project.consulting_work }}</p>
</div>
</div>
</div>
<div class="text-center mt-8">
<NuxtLink to="/project" class="inline-block px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"> Xem thêm dự án </NuxtLink>
</div>
</div>
<!-- Project Modal using AntDV -->
<a-modal v-model:open="isModalOpen" :title="selectedProject?.name" width="80%" :footer="null" @cancel="closeModal">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<a-carousel arrows autoplay>
<template #prevArrow>
<div class="custom-slick-arrow" style="left: 10px; z-index: 1">
<left-circle-outlined />
</div>
</template>
<template #nextArrow>
<div class="custom-slick-arrow" style="right: 10px">
<right-circle-outlined />
</div>
</template>
<div v-for="(image, index) in selectedProject?.gallery" :key="index">
<NuxtImg placeholder="/placeholder.png" :src="image" :alt="`${selectedProject?.name} - Ảnh ${index + 1}`" class="w-full h-auto rounded-lg" />
</div>
</a-carousel>
</div>
<div>
<div class="mb-6">
<h4 class="text-lg font-semibold text-blue-700 mb-2">Thông tin dự án</h4>
<div class="space-y-2">
<p class="text-gray-700"><span class="font-medium">Địa điểm:</span> {{ selectedProject?.investor }}</p>
</div>
</div>
<div class="mb-6">
<h4 class="text-lg font-semibold text-blue-700 mb-2"> tả dự án</h4>
<p class="text-gray-700">{{ selectedProject?.description }}</p>
</div>
<div>
<h4 class="text-lg font-semibold text-blue-700 mb-2">Dịch vụ cung cấp</h4>
<p class="text-gray-700">{{ selectedProject?.consulting_work }}</p>
</div>
</div>
</div>
</a-modal>
<About_Team />
<About_Working />
<About_Contact />
</div>
</template>
<script setup>
import { ref } from "vue";
import { Modal as AModal, Carousel as ACarousel } from "ant-design-vue";
const isModalOpen = ref(false);
const selectedProject = ref(null);
const projects = ref([
{
TT: 1,
project: "Cải tạo, nâng cấp đường Hương Sơn, TP Thái Nguyên",
consulting_work: "Tư vấn thiết kế",
investor: "UBND P.Hương Sơn",
image: "/images/projects/duong-huong-son.jpg",
gallery: ["/images/projects/duong-huong-son.jpg", "/images/projects/duong-huong-son-1.jpg"],
description: "Dự án cải tạo, nâng cấp đường Hương Sơn với chiều dài 1.2km, mặt đường rộng 7m. Bao gồm các hạng mục: san lấp mặt bằng, hệ thống thoát nước, chiếu sáng công cộng.",
},
{
TT: 2,
project: "Xử lý đất thừa, kè ốp mái ta luy dương và bổ sung rãnh thoát nước nút giao Tân Lập trên QL3 mới tỉnh Thái Nguyên",
consulting_work: "Tư vấn thiết kế",
investor: "Sở Giao thông vận tải Thái Nguyên",
image: "/images/projects/tan-lap-ql3.jpg",
gallery: ["/images/projects/tan-lap-ql3.jpg", "/images/projects/tan-lap-ql3-1.jpg", "/images/projects/tan-lap-ql3-2.jpg"],
description: "Dự án xử lý đất thừa, kè ốp mái taluy dương và bổ sung rãnh thoát nước tại nút giao Tân Lập trên QL3, giúp cải thiện an toàn giao thông và hệ thống thoát nước.",
},
// {
// TT: 4,
// project: "Ci to, nâng cp đưng Lưu Nhân Chú và trc đưng vào phưng Hương Sơn TPTN",
// consulting_work: "Tư vn thiết kế",
// investor: "UBND phưng Hương Sơn",
// image: "/images/projects/luu-nhan-chu.jpg",
// gallery: ["/images/projects/luu-nhan-chu-1.jpg", "/images/projects/luu-nhan-chu-2.jpg"],
// description: "D án ci to, nâng cp đưng Lưu Nhân Chú và trc đưng vào phưng Hương Sơn vi mc tiêu ci thin giao thông khu vc, tăng cưng kết ni h tng đô th.",
// },
{
TT: 5,
project: "Các công trình cải tạo đường GTNT, cầu bê tông cốt thép tại Thái Nguyên, Bắc Kạn",
consulting_work: "Tư vấn thiết kế",
investor: "Thành phố Thái Nguyên - Bắc Kạn",
image: "/images/projects/gtnt-bac-kan.jpg",
gallery: ["/images/projects/gtnt-bac-kan-2.jpg", "/images/projects/gtnt-bac-kan-3.jpg", "/images/projects/gtnt-bac-kan-4.jpg"],
description: "Tập hợp các công trình tư vấn thiết kế tại Thái Nguyên và Bắc Kạn, bao gồm cải tạo đường giao thông nông thôn, xây dựng cầu bê tông cốt thép và hạ tầng liên quan.",
},
]);
const openModal = project => {
selectedProject.value = project;
isModalOpen.value = true;
};
const closeModal = () => {
isModalOpen.value = false;
};
</script>
<style>
/* Custom style for carousel dots */
.ant-carousel :deep(.slick-dots) {
position: relative;
height: auto;
}
.ant-carousel :deep(.slick-dots li) {
width: auto;
height: auto;
margin: 0 4px;
}
.ant-carousel :deep(.slick-dots li button) {
width: 10px;
height: 10px;
border-radius: 50%;
background: #ccc;
}
.ant-carousel :deep(.slick-dots li.slick-active button) {
background: #1890ff;
}
</style>

176
pages/introduce/history.vue Normal file
View File

@ -0,0 +1,176 @@
<template>
<div class="container mx-auto px-4 py-8">
<!-- Header Section -->
<header class="mb-10 text-center">
<h1 class="text-3xl md:text-4xl font-bold text-blue-800 mb-4">Lịch sử hình thành</h1>
<div class="w-24 h-1 bg-orange-500 mx-auto"></div>
</header>
<!-- Timeline Section -->
<div class="relative">
<!-- Timeline line -->
<div class="hidden md:block absolute left-1/2 w-1 h-full bg-gray-200 transform -translate-x-1/2"></div>
<!-- Timeline items -->
<div class="space-y-8 md:space-y-16">
<!-- 2010 - Thành lập -->
<div class="relative flex flex-col md:flex-row items-center">
<div class="md:w-1/2 md:pr-8 md:text-right mb-4 md:mb-0">
<!-- <div class="md:hidden absolute left-0 top-4 w-4 h-4 rounded-full bg-blue-600 -ml-2"></div> -->
<h2 class="text-2xl font-bold text-blue-700">2010</h2>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Thành lập công ty</h3>
<p class="text-gray-600">
Công ty Cổ Phần vấn Xây dựng 929 được thành lập ngày 27/02/2010 với giấy chứng nhận kinh doanh số 4600796888 do Sở Kế hoạch Đầu tỉnh Thái Nguyên cấp.
</p>
</div>
<!-- <div class="hidden md:block w-12 h-12 rounded-full bg-blue-600 flex items-center justify-center text-white font-bold mx-4 flex-shrink-0">
2010
</div> -->
<div class="md:w-1/2 md:pl-8">
<div class="bg-white p-6 rounded-lg shadow-md border-l-4 border-blue-500">
<h4 class="font-bold text-gray-800 mb-2">Thông tin ban đầu:</h4>
<ul class="list-disc pl-5 text-gray-600 space-y-1">
<!-- <li>Vốn điều lệ: 1.966 tỷ đồng</li> -->
<li>Trụ sở: Tổ 7 phường Tân Lập, TP Thái Nguyên</li>
<li>Ngành nghề chính: vấn xây dựng, khảo sát, thiết kế</li>
</ul>
</div>
</div>
</div>
<!-- 2015 - Phát triển -->
<div class="relative flex flex-col md:flex-row items-center">
<div class="md:w-1/2 md:pr-8 md:text-right order-2 md:order-1 mb-4 md:mb-0">
<!-- <div class="md:hidden absolute left-0 top-4 w-4 h-4 rounded-full bg-orange-500 -ml-2"></div> -->
<h2 class="text-2xl font-bold text-orange-600">2015</h2>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Giai đoạn phát triển</h3>
<p class="text-gray-600">
Công ty mở rộng hoạt động ra các tỉnh lân cận, thực hiện nhiều dự án lớn về hạ tầng giao thông xây dựng dân dụng.
</p>
</div>
<!-- <div class="hidden md:block w-12 h-12 rounded-full bg-orange-500 flex items-center justify-center text-white font-bold mx-4 flex-shrink-0 order-1">
2015
</div> -->
<div class="md:w-1/2 md:pl-8 order-3">
<div class="bg-white p-6 rounded-lg shadow-md border-l-4 border-orange-500">
<h4 class="font-bold text-gray-800 mb-2">Dự án tiêu biểu:</h4>
<ul class="list-disc pl-5 text-gray-600 space-y-1">
<li>Các công trình GTNT trên địa bàn tỉnh Thái Nguyên Bắc Kạn</li>
<li>Một số công trình Trung tâm văn hóa thể thao, trường Mầm non trên địa bàn tỉnh Thái Nguyên</li>
</ul>
</div>
</div>
</div>
<!-- 2020 - Mở rộng -->
<div class="relative flex flex-col md:flex-row items-center">
<div class="md:w-1/2 md:pr-8 md:text-right mb-4 md:mb-0">
<!-- <div class="md:hidden absolute left-0 top-4 w-4 h-4 rounded-full bg-green-600 -ml-2"></div> -->
<h2 class="text-2xl font-bold text-green-700">2020</h2>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Mở rộng quy </h3>
<p class="text-gray-600">
Công ty mở rộng sang lĩnh vực giám sát thi công, quản dự án thực hiện các dự án tại nhiều tỉnh thành khác như Nội, Bắc Kạn.
</p>
</div>
<!-- <div class="hidden md:block w-12 h-12 rounded-full bg-green-600 flex items-center justify-center text-white font-bold mx-4 flex-shrink-0">
2020
</div> -->
<div class="md:w-1/2 md:pl-8">
<div class="bg-white p-6 rounded-lg shadow-md border-l-4 border-green-500">
<h4 class="font-bold text-gray-800 mb-2">Thành tựu:</h4>
<ul class="list-disc pl-5 text-gray-600 space-y-1">
<li>Thực hiện hơn 100 dự án các loại</li>
<li>Mở rộng đội ngũ lên 30+ kỹ , kiến trúc </li>
<li>Đầu trang thiết bị hiện đại</li>
</ul>
</div>
</div>
</div>
<!-- 2025 - Hiện tại -->
<div class="relative flex flex-col md:flex-row items-center">
<div class="md:w-1/2 md:pr-8 md:text-right order-2 md:order-1 mb-4 md:mb-0">
<!-- <div class="md:hidden absolute left-0 top-4 w-4 h-4 rounded-full bg-purple-600 -ml-2"></div> -->
<h2 class="text-2xl font-bold text-purple-700">2025</h2>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Hiện tại</h3>
<p class="text-gray-600">
Công ty tiếp tục phát triển với phương châm "Uy tín - Chất lượng - Tiến độ - Giá thành và hiệu quả", không ngừng cải tiến nâng cao năng lực.
</p>
</div>
<!-- <div class="hidden md:block w-12 h-12 rounded-full bg-purple-600 flex items-center justify-center text-white font-bold mx-4 flex-shrink-0 order-1">
2025
</div> -->
<div class="md:w-1/2 md:pl-8 order-3">
<div class="bg-white p-6 rounded-lg shadow-md border-l-4 border-purple-500">
<h4 class="font-bold text-gray-800 mb-2">Thông tin hiện tại:</h4>
<ul class="list-disc pl-5 text-gray-600 space-y-1">
<li>Đăng thay đổi lần 5 ngày 12/3/2025</li>
<li>Đội ngũ nhân sự chủ chốt: 30+ người</li>
<li>Máy móc thiết bị hiện đại phục vụ công tác khảo sát, thiết kế</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Values Section -->
<div class="mt-20">
<h2 class="text-2xl md:text-3xl font-bold text-center text-blue-800 mb-8">Phương châm hoạt động</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="bg-white p-6 rounded-lg shadow-md border-t-4 border-blue-500">
<div class="text-blue-500 text-3xl mb-4">
<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
</svg>
</div>
<h3 class="text-xl font-bold text-gray-800 mb-2">Chất lượng</h3>
<p class="text-gray-600">
Luôn đặt chất lượng sản phẩm vấn lên hàng đầu, tuân thủ quy trình kỹ thuật tiêu chuẩn xây dựng.
</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md border-t-4 border-orange-500">
<div class="text-orange-500 text-3xl mb-4">
<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<h3 class="text-xl font-bold text-gray-800 mb-2">Tiến độ</h3>
<p class="text-gray-600">
Cam kết hoàn thành đúng tiến độ theo hợp đồng, đảm bảo kế hoạch triển khai dự án của khách hàng.
</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md border-t-4 border-green-500">
<div class="text-green-500 text-3xl mb-4">
<svg xmlns="http://www.w3.org/2000/svg" class="h-12 w-12" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
</svg>
</div>
<h3 class="text-xl font-bold text-gray-800 mb-2">Chuyên nghiệp</h3>
<p class="text-gray-600">
Đội ngũ nhân sự giàu kinh nghiệm, không ngừng học hỏi ứng dụng công nghệ mới trong công tác vấn.
</p>
</div>
</div>
</div>
</div>
</template>
<script setup>
// Bn có th thêm các logic cn thiết đây
</script>
<style scoped>
/* Thêm các style tùy chỉnh nếu cần */
</style>

View File

@ -0,0 +1,8 @@
<template>
<div class="container mx-auto">
</div>
</template>
<script setup>
await navigateTo("/introduce/about_us")
</script>

463
pages/project/index.vue Normal file
View File

@ -0,0 +1,463 @@
<template>
<div class="bg-gray-50">
<!-- Hero Section -->
<div class="relative bg-blue-800 text-white py-20 md:py-32">
<div class="container mx-auto px-4 text-center">
<h1 class="text-4xl md:text-5xl font-bold mb-4">Dự án tiêu biểu</h1>
<p class="text-xl md:text-2xl max-w-2xl mx-auto">Hơn 200 dự án đã thực hiện tại Thái Nguyên các tỉnh lân cận</p>
</div>
</div>
<!-- Projects Filter -->
<div class="container mx-auto px-4 py-12">
<!-- <div class="mb-8">
<a-radio-group v-model:value="activeCategory" button-style="solid" @change="filterProjects" class="w-full overflow-x-auto pb-2">
<a-radio-button v-for="category in categories" :key="category" :value="category" class="whitespace-nowrap">
{{ category }}
</a-radio-button>
</a-radio-group>
</div> -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<div v-for="(project, index) in paginatedProjects" :key="index" class="bg-white rounded-lg overflow-hidden shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1">
<!-- Project Image -->
<div class="h-48 overflow-hidden">
<NuxtImg placeholder="/placeholder.png" :src="project.image" :alt="project.project" class="w-full h-full object-cover transition-transform duration-500 hover:scale-105" />
</div>
<div class="p-6">
<div class="flex items-start mb-4">
<div class="bg-blue-100 p-3 rounded-full mr-4 transition-colors duration-200 group-hover:bg-blue-200">
<svg class="w-6 h-6 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"></path>
</svg>
</div>
<div>
<h3 class="text-xl font-bold mb-2 line-clamp-2">{{ shortenProjectName(project.project) }}</h3>
<p class="text-gray-500 text-sm mb-3"><span class="font-medium">Chủ đầu :</span> {{ project.investor || "" }}</p>
</div>
</div>
<div class="flex justify-between items-center border-t pt-4">
<a-tag :color="project.consulting_work.includes('thiết kế') ? 'blue' : 'green'">
{{ project.consulting_work }}
</a-tag>
<a-button type="link" @click="openModal(project)" class="flex items-center p-0">
Chi tiết
<template #icon><right-outlined /></template>
</a-button>
</div>
</div>
</div>
</div>
<!-- Pagination -->
<div class="flex justify-center mt-12" v-if="filteredProjects.length > projectsPerPage">
<a-pagination v-model:current="currentPage" :total="filteredProjects.length" :pageSize="projectsPerPage" show-less-items />
</div>
</div>
<!-- Project Modal - Redesigned -->
<a-modal
v-model:open="isModalOpen"
:title="null"
width="100%"
:footer="null"
@cancel="closeModal"
class="max-w-2xl"
:wrap-class-name="'project-modal'"
:closable="false"
>
<div class="modal-content">
<!-- Close Button (Mobile) -->
<button
@click="closeModal"
class="absolute top-4 right-4 z-50 bg-white/80 rounded-full p-2 shadow-md sm:hidden"
>
<close-outlined class="text-lg" />
</button>
<!-- Image Gallery -->
<div class="relative">
<a-carousel
v-if="selectedProject?.gallery?.length > 0"
dots-class="custom-dots"
class="project-gallery"
>
<div v-for="(img, idx) in selectedProject.gallery" :key="idx" class="carousel-image">
<NuxtImg
placeholder="/placeholder.png"
:src="img"
class="w-full h-48 sm:h-64 object-cover"
/>
</div>
</a-carousel>
<div v-else class="h-48 sm:h-64 bg-gray-200 flex items-center justify-center">
<NuxtImg
placeholder="/placeholder.png"
:src="selectedProject?.image"
class="w-full h-full object-cover"
/>
</div>
</div>
<!-- Project Info -->
<div class="p-4">
<!-- Project Title -->
<h3 class="text-xl font-bold text-gray-800 mb-1">
{{ selectedProject?.project }}
</h3>
<!-- Investor -->
<p class="text-gray-600 text-sm mb-3">
{{ selectedProject?.investor || "Không có thông tin" }}
</p>
<!-- Work Type Badge -->
<a-tag
:color="selectedProject?.consulting_work.includes('thiết kế') ? 'blue' : 'green'"
class="mb-4"
>
{{ selectedProject?.consulting_work }}
</a-tag>
<!-- Project Description -->
<div class="mb-4">
<div class="text-blue-700 font-medium mb-2"> tả dự án</div>
<p class="text-gray-700 text-sm whitespace-pre-line">
{{ selectedProject?.description || "Không có mô tả" }}
</p>
</div>
<!-- Action Buttons -->
<div class="flex justify-between mt-6">
<a-button
type="primary"
@click="closeModal"
class="flex-1 sm:hidden"
>
Đóng
</a-button>
<a-button
v-if="selectedProject?.gallery?.length > 1"
type="default"
@click="openGalleryFullscreen"
class="hidden sm:inline-flex items-center"
>
<picture-outlined class="mr-1" />
Xem hình ảnh
</a-button>
</div>
</div>
</div>
</a-modal>
<!-- Fullscreen Gallery Modal -->
<a-modal
v-model:open="isGalleryFullscreen"
:title="'Hình ảnh dự án'"
width="100%"
:footer="null"
@cancel="isGalleryFullscreen = false"
class="gallery-fullscreen"
:wrap-class-name="'gallery-modal'"
>
<a-carousel
v-if="selectedProject?.gallery?.length > 0"
arrows
dots-class="custom-dots"
class="fullscreen-gallery"
>
<div v-for="(img, idx) in selectedProject.gallery" :key="idx" class="carousel-image">
<NuxtImg
placeholder="/placeholder.png"
:src="img"
class="w-full h-full object-contain"
/>
</div>
</a-carousel>
</a-modal>
<!-- Stats Section -->
<div class="bg-blue-500 text-white py-16">
<div class="container mx-auto px-4">
<div class="grid grid-cols-2 md:grid-cols-4 gap-8 text-center">
<div>
<div class="text-4xl md:text-5xl font-bold mb-2">200+</div>
<div class="text-lg">Dự án đã hoàn thành</div>
</div>
<div>
<div class="text-4xl md:text-5xl font-bold mb-2">15+</div>
<div class="text-lg">Năm kinh nghiệm</div>
</div>
<div>
<div class="text-4xl md:text-5xl font-bold mb-2">20+</div>
<div class="text-lg">Kỹ , kiến trúc </div>
</div>
<div>
<div class="text-4xl md:text-5xl font-bold mb-2">10+</div>
<div class="text-lg">Tỉnh thành hoạt động</div>
</div>
</div>
</div>
</div>
<!-- CTA Section -->
<div class="bg-blue-600 text-white py-16">
<div class="container mx-auto px-4 text-center">
<h2 class="text-3xl font-bold mb-6">Bạn cần vấn về dự án xây dựng?</h2>
<p class="text-xl mb-8 max-w-2xl mx-auto">Liên hệ ngay với chúng tôi để được hỗ trợ vấn miễn phí</p>
<div class="flex flex-col sm:flex-row justify-center gap-4">
<NuxtLink to="/contact" class="px-6 py-3 bg-white text-blue-800 rounded-lg hover:bg-gray-100 transition-colors font-semibold"> Gửi yêu cầu </NuxtLink>
<NuxtLink to="/contact" class="flex items-center justify-center px-6 py-3 border border-white rounded-lg hover:bg-blue-500 transition-colors">
<phone-outlined class="mr-2" />
<span>0986 108 999</span>
</NuxtLink>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { RightOutlined, CloseOutlined, PictureOutlined, PhoneOutlined } from '@ant-design/icons-vue';
const projects = ref([
{
TT: 1,
project: "Cải tạo, nâng cấp đường Hương Sơn, TP Thái Nguyên",
consulting_work: "Tư vấn thiết kế",
investor: "UBND phường Hương Sơn TPTN",
image: "/images/projects/duong-huong-son.jpg",
gallery: ["/images/projects/duong-huong-son.jpg", "/images/projects/duong-huong-son-1.jpg"],
description: "Dự án cải tạo, nâng cấp đường Hương Sơn dài 1.2km, mặt đường rộng 7m, gồm san lấp mặt bằng, hệ thống thoát nước, chiếu sáng công cộng.",
},
{
TT: 2,
project: "Xử lý đất thừa, kè ốp mái taluy dương và bổ sung rãnh thoát nước nút giao Tân Lập trên QL3 mới tỉnh Thái Nguyên",
consulting_work: "Tư vấn thiết kế",
investor: "Sở Giao thông vận tải Thái Nguyên",
image: "/images/projects/tan-lap-ql3.jpg",
gallery: ["/images/projects/tan-lap-ql3.jpg", "/images/projects/tan-lap-ql3-1.jpg", "/images/projects/tan-lap-ql3-2.jpg"],
description: "Dự án xử lý đất thừa, kè mái taluy dương và bổ sung rãnh thoát nước tại nút giao Tân Lập, giúp cải thiện an toàn giao thông và hệ thống thoát nước.",
},
{
TT: 3,
project: "Xây dựng, nâng cấp doanh trại Ban CHQS huyện Phú Lương",
consulting_work: "Tư vấn thiết kế",
investor: "Bộ Chỉ huy Quân Sự tỉnh Thái Nguyên",
image: "/images/projects/ban-chqs-phu-luong.jpg",
gallery: ["/images/projects/ban-chqs-phu-luong.jpg"],
description: "Dự án xây dựng, nâng cấp doanh trại Ban CHQS huyện Phú Lương gồm đường vào đơn vị, cổng chính, sân, cải tạo nhà bếp ăn, nâng cao cơ sở vật chất.",
},
{
TT: 4,
project: "Cải tạo, nâng cấp đường Lưu Nhân Chú và nhánh đường vào UBND phường Hương Sơn TPTN",
consulting_work: "Tư vấn thiết kế",
investor: "UBND phường Hương Sơn TPTN",
image: "/images/projects/luu-nhan-chu.jpg",
gallery: ["/images/projects/luu-nhan-chu-1.jpg", "/images/projects/luu-nhan-chu-2.jpg"],
description: "Dự án cải tạo, nâng cấp đường Lưu Nhân Chú và nhánh vào UBND phường Hương Sơn nhằm cải thiện giao thông và hạ tầng khu vực.",
},
{
TT: 5,
project: "Sửa chữa, nâng cấp tuyến đường giao thông từ trụ sở UBND xã Tân Khánh đi Hoàng Mai huyện Phú Bình",
consulting_work: "Tư vấn thiết kế",
investor: "Ban QLDA ĐTXD huyện Phú Bình, tỉnh Thái Nguyên",
image: "/images/projects/_5.jpg",
gallery: ["/images/projects/_5.jpg"],
description: "Dự án nâng cấp tuyến đường giao thông kết nối UBND xã Tân Khánh đi Hoàng Mai, nâng cao chất lượng hạ tầng giao thông nông thôn.",
},
{
TT: 6,
project: "Nâng cấp, mở rộng tuyến đường Lương Thế Vinh TP Thái Nguyên",
consulting_work: "Tư vấn thiết kế",
investor: "UBND phường Quang Trung",
image: "/images/projects/6.jpg",
gallery: ["/images/projects/6.jpg"],
description: "Dự án nâng cấp, mở rộng tuyến đường Lương Thế Vinh, giúp mở rộng lưu thông, giảm ùn tắc giao thông đô thị.",
},
{
TT: 7,
project: "Cải tạo, nâng cấp khuôn viên đài tưởng niệm liệt sỹ xã Quyết Thắng TPTN",
consulting_work: "Tư vấn thiết kế",
investor: "UBND xã Quyết Thắng",
image: "/images/projects/_7.jpg",
gallery: ["/images/projects/_7.jpg"],
description: "Cải tạo, nâng cấp khuôn viên đài tưởng niệm liệt sỹ xã Quyết Thắng TPTN",
},
{
TT: 8,
project: "Đường GTNT xã Thịnh Đức TP Thái Nguyên",
consulting_work: "Tư vấn thiết kế",
investor: "UBND xã Thịnh Đức TPTN",
image: "/images/projects/_8.jpg",
gallery: ["/images/projects/_8.jpg"],
description: "Dự án đường giao thông nông thôn tại xã Thịnh Đức gồm các xóm Ao Sen, Cây Thị, Đồng Chanh, Đức Cường, Đầu Phần, Tân Đức, góp phần phát triển hạ tầng nông thôn.",
},
{
TT: 9,
project: "Nâng cấp, cải tạo đường vào Công ty CP Giấy Hoàng Văn Thụ, phường Quan Triều TP Thái Nguyên",
consulting_work: "Tư vấn thiết kế",
investor: "UBND phường Quan Triều - TPTN",
image: "/images/projects/9.jpg",
gallery: ["/images/projects/9.jpg"],
description: "Dự án cải tạo, nâng cấp tuyến đường vào Công ty CP Giấy Hoàng Văn Thụ giúp đảm bảo giao thông thuận lợi cho hoạt động sản xuất kinh doanh.",
},
{
TT: 10,
project: "Khu tái định cư tổ 4 Tân Thịnh thuộc dự án đường Bắc Sơn kéo dài TP Thái Nguyên",
consulting_work: "Tư vấn giám sát",
investor: "Ban QLDA ĐTXD TP Thái Nguyên, tỉnh Thái Nguyên",
image: "/images/projects/_10.jpg",
gallery: ["/images/projects/_10.jpg"],
description: "Dự án khu tái định cư tổ 4 Tân Thịnh thuộc tuyến đường Bắc Sơn kéo dài nhằm bố trí chỗ ở mới cho các hộ dân bị ảnh hưởng bởi giải phóng mặt bằng.",
},
{
TT: 11,
project: "Xây dựng cầu tổ 12, phường Hương Sơn, TPTN",
consulting_work: "Tư vấn thiết kế",
investor: "UBND phường Hương Sơn",
image: "/images/projects/11.jpg",
gallery: ["/images/projects/11.jpg"],
description: "Xây dựng cầu tổ 12, phường Hương Sơn, TPTN",
},
]);
const selectedProject = ref(null);
const isModalOpen = ref(false);
const isGalleryFullscreen = ref(false);
const activeCategory = ref("Tất cả");
const currentPage = ref(1);
const projectsPerPage = 6;
const categories = ref(["Tất cả", "Tư vấn thiết kế", "Giám sát thi công", "Khảo sát địa hình", "Hạ tầng giao thông", "Công trình dân dụng"]);
// Lc d án theo danh mc
const filteredProjects = computed(() => {
let filtered = projects.value;
if (activeCategory.value !== "Tất cả") {
filtered = projects.value.filter(project => project.consulting_work.includes(activeCategory.value));
}
return filtered;
});
// Phân trang
const paginatedProjects = computed(() => {
const startIndex = (currentPage.value - 1) * projectsPerPage;
return filteredProjects.value.slice(startIndex, startIndex + projectsPerPage);
});
// Các hàm h tr
const shortenProjectName = (name) => {
if (name.length > 50) {
return name.substring(0, 50) + "...";
}
return name;
};
// Các hàm x lý modal
const openModal = (project) => {
selectedProject.value = JSON.parse(JSON.stringify(project));
isModalOpen.value = true;
};
const closeModal = () => {
isModalOpen.value = false;
selectedProject.value = null;
};
const openGalleryFullscreen = () => {
isGalleryFullscreen.value = true;
};
const filterProjects = () => {
currentPage.value = 1;
};
</script>
<style>
/* Project Modal Styles */
.project-modal .ant-modal-content {
@apply p-0 overflow-hidden;
max-height: 90vh;
display: flex;
flex-direction: column;
}
.project-modal .ant-modal-body {
@apply p-0 flex-1 overflow-y-auto;
}
.project-gallery .slick-slide {
@apply h-48 sm:h-64;
}
/* Fullscreen Gallery Styles */
.gallery-modal .ant-modal-content {
@apply h-full flex flex-col;
}
.gallery-modal .ant-modal-body {
@apply flex-1 p-0;
}
.fullscreen-gallery {
@apply h-full;
}
.fullscreen-gallery .slick-slide {
@apply h-[calc(100vh-110px)] flex items-center justify-center;
}
/* Custom dots for carousel */
.ant-carousel .slick-dots.custom-dots li button {
@apply bg-gray-400;
}
.ant-carousel .slick-dots.custom-dots li.slick-active button {
@apply bg-blue-600 w-4;
}
/* Responsive adjustments */
@media (max-width: 640px) {
.project-modal {
@apply top-0 m-0 w-full max-w-none h-full;
}
.project-modal .ant-modal-content {
@apply rounded-none h-full;
}
.project-gallery .slick-slide {
@apply h-48;
}
.ant-radio-button-wrapper {
@apply px-2 text-sm;
}
}
/* Pagination styles */
.ant-pagination-item-active {
@apply border-blue-600 bg-blue-600 text-white;
}
.ant-pagination-item-active a {
@apply text-white;
}
.ant-pagination-item:hover {
@apply border-blue-400;
}
.ant-pagination-item:hover a {
@apply text-blue-600;
}
.ant-tag {
@apply m-0;
}
</style>

File diff suppressed because it is too large Load Diff

Binary file not shown.

BIN
public/bgfooter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 KiB

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
public/home.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

BIN
public/images/team-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

BIN
public/images/team-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
public/images/team-3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
public/images/team-4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

BIN
public/placeholder.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

BIN
public/product/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 KiB

BIN
public/product/2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 KiB

BIN
public/product/3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

BIN
public/product/4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

BIN
public/product/5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

2
public/robots.txt Normal file
View File

@ -0,0 +1,2 @@
User-Agent: *
Disallow:

3
server/tsconfig.json Normal file
View File

@ -0,0 +1,3 @@
{
"extends": "../.nuxt/tsconfig.server.json"
}

25
stores/useStore.js Normal file
View File

@ -0,0 +1,25 @@
import { defineStore } from "pinia";
export const useUserStore = defineStore(
"user",
{
state: () => ({
user: {},
}),
actions: {
setUser(value) {
this.user = value;
},
logout() {
this.user = {};
},
},
getters: {},
persist: {
// storage: piniaPluginPersistedstate.localStorage(),
storage: piniaPluginPersistedstate.cookies(),
},
},
{
persist: true,
},
);

9
tailwind.config.js Normal file
View File

@ -0,0 +1,9 @@
/** @type {import('tailwindcss').Config} */
export default {
content: [],
theme: {
extend: {},
},
plugins: [],
}

4
tsconfig.json Normal file
View File

@ -0,0 +1,4 @@
{
// https://nuxt.com/docs/guide/concepts/typescript
"extends": "./.nuxt/tsconfig.json"
}

7617
yarn.lock Normal file

File diff suppressed because it is too large Load Diff