Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
38465f3
chore: migrate project to pnpm and update dependencies
mrbadri Jul 6, 2025
f66038d
refactor: update docker-compose configuration for core-client service
mrbadri Jul 6, 2025
a5502ca
feat: add docker-compose configuration for core-client service
mrbadri Jul 6, 2025
a56d9a0
feat: add environment variables to Dockerfile for base URL configurat…
mrbadri Jul 6, 2025
18fba39
fix: update base URL in coreApi and guestApi to a hardcoded value
mrbadri Jul 6, 2025
42fb53a
feat: enhance authentication components with clipboard OTP functionality
mrbadri Jul 7, 2025
4f355a4
feat: add clipboard permission request functionality to useClipboardO…
mrbadri Jul 7, 2025
724450c
feat: implement clipboard permission listener in useClipboardOtp hook
mrbadri Jul 7, 2025
33292f7
feat: add deploy action
mrbadri Jul 9, 2025
dbde556
feat: add production docker-compose configuration for core-client ser…
mrbadri Jul 9, 2025
75388c3
refactor: update docker-compose configuration for client service
mrbadri Jul 9, 2025
c44ef34
chore: enhance Docker Hub deployment process in workflow
mrbadri Jul 9, 2025
84d2f80
chore: clean up Docker deployment workflow
mrbadri Jul 9, 2025
ce1f8b6
fix: update Docker deployment workflow to pull client service
mrbadri Jul 9, 2025
8253870
chore: remove commented-out Docker build and push steps from deployme…
mrbadri Jul 9, 2025
40fa684
chore: add concurrency configuration to deployment workflow
mrbadri Jul 9, 2025
6e06020
chore: update deployment workflow to use self-hosted runners
mrbadri Jul 9, 2025
e38ce6f
chore: expose port for core service in production Docker Compose
mrbadri Jul 9, 2025
10046db
fix: update API base URLs from HTTPS to HTTP
mrbadri Jul 10, 2025
1a21f6c
refactor: simplify post-login schema transformation and update docker…
mrbadri Jul 10, 2025
1ecb3c2
feat: add development and preview Docker Compose configurations
mrbadri Jul 10, 2025
47b4846
refactor: update PR comment actions in deployment workflow
mrbadri Jul 10, 2025
4ee4a08
chore: update permissions in deployment workflow
mrbadri Jul 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: CI/CD Pipeline

on:
push:
branches:
- main
pull_request:

concurrency:
group: "CI-${{ github.ref_name }}"
cancel-in-progress: false

jobs:
build:
runs-on: [self-hosted, core]
steps:
- name: Checkout Repository
uses: actions/checkout@v4

- name: Create .env file
run: |
echo "NEXT_PUBLIC_BASE_URL=${{ secrets.NEXT_PUBLIC_BASE_URL }}" >> .env
echo "NEXT_PUBLIC_BASE_URL_ATTACHMENT=${{ secrets.NEXT_PUBLIC_BASE_URL_ATTACHMENT }}" >> .env

- name: Login to Docker Hub
run: docker login -u mrbadri -p ${{ secrets.DOCKER_TOKEN }}

- name: Build Docker Image using Docker Compose
run: docker compose -f docker-compose.prod.yml build

- name: Push Docker Image to Docker Hub
run: docker push mrbadri/pixel-client:latest

deploy:
runs-on: [self-hosted, core]
needs: build
steps:
- name: Checkout Repository
uses: actions/checkout@v4

- name: Create .env file
run: |
echo "NEXT_PUBLIC_BASE_URL=${{ secrets.NEXT_PUBLIC_BASE_URL }}" >> .env
echo "NEXT_PUBLIC_BASE_URL_ATTACHMENT=${{ secrets.NEXT_PUBLIC_BASE_URL_ATTACHMENT }}" >> .env

- name: Deploy using Docker Compose
run: |
docker compose -f docker-compose.prod.yml pull client
docker compose -f docker-compose.prod.yml down || true
docker compose -f docker-compose.prod.yml up -d

# if container is not running, rullback to the previous version
15 changes: 9 additions & 6 deletions apps/core/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ RUN apk update
RUN apk add --no-cache libc6-compat
# Set working directory
WORKDIR /app
RUN yarn global add turbo
RUN npm install -g pnpm turbo
COPY . .
# RUN npm run prepare:ci
RUN turbo prune core --docker
Expand All @@ -19,13 +19,12 @@ FROM base AS installer
RUN apk update
RUN apk add --no-cache libc6-compat
WORKDIR /app
RUN npm install -g pnpm turbo

# First install the dependencies (as they change less often)
COPY --from=builder /app/out/json/ .
# Configure Yarn with better network settings and use Taobao registry
RUN yarn config set registry https://registry.npmmirror.com/ && \
yarn config set network-timeout 600000 && \
yarn install --network-timeout 600000 --no-network-concurrency
# Configure pnpm with better network settings and use Taobao registry
RUN pnpm install --frozen-lockfile

# Build the project
COPY --from=builder /app/out/full/ .
Expand All @@ -37,7 +36,7 @@ COPY --from=builder /app/out/full/ .
# ARG TURBO_TOKEN
# ENV TURBO_TOKEN=$TURBO_TOKEN

RUN yarn turbo build --filter=core
RUN pnpm turbo build

FROM base AS runner
WORKDIR /app
Expand All @@ -47,6 +46,10 @@ RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
USER nextjs

# Environment variables
ENV NEXT_PUBLIC_BASE_URL=${NEXT_PUBLIC_BASE_URL}
ENV NEXT_PUBLIC_BASE_URL_ATTACHMENT=${NEXT_PUBLIC_BASE_URL_ATTACHMENT}

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=installer --chown=nextjs:nodejs /app/apps/core/.next/standalone ./
Expand Down
24 changes: 19 additions & 5 deletions apps/core/app/(landing)/_components/mobile-menu/BrowseSheet.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import {
IconDeviceMobile, IconUsersGroup, IconEye, IconCube, IconVector, IconBox, IconLayout, IconMessage, IconTypography, IconDiamond
import {
IconDeviceMobile,
IconUsersGroup,
IconEye,
IconCube,
IconVector,
IconBox,
IconLayout,
IconMessage,
IconTypography,
IconDiamond,
} from "@tabler/icons-react";

const categories = [
Expand All @@ -18,10 +27,15 @@ const categories = [
const BrowseSheet = () => (
<div className="flex flex-col items-center w-full">
<div className="w-12 h-1.5 bg-[#fff]/20 rounded-full mt-1 mb-4" />
<h2 className="text-2xl font-bold text-white mb-6 w-full text-left">Browse</h2>
<h2 className="text-2xl font-bold text-white mb-6 w-full text-left">
Browse
</h2>
<div className="grid grid-cols-2 gap-x-8 gap-y-5 w-full">
{categories.map((cat) => (
<div key={cat.label} className="flex items-center gap-3 text-white/90 text-base font-medium">
<div
key={cat.label}
className="flex items-center gap-3 text-white/90 text-base font-medium"
>
<span className="bg-[#232228] rounded-md p-2 flex items-center justify-center">
{cat.icon}
</span>
Expand All @@ -32,4 +46,4 @@ const BrowseSheet = () => (
</div>
);

export default BrowseSheet;
export default BrowseSheet;
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ const AutherForm = () => {
/>
</div>
<div>

<Textarea
placeholder="Write a short message about yourself"
className=" bg-card h-40 resize-none p-3"
Expand Down
29 changes: 24 additions & 5 deletions apps/core/app/auth/_components/auth-card.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
// styles
// props : children
// <authCard> form </authCard>

"use client";
import PixelIcon from "@repo/icons/pxiel";
import { Button } from "@repo/ui/components";
import { ArrowLeft } from "lucide-react";
import { useRouter } from "next/navigation";

import { ReactNode } from "react";

const AuthCard = ({ children }: { children: ReactNode }) => {
const router = useRouter();

const handleBackClick = () => {
router.back();
};

return (
<div className="flex items-center relative z-10 flex-col gap-4 bg-card w-[calc(100% - 32px)] sm:w-[450px] rounded-xl mx-4">
{/* add back button */}
<div className="absolute top-4 left-4 z-10">
<Button
variant="tertiary"
size="icon"
onClick={handleBackClick}
className="hover:bg-secondary/50"
aria-label="Go back"
>
<ArrowLeft size={20} />
</Button>
</div>

{/* logo */}
<div className="w-full px-3 sm:p-7 py-7 flex flex-col items-center gap-4">
<div className="w-full px-3 sm:p-7 py-8 flex flex-col items-center gap-4">
<div>
<PixelIcon size={86} color="currentColor" />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,46 @@ import { Button, Input } from "@repo/ui/components";
import { postForgetPasswordSchema } from "@repo/apis/core/accounts/users/forgot-password/post/post-forget-password.schema";
import type { PostForgetPasswordRequest } from "@repo/apis/core/accounts/users/forgot-password/post/post-forget-password.types";
import { UsePostForgetPassword } from "@repo/apis/core/accounts/users/forgot-password/post/use-post-forget-password";
import { useEffect } from "react";

const ForgetPasswordForm = () => {
const router = useRouter();

const form = useForm<PostForgetPasswordRequest>({
resolver: zodResolver(postForgetPasswordSchema.request),
});

const {
register,
formState: { errors },
handleSubmit,
} = form;

const mutation = UsePostForgetPassword({
onSuccess: (res, context) => {
toast.info(res.data.message);
router.replace(`/auth/set-password?username=${context.username}`);
},
onError: (err) => {
toast.error(err.response?.data.message ?? "Something went wrong");
},
});

const onSubmit = (data: PostForgetPasswordRequest) => {
mutation.mutate(data);
};

useEffect(() => {
router.prefetch("/auth/set-password");
}, [router]);

return (
<form onSubmit={handleSubmit(onSubmit)} className="w-full pb-7">
<Input
label="Username"
className="font-normal text-xs"
placeholder="genius@exanpel.com"
placeholder="Enter your username"
autoFocus
{...register("username")}
error={errors.username?.message}
/>
Expand Down
18 changes: 13 additions & 5 deletions apps/core/app/auth/login/_components/form/loginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { setAuthTokens } from "@repo/apis/utils/cookies";
import { Button, PasswordInput, Input } from "@repo/ui/components";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";

Expand All @@ -29,7 +30,9 @@ const LoginForm = () => {

const loginMutation = usePostLogin({
onSuccess: (res) => {
toast.success("Logged in successfully");
toast.success(
`Hello @${res.data.data.username}! Welcome back to Pixel 🎉`,
);
setAuthTokens(res.data.data.token);
router.push("/");
},
Expand All @@ -43,6 +46,12 @@ const LoginForm = () => {
loginMutation.mutate(values);
});

useEffect(() => {
router.prefetch("/");
router.prefetch("/auth/forget-password");
router.prefetch("/auth/signup");
}, [router]);

return (
<form className="w-full" onSubmit={handleSubmitForm}>
<div className="mb-2 flex flex-wrap gap-4">
Expand All @@ -51,6 +60,7 @@ const LoginForm = () => {
label="User Name & Email"
className="font-normal text-xs w-full"
placeholder="example@pixel.design "
autoFocus
{...register("username")}
error={errors.username?.message}
/>
Expand All @@ -61,17 +71,15 @@ const LoginForm = () => {
className="w-full font-normal text-md"
placeholder="********"
helperText={
<Link
href="/auth/forget-password"
className="block mb-3 text-sm font-light text-muted-foreground hover:text-muted cursor-pointer"
>
<Link href="/auth/forget-password" className="underline">
Forgot password?
</Link>
}
{...register("password")}
error={errors.password?.message}
/>
</div>

{/* Button */}
<Button
size="md"
Expand Down
29 changes: 2 additions & 27 deletions apps/core/app/auth/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,10 @@ const LoginPage = () => {
</div>

<LoginForm />
{/* line */}
{/* <div className="flex items-center w-full gap-3">
<div className="w-full h-[1px] bg-gray-700 rounded-full" />
<p className="text-base font-medium">OR</p>
<div className="w-full h-[1px] bg-gray-700 rounded-full" />
</div> */}
{/* login with google and linkedin */}
{/* <div className="w-full flex flex-col items-center gap-3">
<Button
className="w-full text-lg bg-background"
variant="secondary"
size={"lg"}
>
<GoogleIcon size={24} className="mr-2" />
Log in with Google
</Button>
<Button
className="w-full text-lg bg-background"
variant="secondary"
size={"lg"}
>
<LinkedinIcon size={24} className="mr-2" />
Log in with linkedin
</Button>
</div> */}
{/* forgot password */}

<div className=" flex gap-2 pb-4 text-sm">
<p>Don’t have an account?</p>
<Link href={"/auth/signup"} prefetch={false}>
<Link href={"/auth/signup"}>
<p className="underline cursor-pointer">Sign up</p>
</Link>
</div>
Expand Down
Loading