sina_sajjadi 2 weeks ago
parent
commit
817bd82c29
  1. 11
      .dockerignore
  2. 3
      .env.prod
  3. 1
      .gitignore
  4. 54
      Dockerfile
  5. 52
      Jenkinsfile
  6. 1
      README.md
  7. BIN
      app/apple-icon.png
  8. BIN
      app/favicon.ico
  9. BIN
      app/icon.png
  10. 268
      app/icon.svg
  11. 9
      app/layout.tsx
  12. 24
      docker-compose.yml
  13. 2
      next.config.ts
  14. BIN
      public/favicon.ico
  15. 3
      runner.sh

11
.dockerignore

@ -0,0 +1,11 @@
Dockerfile
docker-compose.yml
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git
.gitignore
.env*.local
.env.development

3
.env.prod

@ -0,0 +1,3 @@
PORT=3000
NODE_ENV=production
NEXT_TELEMETRY_DISABLED=1

1
.gitignore

@ -32,6 +32,7 @@ yarn-error.log*
# env files (can opt-in for committing if needed)
.env*
!.env.prod
# vercel
.vercel

54
Dockerfile

@ -0,0 +1,54 @@
# syntax=docker/dockerfile:1.7
# ──────────────────────────────────────────────────────────────────────────
# مرحلهٔ ۱ — deps: آماده‌سازی وابستگی‌ها با کش npm
# ──────────────────────────────────────────────────────────────────────────
FROM node:22-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json package-lock.json* ./
RUN --mount=type=cache,target=/root/.npm npm ci --prefer-offline --no-audit --fund=false
# ──────────────────────────────────────────────────────────────────────────
# مرحلهٔ ۲ — builder: ساخت خروجی بهینه‌شده standalone برای Next.js
# ──────────────────────────────────────────────────────────────────────────
FROM node:22-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
ENV NODE_ENV=production
RUN npm run build
# ──────────────────────────────────────────────────────────────────────────
# مرحلهٔ ۳ — runner: سرور مینیمال، سبک و امن standalone در محیط پروداکشن
# ──────────────────────────────────────────────────────────────────────────
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
# ایجاد کاربر غیر روت برای امنیت کانتینر
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
# هلث‌چک کانتینر
HEALTHCHECK --interval=30s --timeout=5s --start-period=15s --retries=3 \
CMD wget -qO- http://127.0.0.1:3000/ || exit 1
CMD ["node", "server.js"]

52
Jenkinsfile

@ -0,0 +1,52 @@
pipeline {
environment {
develop_server_ip = ''
develop_server_name = ''
production_server_ip = "88.99.212.243"
production_server_name = "newhorizon_germany_001_server"
project_path = "/projects/teamby/teamby_landing"
version = "master"
gitBranch = "origin/master"
}
agent any
stages {
stage('deploy') {
steps {
script {
if (gitBranch == "origin/master") {
try {
withCredentials([usernamePassword(credentialsId: production_server_name, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
sh 'sshpass -p $PASSWORD ssh -p 1782 $USERNAME@$production_server_ip -o StrictHostKeyChecking=no "cd $project_path && ./runner.sh"'
}
} catch (Exception e) {
def lastCommit = sh(script: 'git log -1 --pretty=format:"%h - %s (%an)"', returnStdout: true).trim()
sh """
curl -s -F chat_id=-1002316394394 \
-F message_thread_id=1629 \
-F document=@/var/jenkins_home/jobs/${env.JOB_NAME}/builds/${env.BUILD_NUMBER}/log \
-F caption='Project name: #${env.JOB_NAME} \
Build status is FAILED \
Build url: ${BUILD_URL} \
Last Commit: ${lastCommit}' \
https://api.telegram.org/bot7207581748:AAH1y1pW8L9K_jWlKx3Xj_xV3pZl4Zq9V1Y/sendDocument || true
"""
currentBuild.result = 'FAILURE'
throw e
}
def lastCommit = sh(script: 'git log -1 --pretty=format:"%h - %s (%an)"', returnStdout: true).trim()
sh """
curl -s -F chat_id=-1002316394394 \
-F message_thread_id=1629 \
-F document=@/var/jenkins_home/jobs/${env.JOB_NAME}/builds/${env.BUILD_NUMBER}/log \
-F caption='Project name: #${env.JOB_NAME} \
Build status is SUCCESS \
Build url: ${BUILD_URL} \
Last Commit: ${lastCommit}' \
https://api.telegram.org/bot7207581748:AAH1y1pW8L9K_jWlKx3Xj_xV3pZl4Zq9V1Y/sendDocument || true
"""
}
}
}
}
}
}

1
README.md

@ -34,3 +34,4 @@ You can check out [the Next.js GitHub repository](https://github.com/vercel/next
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
# TeamBy Landing Page - Automated CI/CD Enabled

BIN
app/apple-icon.png

After

Width: 51  |  Height: 51  |  Size: 5.0 KiB

BIN
app/favicon.ico

BIN
app/icon.png

After

Width: 51  |  Height: 51  |  Size: 5.0 KiB

268
app/icon.svg

@ -0,0 +1,268 @@
<svg width="51" height="51" viewBox="0 0 51 51" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M35.4741 24.5053H22.1291V22.1289H33.0978V17.3763H35.4741V24.5053Z" fill="url(#paint0_linear_4178_61388)"/>
<path d="M35.4741 17.3763L28.6187 17.3763C27.2476 17.3764 24.5054 18.117 24.5054 21.0781V22.2656H22.1291V21.3516C22.1293 18.7925 23.5467 15.0001 28.6187 15H35.4741V17.3763Z" fill="url(#paint1_linear_4178_61388)"/>
<path d="M15 28.6186C15 23.546 18.7937 22.129 21.3529 22.129H22.2669V24.5053H21.0781C18.117 24.5055 17.3763 27.2477 17.3763 28.6186V35.4728H15V28.6186Z" fill="url(#paint2_linear_4178_61388)"/>
<path d="M24.5053 22.129V35.4728H17.3763L17.3764 33.0965H22.129L22.1291 22.1289L24.5053 22.129Z" fill="url(#paint3_linear_4178_61388)"/>
<path d="M29.258 24.5054L24.5053 24.5054L24.5053 22.129L29.258 22.129V24.5054Z" fill="url(#paint4_linear_4178_61388)"/>
<path d="M35.4741 24.5053H22.1291V22.1289H33.0978V17.3763H35.4741V24.5053Z" fill="url(#paint5_linear_4178_61388)"/>
<path d="M35.4741 17.3763L28.6187 17.3763C27.2476 17.3764 24.5054 18.117 24.5054 21.0781V22.2656H22.1291V21.3516C22.1293 18.7925 23.5467 15.0001 28.6187 15H35.4741V17.3763Z" fill="url(#paint6_linear_4178_61388)"/>
<path d="M15 28.6186C15 23.546 18.7937 22.129 21.3529 22.129H22.2669V24.5053H21.0781C18.117 24.5055 17.3763 27.2477 17.3763 28.6186V35.4728H15V28.6186Z" fill="url(#paint7_linear_4178_61388)"/>
<path d="M24.5053 22.129V35.4728H17.3763L17.3764 33.0965H22.129L22.1291 22.1289L24.5053 22.129Z" fill="url(#paint8_linear_4178_61388)"/>
<path d="M29.258 24.5054L24.5053 24.5054L24.5053 22.129L29.258 22.129V24.5054Z" fill="url(#paint9_linear_4178_61388)"/>
<g opacity="0.3" filter="url(#filter0_f_4178_61388)" style="mix-blend-mode:color-dodge">
<path d="M35.4741 24.5053H22.1291V22.1289H33.0978V17.3763H35.4741V24.5053Z" fill="white"/>
<path d="M35.4741 17.3763L28.6187 17.3763C27.2476 17.3764 24.5054 18.117 24.5054 21.0781V22.2656H22.1291V21.3516C22.1293 18.7925 23.5467 15.0001 28.6187 15H35.4741V17.3763Z" fill="white"/>
<path d="M15 28.6186C15 23.546 18.7937 22.129 21.3529 22.129H22.2669V24.5053H21.0781C18.117 24.5055 17.3763 27.2477 17.3763 28.6186V35.4728H15V28.6186Z" fill="white"/>
<path d="M24.5053 22.129V35.4728H17.3763L17.3764 33.0965H22.129L22.1291 22.1289L24.5053 22.129Z" fill="white"/>
<path d="M29.258 24.5054L24.5053 24.5054L24.5053 22.129L29.258 22.129V24.5054Z" fill="white"/>
<path d="M35.4741 24.5053H22.1291V22.1289H33.0978V17.3763H35.4741V24.5053Z" fill="white"/>
<path d="M35.4741 17.3763L28.6187 17.3763C27.2476 17.3764 24.5054 18.117 24.5054 21.0781V22.2656H22.1291V21.3516C22.1293 18.7925 23.5467 15.0001 28.6187 15H35.4741V17.3763Z" fill="white"/>
<path d="M15 28.6186C15 23.546 18.7937 22.129 21.3529 22.129H22.2669V24.5053H21.0781C18.117 24.5055 17.3763 27.2477 17.3763 28.6186V35.4728H15V28.6186Z" fill="white"/>
<path d="M24.5053 22.129V35.4728H17.3763L17.3764 33.0965H22.129L22.1291 22.1289L24.5053 22.129Z" fill="white"/>
<path d="M29.258 24.5054L24.5053 24.5054L24.5053 22.129L29.258 22.129V24.5054Z" fill="white"/>
</g>
<g filter="url(#filter1_f_4178_61388)" style="mix-blend-mode:plus-lighter">
<path d="M35.4741 24.5053H22.1291V22.1289H33.0978V17.3763H35.4741V24.5053Z" fill="url(#paint10_linear_4178_61388)"/>
<path d="M35.4741 17.3763L28.6187 17.3763C27.2476 17.3764 24.5054 18.117 24.5054 21.0781V22.2656H22.1291V21.3516C22.1293 18.7925 23.5467 15.0001 28.6187 15H35.4741V17.3763Z" fill="url(#paint11_linear_4178_61388)"/>
<path d="M15 28.6186C15 23.546 18.7937 22.129 21.3529 22.129H22.2669V24.5053H21.0781C18.117 24.5055 17.3763 27.2477 17.3763 28.6186V35.4728H15V28.6186Z" fill="url(#paint12_linear_4178_61388)"/>
<path d="M24.5053 22.129V35.4728H17.3763L17.3764 33.0965H22.129L22.1291 22.1289L24.5053 22.129Z" fill="url(#paint13_linear_4178_61388)"/>
<path d="M29.258 24.5054L24.5053 24.5054L24.5053 22.129L29.258 22.129V24.5054Z" fill="url(#paint14_linear_4178_61388)"/>
<path d="M35.4741 24.5053H22.1291V22.1289H33.0978V17.3763H35.4741V24.5053Z" fill="url(#paint15_linear_4178_61388)"/>
<path d="M35.4741 17.3763L28.6187 17.3763C27.2476 17.3764 24.5054 18.117 24.5054 21.0781V22.2656H22.1291V21.3516C22.1293 18.7925 23.5467 15.0001 28.6187 15H35.4741V17.3763Z" fill="url(#paint16_linear_4178_61388)"/>
<path d="M15 28.6186C15 23.546 18.7937 22.129 21.3529 22.129H22.2669V24.5053H21.0781C18.117 24.5055 17.3763 27.2477 17.3763 28.6186V35.4728H15V28.6186Z" fill="url(#paint17_linear_4178_61388)"/>
<path d="M24.5053 22.129V35.4728H17.3763L17.3764 33.0965H22.129L22.1291 22.1289L24.5053 22.129Z" fill="url(#paint18_linear_4178_61388)"/>
<path d="M29.258 24.5054L24.5053 24.5054L24.5053 22.129L29.258 22.129V24.5054Z" fill="url(#paint19_linear_4178_61388)"/>
</g>
<defs>
<filter id="filter0_f_4178_61388" x="5" y="5" width="40.4727" height="40.4728" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="5" result="effect1_foregroundBlur_4178_61388"/>
</filter>
<filter id="filter1_f_4178_61388" x="0" y="0" width="50.4727" height="50.4728" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="7.5" result="effect1_foregroundBlur_4178_61388"/>
</filter>
<linearGradient id="paint0_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint1_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint2_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint3_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint4_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint5_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint6_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint7_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint8_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint9_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint10_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint11_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint12_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint13_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint14_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint15_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint16_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint17_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint18_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
<linearGradient id="paint19_linear_4178_61388" x1="25.2371" y1="15" x2="25.2371" y2="41.6877" gradientUnits="userSpaceOnUse">
<stop stop-color="#0029B3"/>
<stop offset="0.1" stop-color="#0038BF"/>
<stop offset="0.2" stop-color="#0E4ACC"/>
<stop offset="0.3" stop-color="#255CD9"/>
<stop offset="0.4" stop-color="#3D6FE6"/>
<stop offset="0.5" stop-color="#487EFF"/>
<stop offset="0.65" stop-color="#4B80FF"/>
<stop offset="0.8" stop-color="#5D8BFF"/>
<stop offset="1" stop-color="#ADBFFF"/>
</linearGradient>
</defs>
</svg>

9
app/layout.tsx

@ -19,6 +19,13 @@ export const metadata: Metadata = {
title: "TeamBy.ai - AI-Powered Management for Team Leads",
description:
"TeamBy unifies your work and uses AI to optimize workflows, meetings, and costs—so you can manage smarter without chasing updates.",
icons: {
icon: [
{ url: "/assets/images/logo_icon.svg", type: "image/svg+xml" },
{ url: "/favicon.ico", sizes: "any" },
],
apple: "/assets/images/logo_icon.png",
},
};
export default function RootLayout({
@ -28,11 +35,9 @@ export default function RootLayout({
}>) {
return (
<html lang="en" className={`${inter.variable} ${poppins.variable} dark bg-[#03070D]`}>
<body className="min-h-full flex flex-col bg-[#03070D] text-[#ffffff] font-sans antialiased selection:bg-blue-500/30 selection:text-blue-200">
{children}
</body>
</html>
);
}

24
docker-compose.yml

@ -0,0 +1,24 @@
services:
web:
build:
context: .
dockerfile: Dockerfile
image: teamby-landing:latest
container_name: teamby_landing
restart: unless-stopped
env_file:
- .env.prod
ports:
- "8065:3000"
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3000/ || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 15s
networks:
- teamby_backend_teamby
networks:
teamby_backend_teamby:
external: true

2
next.config.ts

@ -1,7 +1,7 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
/* config options here */
output: "standalone",
};
export default nextConfig;

BIN
public/favicon.ico

3
runner.sh

@ -0,0 +1,3 @@
#!/bin/bash
set -e
git pull origin master --rebase && docker compose up -d --build
Loading…
Cancel
Save