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 files (can opt-in for committing if needed)
.env* .env*
!.env.prod
# vercel # vercel
.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. 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. 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", title: "TeamBy.ai - AI-Powered Management for Team Leads",
description: description:
"TeamBy unifies your work and uses AI to optimize workflows, meetings, and costs—so you can manage smarter without chasing updates.", "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({ export default function RootLayout({
@ -28,11 +35,9 @@ export default function RootLayout({
}>) { }>) {
return ( return (
<html lang="en" className={`${inter.variable} ${poppins.variable} dark bg-[#03070D]`}> <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"> <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} {children}
</body> </body>
</html> </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"; import type { NextConfig } from "next";
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
/* config options here */
output: "standalone",
}; };
export default nextConfig; 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