From ad261f00467c1e1fc31b181ecd031b5a6e1e5144 Mon Sep 17 00:00:00 2001 From: "mike.michel" Date: Thu, 5 Sep 2024 00:08:54 +0200 Subject: [PATCH 01/62] improve docker-compose --- apps/docs/quickstart.mdx | 24 +++++++++++++----------- docker-compose.dev.yaml | 34 ++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/apps/docs/quickstart.mdx b/apps/docs/quickstart.mdx index 07cec42e..970a0ee4 100644 --- a/apps/docs/quickstart.mdx +++ b/apps/docs/quickstart.mdx @@ -48,7 +48,7 @@ git clone https://github.com/gitroomhq/gitroom Copy the `.env.example` file to `.env` and fill in the values ```bash .env -DATABASE_URL="postgres database URL" +DATABASE_URL="postgres database URL i.g. postgresql://postiz-local:postiz-local-pwd@0.0.0.0:5432/postiz-db-local" REDIS_URL="redis database URL" JWT_SECRET="random string for your JWT secret, make it long" FRONTEND_URL="By default: http://localhost:4200" @@ -73,6 +73,7 @@ CLOUDFLARE_BUCKET_URL="Cloudflare R2 Backet URL" NX_ADD_PLUGINS=false IS_GENERAL="true" # required for now ``` + @@ -80,19 +81,20 @@ IS_GENERAL="true" # required for now ```bash Terminal npm install ``` + - -```bash Terminal -docker compose -f "docker-compose.dev.yaml" up -``` - +{' '} + + Using this you can skip the redis and postgres steps from above. This will + also give you pg-admin to check the database. ```bash Terminal docker compose + -f "docker-compose.dev.yaml" up ``` + - -```bash Terminal -npm run prisma-db-push -``` - +{' '} + + ```bash Terminal npm run prisma-db-push ``` + ```bash Terminal diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml index 5948c53f..55641b1b 100644 --- a/docker-compose.dev.yaml +++ b/docker-compose.dev.yaml @@ -1,26 +1,40 @@ -version: '3.9' - services: - gitroom-postgres: + postiz-postgres: image: postgres:14.5 - container_name: gitroom-postgres + container_name: postiz-postgres restart: always environment: - POSTGRES_PASSWORD: gitroom-local-pwd - POSTGRES_USER: gitroom-local - POSTGRES_DB: gitroom-db-local + POSTGRES_PASSWORD: postiz-local-pwd + POSTGRES_USER: postiz-local + POSTGRES_DB: postiz-db-local volumes: - postgres-volume:/var/lib/postgresql/data ports: - 5432:5432 - gitroom-redis: + networks: + - postiz-network + postiz-pg-admin: + image: dpage/pgadmin4 + container_name: postiz-pg-admin + restart: always + ports: + - 8081:80 + environment: + PGADMIN_DEFAULT_EMAIL: admin@admin.com + PGADMIN_DEFAULT_PASSWORD: admin + networks: + - postiz-network + postiz-redis: image: redis:7.2 - container_name: gitroom-redis + container_name: postiz-redis restart: always ports: - 6379:6379 - volumes: postgres-volume: external: false + +networks: + postiz-network: + external: false From 3477fc7a322af4fd9e462c62eb884a7531c5f902 Mon Sep 17 00:00:00 2001 From: jamesread Date: Sat, 7 Sep 2024 01:49:53 +0100 Subject: [PATCH 02/62] doc: Simplify quickstart instructions for end users --- apps/docs/emails.mdx | 14 ++++++++------ apps/docs/howitworks.mdx | 12 ++++++------ apps/docs/quickstart.mdx | 42 +++++++++++++++++++++------------------- 3 files changed, 36 insertions(+), 32 deletions(-) diff --git a/apps/docs/emails.mdx b/apps/docs/emails.mdx index 1e45b704..e7c7ea45 100644 --- a/apps/docs/emails.mdx +++ b/apps/docs/emails.mdx @@ -3,14 +3,16 @@ title: Email Notifications description: How to send notifications to users --- -At the moment we are using Resend to send email notifications to users, and might be changed the Novu later. +Postiz uses Resend to send email notifications to users. Emails are currently +required as part of the new-user creation process, which sends an activation +email. -Register to [Resend](https://resend.com) connect your domain. -Copy your API Key. -Head over to .env file and add the following line. +* Register to [Resend](https://resend.com), and connect your domain. +* Copy your API Key from the Resend control panel. +* Open the .env file and edit the following line. ```env -RESEND_API_KEY="" +RESEND_API_KEY="" ``` -Feel free to contribute other providers to send email notifications. \ No newline at end of file +Feel free to contribute other providers to send email notifications. diff --git a/apps/docs/howitworks.mdx b/apps/docs/howitworks.mdx index 8232d9d8..aa1fa7dc 100644 --- a/apps/docs/howitworks.mdx +++ b/apps/docs/howitworks.mdx @@ -8,13 +8,13 @@ Unlike other NX project, this project has one `.env` file that is shared between It makes it easier to develop and deploy the project.

When deploying to websites like [Railway](https://railway.app) or [Heroku](https://heroku.com), you can use a shared environment variables for all the apps.

-**At the moment it has 6 project:** +**At the moment it has 6 projects:** -- **Backend** - NestJS based system -- **Workers** - NestJS based workers connected to a Redis Queue. -- **Cron** - NestJS scheduler to run cron jobs. -- **Frontend** - NextJS based control panel. -- **Docs** - Mintlify based documentation website. +- [Frontend](#frontend) - Provides the Web user interface, talks to the Backend. +- [Backend](#backend) - Does all the real work, provides an API for the frontend, and posts work to the redis queue. +- [Workers](#worker) - Consumes work from the Redis Queue. +- [Cron](#cron) - Run jobs at scheduled times. +- [Docs](#docs) - This documentation site! -If you don't, you can install [Docker](https://www.docker.com/products/docker-desktop) and run: +Make sure you have PostgreSQL installed on your machine. -```bash +#### Option A) Postgres and Redis as Single containers + +You can install [Docker](https://www.docker.com/products/docker-desktop) and run: + +```bash Terminal docker run -e POSTGRES_USER=root -e POSTGRES_PASSWORD=your_password --name postgres -p 5432:5432 -d postgres -``` - -### Redis - -Make sure you have Redis installed on your machine.
-If you don't, you can install [Docker](https://www.docker.com/products/docker-desktop) and run: - -```bash docker run --name redis -p 6379:6379 -d redis ``` -## Installation +#### Option B) Postgres and Redis as docker-compose + +Download the [docker-compose.yaml file here](https://raw.githubusercontent.com/gitroomhq/postiz-app/main/docker-compose.dev.yaml), +or grab it from the repository in the next step. + +```bash Terminal +docker compose -f "docker-compose.dev.yaml" up +``` + +## Build Postiz @@ -44,7 +52,7 @@ git clone https://github.com/gitroomhq/gitroom ``` - + Copy the `.env.example` file to `.env` and fill in the values ```bash .env @@ -82,12 +90,6 @@ npm install ``` - -```bash Terminal -docker compose -f "docker-compose.dev.yaml" up -``` - - ```bash Terminal npm run prisma-db-push From 91bb329370912934ce3093366273ab9b6b559ae6 Mon Sep 17 00:00:00 2001 From: jamesread Date: Sat, 7 Sep 2024 01:52:02 +0100 Subject: [PATCH 03/62] feat: Dockerfile! --- Dockerfile | 38 ++++++++++++++++++++++++++++++++++++++ package.json | 1 + 2 files changed, 39 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..2418810d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,38 @@ +# Foundation image +FROM registry.fedoraproject.org/fedora-minimal:40 AS foundation + +RUN microdnf install --nodocs --noplugins --setopt=keepcache=0 --setopt=install_weak_deps=0 -y \ + npm \ + node \ + && microdnf clean all + +# Builder image +FROM foundation AS builder + +run mkdir /src + +COPY . /src + +WORKDIR /src + +RUN npx nx reset +RUN npm run build + +# Output image +FROM foundation AS dist + +LABEL org.opencontainers.image.source=https://github.com/gitroomhq/postiz-app +LABEL org.opencontainers.image.title="Postiz App" + +RUN mkdir -p /config /app + +COPY --from=builder /src/dist /app/dist/ +COPY --from=builder /src/package.json /app/ +COPY --from=builder /src/nx.json /app/ + +EXPOSE 4200 +EXPOSE 3000 + +WORKDIR /app + +ENTRYPOINT ["npm", "run", "dev"] diff --git a/package.json b/package.json index 9a5c2dc6..bfadd59e 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "prisma-generate": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma generate", "prisma-db-push": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma db push", "prisma-reset": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma db push --force-reset && npx prisma db push", + "build-docker-image": "docker rmi localhost/postiz || true && docker build -t localhost/postiz . && docker create --name postiz -p 3000:3000 -p 4200:4200 localhost/postiz", "postinstall": "npm run prisma-generate" }, "private": true, From b233abaa11b852201bf93b507d35ba088d88718c Mon Sep 17 00:00:00 2001 From: jamesread Date: Sat, 7 Sep 2024 10:00:33 +0100 Subject: [PATCH 04/62] feat: Add production start, config vol, fox typos --- Dockerfile | 9 +++++++-- package.json | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2418810d..5e87f34a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ RUN microdnf install --nodocs --noplugins --setopt=keepcache=0 --setopt=install_ # Builder image FROM foundation AS builder -run mkdir /src +RUN mkdir /src COPY . /src @@ -26,13 +26,18 @@ LABEL org.opencontainers.image.title="Postiz App" RUN mkdir -p /config /app +VOLUME /config + COPY --from=builder /src/dist /app/dist/ COPY --from=builder /src/package.json /app/ COPY --from=builder /src/nx.json /app/ +COPY .env.example /config/.env +COPY var/docker-entrypoint.sh /app/entrypoint.sh + EXPOSE 4200 EXPOSE 3000 WORKDIR /app -ENTRYPOINT ["npm", "run", "dev"] +ENTRYPOINT ["/app/entrypoint.sh"] diff --git a/package.json b/package.json index bfadd59e..2ea2cf88 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "prisma-generate": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma generate", "prisma-db-push": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma db push", "prisma-reset": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma db push --force-reset && npx prisma db push", - "build-docker-image": "docker rmi localhost/postiz || true && docker build -t localhost/postiz . && docker create --name postiz -p 3000:3000 -p 4200:4200 localhost/postiz", + "docker-build": "docker rmi localhost/postiz || true && docker build -t localhost/postiz . ", + "docker-create": "docker kill postiz || true && docker rm postiz || true && docker create --name postiz -p 3000:3000 -p 4200:4200 localhost/postiz", "postinstall": "npm run prisma-generate" }, "private": true, From f0fc916712761f0ba5743521ab66568becbfabe4 Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Sat, 7 Sep 2024 13:28:29 -0500 Subject: [PATCH 05/62] add build gh-action Signed-off-by: Jonathan Irvin --- .github/build.yaml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/build.yaml diff --git a/.github/build.yaml b/.github/build.yaml new file mode 100644 index 00000000..382ddb64 --- /dev/null +++ b/.github/build.yaml @@ -0,0 +1,26 @@ +name: Build + +on: + push: + branches: [$default-branch] + pull_request: + branches: [$default-branch] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20.x, 22.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v4 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + - run: npm ci + - run: npm run build --if-present From 3319917ea629466cd761b3421c3e00f3e34716b8 Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Sat, 7 Sep 2024 13:30:24 -0500 Subject: [PATCH 06/62] set to main brain Signed-off-by: Jonathan Irvin --- .github/build.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/build.yaml b/.github/build.yaml index 382ddb64..3ef2ed05 100644 --- a/.github/build.yaml +++ b/.github/build.yaml @@ -2,9 +2,11 @@ name: Build on: push: - branches: [$default-branch] + branches: + - main pull_request: - branches: [$default-branch] + branches: + - main jobs: build: From 05d7b7547be3b3d4ddadee4b977ca3f431eb520f Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Sat, 7 Sep 2024 13:34:34 -0500 Subject: [PATCH 07/62] move build.yaml to the correct location Signed-off-by: Jonathan Irvin --- .github/{ => workflows}/build.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{ => workflows}/build.yaml (100%) diff --git a/.github/build.yaml b/.github/workflows/build.yaml similarity index 100% rename from .github/build.yaml rename to .github/workflows/build.yaml From aab1ef1c3a422afe2587e8bb8b615fe9b2c6aa94 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Sun, 8 Sep 2024 13:21:50 +0700 Subject: [PATCH 08/62] feat: fixing date --- .../src/api/routes/posts.controller.ts | 3 +- .../components/launches/calendar.context.tsx | 3 +- .../src/components/launches/calendar.tsx | 88 +++++++++---------- .../launches/new.calendar.component.tsx | 2 - .../prisma/comments/comments.repository.ts | 3 +- .../prisma/comments/comments.service.ts | 4 +- .../database/prisma/posts/posts.repository.ts | 6 +- .../src/dtos/posts/get.posts.dto.ts | 4 - 8 files changed, 52 insertions(+), 61 deletions(-) diff --git a/apps/backend/src/api/routes/posts.controller.ts b/apps/backend/src/api/routes/posts.controller.ts index c13c614a..8814a6b0 100644 --- a/apps/backend/src/api/routes/posts.controller.ts +++ b/apps/backend/src/api/routes/posts.controller.ts @@ -53,8 +53,7 @@ export class PostsController { this._commentsService.getAllCommentsByWeekYear( org.id, query.year, - query.week, - query.isIsoWeek === 'true' + query.week ), ]); diff --git a/apps/frontend/src/components/launches/calendar.context.tsx b/apps/frontend/src/components/launches/calendar.context.tsx index 0105bda9..3d625ad8 100644 --- a/apps/frontend/src/components/launches/calendar.context.tsx +++ b/apps/frontend/src/components/launches/calendar.context.tsx @@ -109,8 +109,7 @@ export const CalendarWeekProvider: FC<{ const params = useMemo(() => { return new URLSearchParams({ week: filters.currentWeek.toString(), - year: filters.currentYear.toString(), - isIsoWeek: isIsoWeek.toString(), + year: filters.currentYear.toString() }).toString(); }, [filters]); diff --git a/apps/frontend/src/components/launches/calendar.tsx b/apps/frontend/src/components/launches/calendar.tsx index c24d4923..bdba443e 100644 --- a/apps/frontend/src/components/launches/calendar.tsx +++ b/apps/frontend/src/components/launches/calendar.tsx @@ -144,44 +144,44 @@ export const Calendar = () => { ); }; +// export const CalendarColumn: FC<{ day: number; hour: string }> = (props) => { +// const { day, hour } = props; +// const { currentWeek, currentYear } = useCalendar(); +// +// const getDate = useMemo(() => { +// const date = +// dayjs() +// .year(currentYear) +// .isoWeek(currentWeek) +// .isoWeekday(day) +// .format('YYYY-MM-DD') + +// 'T' + +// hour + +// ':00'; +// return dayjs(date); +// }, [currentWeek]); +// +// const isBeforeNow = useMemo(() => { +// return getDate.isBefore(dayjs()); +// }, [getDate]); +// +// const [ref, entry] = useIntersectionObserver({ +// threshold: 0.5, +// root: null, +// rootMargin: '0px', +// }); +// +// return ( +//
+// {!entry?.isIntersecting ? ( +//
+// ) : ( +// +// )} +//
+// ); +// }; export const CalendarColumn: FC<{ day: number; hour: string }> = (props) => { - const { day, hour } = props; - const { currentWeek, currentYear } = useCalendar(); - - const getDate = useMemo(() => { - const date = - dayjs() - .year(currentYear) - .isoWeek(currentWeek) - .isoWeekday(day) - .format('YYYY-MM-DD') + - 'T' + - hour + - ':00'; - return dayjs(date); - }, [currentWeek]); - - const isBeforeNow = useMemo(() => { - return getDate.isBefore(dayjs()); - }, [getDate]); - - const [ref, entry] = useIntersectionObserver({ - threshold: 0.5, - root: null, - rootMargin: '0px', - }); - - return ( -
- {!entry?.isIntersecting ? ( -
- ) : ( - - )} -
- ); -}; -const CalendarColumnRender: FC<{ day: number; hour: string }> = (props) => { const { day, hour } = props; const user = useUser(); const { @@ -201,12 +201,13 @@ const CalendarColumnRender: FC<{ day: number; hour: string }> = (props) => { const date = dayjs() .year(currentYear) - .isoWeek(currentWeek) - .isoWeekday(day) + .week(currentWeek) + .day(day + 1) .format('YYYY-MM-DD') + 'T' + hour + ':00'; + return dayjs(date); }, [currentWeek]); @@ -311,6 +312,7 @@ const CalendarColumnRender: FC<{ day: number; hour: string }> = (props) => { return previewPublication(post); } const data = await (await fetch(`/posts/${post.id}`)).json(); + const publishDate = dayjs.utc(data.posts[0].publishDate).local(); modal.openModal({ closeOnClickOutside: false, @@ -327,7 +329,7 @@ const CalendarColumnRender: FC<{ day: number; hour: string }> = (props) => { .slice(0) .filter((f) => f.id === data.integration) .map((p) => ({ ...p, picture: data.integrationPicture }))} - date={getDate} + date={publishDate} /> ), @@ -361,7 +363,7 @@ const CalendarColumnRender: FC<{ day: number; hour: string }> = (props) => { const addProvider = useAddProvider(); return ( -
+
= (props) => { 'data-tooltip-content': 'Predicted GitHub Trending Change', } : {})} - ref={drop} className={clsx( - 'flex-col flex-1 text-[12px] pointer w-full overflow-hidden justify-center overflow-x-auto flex scrollbar scrollbar-thumb-tableBorder scrollbar-track-secondary', + 'flex-col flex-1 text-[12px] pointer w-full cursor-pointer overflow-hidden justify-center overflow-x-auto flex scrollbar scrollbar-thumb-tableBorder scrollbar-track-secondary', isBeforeNow && 'bg-customColor23', - canDrop && 'bg-white/80', canBeTrending && 'bg-customColor24' )} > diff --git a/apps/frontend/src/components/launches/new.calendar.component.tsx b/apps/frontend/src/components/launches/new.calendar.component.tsx index 63dae17f..720443d6 100644 --- a/apps/frontend/src/components/launches/new.calendar.component.tsx +++ b/apps/frontend/src/components/launches/new.calendar.component.tsx @@ -1,6 +1,4 @@ 'use client'; -import { ChevronLeft, ChevronRight, Plus } from 'lucide-react'; -import { Button } from '@gitroom/react/form/button'; import { Fragment } from 'react'; import { CalendarColumn } from '@gitroom/frontend/components/launches/calendar'; import { DNDProvider } from '@gitroom/frontend/components/launches/helpers/dnd.provider'; diff --git a/libraries/nestjs-libraries/src/database/prisma/comments/comments.repository.ts b/libraries/nestjs-libraries/src/database/prisma/comments/comments.repository.ts index 58230c0c..655ed7a8 100644 --- a/libraries/nestjs-libraries/src/database/prisma/comments/comments.repository.ts +++ b/libraries/nestjs-libraries/src/database/prisma/comments/comments.repository.ts @@ -116,10 +116,9 @@ export class CommentsRepository { orgId: string, year: number, week: number, - isIsoWeek: boolean ) { const dateYear = dayjs().year(year); - const date = isIsoWeek ? dateYear.isoWeek(week) : dateYear.week(week); + const date = dateYear.isoWeek(week); const startDate = date.startOf('isoWeek').subtract(2, 'days').toDate(); const endDate = date.endOf('isoWeek').add(2, 'days').toDate(); diff --git a/libraries/nestjs-libraries/src/database/prisma/comments/comments.service.ts b/libraries/nestjs-libraries/src/database/prisma/comments/comments.service.ts index 85b4c755..7882a01e 100644 --- a/libraries/nestjs-libraries/src/database/prisma/comments/comments.service.ts +++ b/libraries/nestjs-libraries/src/database/prisma/comments/comments.service.ts @@ -44,7 +44,7 @@ export class CommentsService { ); } - getAllCommentsByWeekYear(orgId: string, year: number, week: number, isIsoWeek: boolean) { - return this._commentsRepository.getAllCommentsByWeekYear(orgId, year, week, isIsoWeek); + getAllCommentsByWeekYear(orgId: string, year: number, week: number) { + return this._commentsRepository.getAllCommentsByWeekYear(orgId, year, week); } } diff --git a/libraries/nestjs-libraries/src/database/prisma/posts/posts.repository.ts b/libraries/nestjs-libraries/src/database/prisma/posts/posts.repository.ts index 70b86ed4..e5931498 100644 --- a/libraries/nestjs-libraries/src/database/prisma/posts/posts.repository.ts +++ b/libraries/nestjs-libraries/src/database/prisma/posts/posts.repository.ts @@ -64,10 +64,10 @@ export class PostsRepository { getPosts(orgId: string, query: GetPostsDto) { const dateYear = dayjs().year(query.year); - const date = query.isIsoWeek === 'true' ? dateYear.isoWeek(query.week) : dateYear.week(query.week); + const date = dateYear.isoWeek(query.week); - const startDate = date.startOf('week').subtract(2, 'days').toDate(); - const endDate = date.endOf('week').add(2, 'days').toDate(); + const startDate = date.startOf('isoWeek').subtract(2, 'days').toDate(); + const endDate = date.endOf('isoWeek').add(2, 'days').toDate(); return this._post.model.post.findMany({ where: { diff --git a/libraries/nestjs-libraries/src/dtos/posts/get.posts.dto.ts b/libraries/nestjs-libraries/src/dtos/posts/get.posts.dto.ts index 557f551d..4872a787 100644 --- a/libraries/nestjs-libraries/src/dtos/posts/get.posts.dto.ts +++ b/libraries/nestjs-libraries/src/dtos/posts/get.posts.dto.ts @@ -14,8 +14,4 @@ export class GetPostsDto { @Max(dayjs().add(10, 'year').year()) @Min(2022) year: number; - - @IsIn(['true', 'false']) - @IsString() - isIsoWeek: 'true' | 'false'; } From 9fb979687dc0ee43eeefb8cf228884f3e8abf543 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Sun, 8 Sep 2024 20:27:19 +0700 Subject: [PATCH 09/62] feat: month view --- .../src/api/routes/posts.controller.ts | 14 +- apps/frontend/src/app/colors.scss | 2 +- .../components/launches/add.edit.model.tsx | 3 - .../components/launches/calendar.context.tsx | 94 +++-- .../src/components/launches/calendar.tsx | 391 ++++++++---------- .../src/components/launches/filters.tsx | 141 ++++++- .../launches/launches.component.tsx | 8 +- .../launches/new.calendar.component.tsx | 54 --- .../database/prisma/posts/posts.repository.ts | 6 +- .../src/dtos/posts/get.posts.dto.ts | 10 +- 10 files changed, 382 insertions(+), 341 deletions(-) delete mode 100644 apps/frontend/src/components/launches/new.calendar.component.tsx diff --git a/apps/backend/src/api/routes/posts.controller.ts b/apps/backend/src/api/routes/posts.controller.ts index 8814a6b0..dccdd28c 100644 --- a/apps/backend/src/api/routes/posts.controller.ts +++ b/apps/backend/src/api/routes/posts.controller.ts @@ -48,18 +48,18 @@ export class PostsController { @GetOrgFromRequest() org: Organization, @Query() query: GetPostsDto ) { - const [posts, comments] = await Promise.all([ + const [posts] = await Promise.all([ this._postsService.getPosts(org.id, query), - this._commentsService.getAllCommentsByWeekYear( - org.id, - query.year, - query.week - ), + // this._commentsService.getAllCommentsByWeekYear( + // org.id, + // query.year, + // query.week + // ), ]); return { posts, - comments, + // comments, }; } diff --git a/apps/frontend/src/app/colors.scss b/apps/frontend/src/app/colors.scss index 0a3cf3ca..961de950 100644 --- a/apps/frontend/src/app/colors.scss +++ b/apps/frontend/src/app/colors.scss @@ -34,7 +34,7 @@ --color-custom20: #121b2c; --color-custom21: #506490; --color-custom22: #b91c1c; - --color-custom23: #06080d; + --color-custom23: #000000; --color-custom24: #eaff00; --color-custom25: #2e3336; --color-custom26: #1d9bf0; diff --git a/apps/frontend/src/components/launches/add.edit.model.tsx b/apps/frontend/src/components/launches/add.edit.model.tsx index f54a97c5..5bc20e65 100644 --- a/apps/frontend/src/components/launches/add.edit.model.tsx +++ b/apps/frontend/src/components/launches/add.edit.model.tsx @@ -12,7 +12,6 @@ import React, { import dayjs from 'dayjs'; import { Integrations } from '@gitroom/frontend/components/launches/calendar.context'; import clsx from 'clsx'; -import { commands } from '@uiw/react-md-editor'; import { usePreventWindowUnload } from '@gitroom/react/helpers/use.prevent.window.unload'; import { deleteDialog } from '@gitroom/react/helpers/delete.dialog'; import { useModals } from '@mantine/modals'; @@ -27,7 +26,6 @@ import { import { useFetch } from '@gitroom/helpers/utils/custom.fetch'; import { useMoveToIntegration } from '@gitroom/frontend/components/launches/helpers/use.move.to.integration'; import { useExistingData } from '@gitroom/frontend/components/launches/helpers/use.existing.data'; -import { newImage } from '@gitroom/frontend/components/launches/helpers/new.image.component'; import { MultiMediaComponent } from '@gitroom/frontend/components/media/media.component'; import { useExpend } from '@gitroom/frontend/components/launches/helpers/use.expend'; import { TopTitle } from '@gitroom/frontend/components/launches/helpers/top.title.component'; @@ -36,7 +34,6 @@ import { ProvidersOptions } from '@gitroom/frontend/components/launches/provider import { v4 as uuidv4 } from 'uuid'; import useSWR, { useSWRConfig } from 'swr'; import { useToaster } from '@gitroom/react/toaster/toaster'; -import { postSelector } from '@gitroom/frontend/components/post-url-selector/post.url.selector'; import { UpDownArrow } from '@gitroom/frontend/components/launches/up.down.arrow'; import { DatePicker } from '@gitroom/frontend/components/launches/helpers/date.picker'; import { arrayMoveImmutable } from 'array-move'; diff --git a/apps/frontend/src/components/launches/calendar.context.tsx b/apps/frontend/src/components/launches/calendar.context.tsx index 3d625ad8..5cb333b1 100644 --- a/apps/frontend/src/components/launches/calendar.context.tsx +++ b/apps/frontend/src/components/launches/calendar.context.tsx @@ -21,12 +21,23 @@ import { isGeneral } from '@gitroom/react/helpers/is.general'; const CalendarContext = createContext({ currentWeek: dayjs().week(), currentYear: dayjs().year(), + currentMonth: dayjs().month(), comments: [] as Array<{ date: string; total: number }>, integrations: [] as Integrations[], trendings: [] as string[], posts: [] as Array, - setFilters: (filters: { currentWeek: number; currentYear: number }) => {}, - changeDate: (id: string, date: dayjs.Dayjs) => {}, + display: 'week', + setFilters: (filters: { + currentWeek: number; + currentYear: number; + currentMonth: number; + display: 'week' | 'month'; + }) => { + /** empty **/ + }, + changeDate: (id: string, date: dayjs.Dayjs) => { + /** empty **/ + }, }); export interface Integrations { @@ -40,28 +51,21 @@ export interface Integrations { } function getWeekNumber(date: Date) { - // Copy date so don't modify original - const targetDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())); - // Set to nearest Thursday: current date + 4 - current day number - // Make Sunday's day number 7 - targetDate.setUTCDate(targetDate.getUTCDate() + 4 - (targetDate.getUTCDay() || 7)); - // Get first day of year - const yearStart = new Date(Date.UTC(targetDate.getUTCFullYear(), 0, 1)); - // Calculate full weeks to nearest Thursday - return Math.ceil((((targetDate.getTime() - yearStart.getTime()) / 86400000) + 1) / 7); -} - -function isISOWeek(date: Date, weekNumber: number): boolean { - // Copy date so don't modify original - const targetDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())); - // Set to nearest Thursday: current date + 4 - current day number - // Make Sunday's day number 7 - targetDate.setUTCDate(targetDate.getUTCDate() + 4 - (targetDate.getUTCDay() || 7)); - // Get first day of year - const yearStart = new Date(Date.UTC(targetDate.getUTCFullYear(), 0, 1)); - // Calculate full weeks to nearest Thursday - const isoWeekNo = Math.ceil((((targetDate.getTime() - yearStart.getTime()) / 86400000) + 1) / 7); - return isoWeekNo === weekNumber; + // Copy date so don't modify original + const targetDate = new Date( + Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) + ); + // Set to nearest Thursday: current date + 4 - current day number + // Make Sunday's day number 7 + targetDate.setUTCDate( + targetDate.getUTCDate() + 4 - (targetDate.getUTCDay() || 7) + ); + // Get first day of year + const yearStart = new Date(Date.UTC(targetDate.getUTCFullYear(), 0, 1)); + // Calculate full weeks to nearest Thursday + return Math.ceil( + ((targetDate.getTime() - yearStart.getTime()) / 86400000 + 1) / 7 + ); } export const CalendarWeekProvider: FC<{ @@ -84,20 +88,32 @@ export const CalendarWeekProvider: FC<{ })(); }, []); + const display = searchParams.get('month') ? 'month' : 'week'; const [filters, setFilters] = useState({ - currentWeek: +(searchParams.get('week') || getWeekNumber(new Date())), + currentWeek: + display === 'week' + ? +(searchParams.get('week') || getWeekNumber(new Date())) + : 0, + currentMonth: + display === 'week' ? 0 : +(searchParams.get('month') || dayjs().month()), currentYear: +(searchParams.get('year') || dayjs().year()), + display, }); - const isIsoWeek = useMemo(() => { - return isISOWeek(new Date(), filters.currentWeek); - }, [filters]); - const setFiltersWrapper = useCallback( - (filters: { currentWeek: number; currentYear: number }) => { + (filters: { + currentWeek: number; + currentYear: number; + currentMonth: number; + display: 'week' | 'month'; + }) => { setFilters(filters); router.replace( - `/launches?week=${filters.currentWeek}&year=${filters.currentYear}` + `/launches?${ + filters.currentWeek + ? `week=${filters.currentWeek}` + : `month=${filters.currentMonth}` + }&year=${filters.currentYear}` ); setTimeout(() => { mutate('/posts'); @@ -107,14 +123,22 @@ export const CalendarWeekProvider: FC<{ ); const params = useMemo(() => { - return new URLSearchParams({ - week: filters.currentWeek.toString(), - year: filters.currentYear.toString() - }).toString(); + return new URLSearchParams( + filters.currentWeek + ? { + week: filters.currentWeek.toString(), + year: filters.currentYear.toString(), + } + : { + year: filters.currentYear.toString(), + month: (filters.currentMonth + 1).toString(), + } + ).toString(); }, [filters]); const loadData = useCallback( async (url: string) => { + setInternalData([]); const data = (await fetch(`${url}?${params}`)).json(); return data; }, diff --git a/apps/frontend/src/components/launches/calendar.tsx b/apps/frontend/src/components/launches/calendar.tsx index bdba443e..5a048898 100644 --- a/apps/frontend/src/components/launches/calendar.tsx +++ b/apps/frontend/src/components/launches/calendar.tsx @@ -1,6 +1,6 @@ 'use client'; -import React, { FC, useCallback, useMemo } from 'react'; +import React, { FC, Fragment, useCallback, useMemo } from 'react'; import { Integrations, useCalendar, @@ -17,14 +17,12 @@ import { Integration, Post, State } from '@prisma/client'; import { useAddProvider } from '@gitroom/frontend/components/launches/add.provider.component'; import { CommentComponent } from '@gitroom/frontend/components/launches/comments/comment.component'; import { useSWRConfig } from 'swr'; -import { useIntersectionObserver } from '@uidotdev/usehooks'; import { useToaster } from '@gitroom/react/toaster/toaster'; import { useUser } from '@gitroom/frontend/components/layout/user.context'; import { IntegrationContext } from '@gitroom/frontend/components/launches/helpers/use.integration'; import { PreviewPopup } from '@gitroom/frontend/components/marketplace/special.message'; export const days = [ - '', 'Monday', 'Tuesday', 'Wednesday', @@ -33,192 +31,143 @@ export const days = [ 'Saturday', 'Sunday', ]; -export const hours = [ - '00:00', - '01:00', - '02:00', - '03:00', - '04:00', - '05:00', - '06:00', - '07:00', - '08:00', - '09:00', - '10:00', - '11:00', - '12:00', - '13:00', - '14:00', - '15:00', - '16:00', - '17:00', - '18:00', - '19:00', - '20:00', - '21:00', - '22:00', - '23:00', -]; +export const hours = Array.from({ length: 24 }, (_, i) => i); -export const Calendar = () => { - const { currentWeek, currentYear, comments } = useCalendar(); - - const firstDay = useMemo(() => { - return dayjs().year(currentYear).isoWeek(currentWeek).isoWeekday(1); - }, [currentYear, currentWeek]); +export const WeekView = () => { + const { currentYear, currentWeek } = useCalendar(); return ( - -
-
+
+
+
+
{days.map((day, index) => (
-
{day}
-
- {day && `(${firstDay.add(index - 1, 'day').format('DD/MM')})`} -
+
{day}
))} - {hours.map((hour) => - days.map((day, index) => ( - <> - {index === 0 ? ( -
- {['00', '10', '20', '30', '40', '50'].map((num) => ( -
- {hour.split(':')[0] + ':' + num} -
- ))} -
- ) : ( -
- - dayjs - .utc(p.date) - .local() - .format('YYYY-MM-DD HH:mm') === - dayjs() - .isoWeek(currentWeek) - .isoWeekday(index + 1) - .hour(+hour.split(':')[0] - 1) - .minute(0) - .format('YYYY-MM-DD HH:mm') - )?.total || 0 - } - date={dayjs() - .isoWeek(currentWeek) - .isoWeekday(index + 1) - .hour(+hour.split(':')[0] - 1) - .minute(0)} + {hours.map((hour) => ( + +
+ {hour.toString().padStart(2, '0')}:00 +
+ {days.map((day, indexDay) => ( + +
+ - {['00', '10', '20', '30', '40', '50'].map((num) => ( - - ))}
- )} - - )) - )} +
+ ))} +
+ ))}
+
+ ); +}; + +export const MonthView = () => { + const { currentYear, currentMonth } = useCalendar(); + + const calendarDays = useMemo(() => { + const startOfMonth = dayjs(new Date(currentYear, currentMonth, 1)); + + // Calculate the day offset for Monday (isoWeekday() returns 1 for Monday) + const startDayOfWeek = startOfMonth.isoWeekday(); // 1 for Monday, 7 for Sunday + const daysBeforeMonth = startDayOfWeek - 1; // Days to show from the previous month + + // Get the start date (Monday of the first week that includes this month) + const startDate = startOfMonth.subtract(daysBeforeMonth, 'day'); + + // Create an array to hold the calendar days (6 weeks * 7 days = 42 days max) + const calendarDays = []; + let currentDay = startDate; + + for (let i = 0; i < 42; i++) { + let label = 'current-month'; + if (currentDay.month() < currentMonth) label = 'previous-month'; + if (currentDay.month() > currentMonth) label = 'next-month'; + + calendarDays.push({ + day: currentDay, + label, + }); + + // Move to the next day + currentDay = currentDay.add(1, 'day'); + } + + return calendarDays; + }, [currentYear, currentMonth]); + + return ( +
+
+
+ {days.map((day) => ( +
+
{day}
+
+ ))} + {calendarDays.map((date, index) => ( +
+ +
+ ))} +
+
+
+ ); +}; + +export const Calendar = () => { + const { display } = useCalendar(); + return ( + + {display === 'week' ? : } ); }; -// export const CalendarColumn: FC<{ day: number; hour: string }> = (props) => { -// const { day, hour } = props; -// const { currentWeek, currentYear } = useCalendar(); -// -// const getDate = useMemo(() => { -// const date = -// dayjs() -// .year(currentYear) -// .isoWeek(currentWeek) -// .isoWeekday(day) -// .format('YYYY-MM-DD') + -// 'T' + -// hour + -// ':00'; -// return dayjs(date); -// }, [currentWeek]); -// -// const isBeforeNow = useMemo(() => { -// return getDate.isBefore(dayjs()); -// }, [getDate]); -// -// const [ref, entry] = useIntersectionObserver({ -// threshold: 0.5, -// root: null, -// rootMargin: '0px', -// }); -// -// return ( -//
-// {!entry?.isIntersecting ? ( -//
-// ) : ( -// -// )} -//
-// ); -// }; -export const CalendarColumn: FC<{ day: number; hour: string }> = (props) => { - const { day, hour } = props; +export const CalendarColumn: FC<{ + getDate: dayjs.Dayjs; + randomHour?: boolean; +}> = (props) => { + const { getDate, randomHour } = props; const user = useUser(); - const { - currentWeek, - currentYear, - integrations, - posts, - trendings, - changeDate, - } = useCalendar(); + const { integrations, posts, trendings, changeDate, display } = useCalendar(); const toaster = useToaster(); const modal = useModals(); const fetch = useFetch(); - const getDate = useMemo(() => { - const date = - dayjs() - .year(currentYear) - .week(currentWeek) - .day(day + 1) - .format('YYYY-MM-DD') + - 'T' + - hour + - ':00'; - - return dayjs(date); - }, [currentWeek]); - const postList = useMemo(() => { return posts.filter((post) => { - return dayjs - .utc(post.publishDate) - .local() - .isBetween(getDate, getDate.add(59, 'minute'), 'minute', '[)'); + const pList = dayjs.utc(post.publishDate).local(); + return display === 'week' + ? pList.isBetween(getDate.startOf('hour'), getDate.endOf('hour')) + : pList.format('DD/MM/YYYY') === getDate.format('DD/MM/YYYY'); }); - }, [posts]); + }, [posts, display, getDate]); const canBeTrending = useMemo(() => { return !!trendings.find((trend) => { @@ -351,7 +300,9 @@ export const CalendarColumn: FC<{ day: number; hour: string }> = (props) => { children: ( ({ ...p }))} - date={getDate} + date={ + randomHour ? getDate.hour(Math.floor(Math.random() * 24)) : getDate + } reopenModal={() => ({})} /> ), @@ -363,70 +314,85 @@ export const CalendarColumn: FC<{ day: number; hour: string }> = (props) => { const addProvider = useAddProvider(); return ( -
+
+ {display === 'month' && ( +
+ {getDate.date()} +
+ )}
- {postList.map((post) => ( -
-
- + {postList.map((post) => ( +
+
+ +
+
+ ))} +
+ {!isBeforeNow && ( +
+
+
- ))} + )}
- {!isBeforeNow && ( -
-
-
-
-
- )}
); }; const CalendarItem: FC<{ date: dayjs.Dayjs; + isBeforeNow: boolean; editPost: () => void; integrations: Integrations[]; state: State; post: Post & { integration: Integration }; }> = (props) => { - const { editPost, post, date, integrations, state } = props; + const { editPost, post, date, isBeforeNow, state } = props; const [{ opacity }, dragRef] = useDrag( () => ({ type: 'post', @@ -444,7 +410,7 @@ const CalendarItem: FC<{ className={clsx( 'gap-[5px] w-full flex h-full flex-1 rounded-[10px] border border-seventh px-[5px] p-[2.5px]', 'relative', - state === 'DRAFT' && '!grayscale' + (state === 'DRAFT' || isBeforeNow) && '!grayscale' )} style={{ opacity }} > @@ -458,7 +424,10 @@ const CalendarItem: FC<{ src={`/icons/platforms/${post.integration?.providerIdentifier}.png`} />
-
{post.content}
+
+ {state === 'DRAFT' ? 'Draft: ' : ''} + {post.content} +
); }; diff --git a/apps/frontend/src/components/launches/filters.tsx b/apps/frontend/src/components/launches/filters.tsx index af3025c6..a789fea8 100644 --- a/apps/frontend/src/components/launches/filters.tsx +++ b/apps/frontend/src/components/launches/filters.tsx @@ -1,32 +1,109 @@ 'use client'; import { useCalendar } from '@gitroom/frontend/components/launches/calendar.context'; +import clsx from 'clsx'; import dayjs from 'dayjs'; -import {useCallback} from "react"; +import { useCallback } from 'react'; export const Filters = () => { const week = useCalendar(); const betweenDates = - dayjs().year(week.currentYear).isoWeek(week.currentWeek).startOf('isoWeek').format('DD/MM/YYYY') + - ' - ' + - dayjs().year(week.currentYear).isoWeek(week.currentWeek).endOf('isoWeek').format('DD/MM/YYYY'); + week.display === 'week' + ? dayjs() + .year(week.currentYear) + .isoWeek(week.currentWeek) + .startOf('isoWeek') + .format('DD/MM/YYYY') + + ' - ' + + dayjs() + .year(week.currentYear) + .isoWeek(week.currentWeek) + .endOf('isoWeek') + .format('DD/MM/YYYY') + : dayjs() + .year(week.currentYear) + .month(week.currentMonth) + .startOf('month') + .format('DD/MM/YYYY') + + ' - ' + + dayjs() + .year(week.currentYear) + .month(week.currentMonth) + .endOf('month') + .format('DD/MM/YYYY'); - const nextWeek = useCallback(() => { - week.setFilters({ - currentWeek: week.currentWeek === 52 ? 1 : week.currentWeek + 1, - currentYear: week.currentWeek === 52 ? week.currentYear + 1 : week.currentYear, - }); - }, [week.currentWeek, week.currentYear]); + const setWeek = useCallback(() => { + week.setFilters({ + currentWeek: dayjs().isoWeek(), + currentYear: dayjs().year(), + currentMonth: 0, + display: 'week', + }); + }, [week]); - const previousWeek = useCallback(() => { - week.setFilters({ - currentWeek: week.currentWeek === 1 ? 52 : week.currentWeek - 1, - currentYear: week.currentWeek === 1 ? week.currentYear - 1 : week.currentYear, - }); - }, [week.currentWeek, week.currentYear]); + const setMonth = useCallback(() => { + week.setFilters({ + currentMonth: dayjs().month(), + currentWeek: 0, + currentYear: dayjs().year(), + display: 'month', + }); + }, [week]); + + const next = useCallback(() => { + week.setFilters({ + currentWeek: + week.display === 'week' + ? week.currentWeek === 52 + ? 1 + : week.currentWeek + 1 + : 0, + currentYear: + week.display === 'week' + ? week.currentWeek === 52 + ? week.currentYear + 1 + : week.currentYear + : week.currentMonth === 11 + ? week.currentYear + 1 + : week.currentYear, + display: week.display as any, + currentMonth: + week.display === 'week' + ? 0 + : week.currentMonth === 11 + ? 0 + : week.currentMonth + 1, + }); + }, [week.display, week.currentMonth, week.currentWeek, week.currentYear]); + + const previous = useCallback(() => { + week.setFilters({ + currentWeek: + week.display === 'week' + ? week.currentWeek === 1 + ? 52 + : week.currentWeek - 1 + : 0, + currentYear: + week.display === 'week' + ? week.currentWeek === 1 + ? week.currentYear - 1 + : week.currentYear + : week.currentMonth === 0 + ? week.currentYear - 1 + : week.currentYear, + display: week.display as any, + currentMonth: + week.display === 'week' + ? 0 + : week.currentMonth === 0 + ? 11 + : week.currentMonth - 1, + }); + }, [week.display, week.currentMonth, week.currentWeek, week.currentYear]); return ( -
-
+
+
{ />
-
Week {week.currentWeek}
-
+
+ {week.display === 'week' + ? `Week ${week.currentWeek}` + : `${dayjs().month(week.currentMonth).format('MMMM')}`} +
+
{ />
-
{betweenDates}
+
{betweenDates}
+
+ Week +
+
+ Month +
); }; diff --git a/apps/frontend/src/components/launches/launches.component.tsx b/apps/frontend/src/components/launches/launches.component.tsx index 8c7a47e0..a9edc5d2 100644 --- a/apps/frontend/src/components/launches/launches.component.tsx +++ b/apps/frontend/src/components/launches/launches.component.tsx @@ -13,13 +13,12 @@ import { LoadingComponent } from '@gitroom/frontend/components/layout/loading'; import clsx from 'clsx'; import { useUser } from '../layout/user.context'; import { Menu } from '@gitroom/frontend/components/launches/menu/menu'; -import { GeneratorComponent } from '@gitroom/frontend/components/launches/generator/generator'; import { useRouter, useSearchParams } from 'next/navigation'; import { Integration } from '@prisma/client'; import ImageWithFallback from '@gitroom/react/helpers/image.with.fallback'; import { useToaster } from '@gitroom/react/toaster/toaster'; import { useFireEvents } from '@gitroom/helpers/utils/use.fire.events'; -import { NewCalendarComponent } from '@gitroom/frontend/components/launches/new.calendar.component'; +import { Calendar } from './calendar'; export const LaunchesComponent = () => { const fetch = useFetch(); @@ -117,7 +116,7 @@ export const LaunchesComponent = () => {
-
+

Channels

@@ -213,8 +212,7 @@ export const LaunchesComponent = () => {
- - {/**/} +
diff --git a/apps/frontend/src/components/launches/new.calendar.component.tsx b/apps/frontend/src/components/launches/new.calendar.component.tsx deleted file mode 100644 index 720443d6..00000000 --- a/apps/frontend/src/components/launches/new.calendar.component.tsx +++ /dev/null @@ -1,54 +0,0 @@ -'use client'; -import { Fragment } from 'react'; -import { CalendarColumn } from '@gitroom/frontend/components/launches/calendar'; -import { DNDProvider } from '@gitroom/frontend/components/launches/helpers/dnd.provider'; - -export const days = [ - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday', - 'Sunday', -]; -export const hours = Array.from({ length: 24 }, (_, i) => i); - -export const NewCalendarComponent = () => { - return ( - -
-
-
-
- {days.map((day, index) => ( -
-
{day}
-
- ))} - {hours.map((hour) => ( - -
- {hour.toString().padStart(2, '0')}:00 -
- {days.map((day, indexDay) => ( - -
- -
-
- ))} -
- ))} -
-
-
-
- ); -}; diff --git a/libraries/nestjs-libraries/src/database/prisma/posts/posts.repository.ts b/libraries/nestjs-libraries/src/database/prisma/posts/posts.repository.ts index e5931498..b4704b29 100644 --- a/libraries/nestjs-libraries/src/database/prisma/posts/posts.repository.ts +++ b/libraries/nestjs-libraries/src/database/prisma/posts/posts.repository.ts @@ -64,10 +64,10 @@ export class PostsRepository { getPosts(orgId: string, query: GetPostsDto) { const dateYear = dayjs().year(query.year); - const date = dateYear.isoWeek(query.week); + const date = query.week ? dateYear.isoWeek(query.week) : dateYear.month(query.month-1); - const startDate = date.startOf('isoWeek').subtract(2, 'days').toDate(); - const endDate = date.endOf('isoWeek').add(2, 'days').toDate(); + const startDate = (query.week ? date.startOf('isoWeek') : date.startOf('month')).subtract(2, 'days').toDate(); + const endDate = (query.week ? date.endOf('isoWeek') : date.endOf('month')).add(2, 'days').toDate(); return this._post.model.post.findMany({ where: { diff --git a/libraries/nestjs-libraries/src/dtos/posts/get.posts.dto.ts b/libraries/nestjs-libraries/src/dtos/posts/get.posts.dto.ts index 4872a787..1a89560f 100644 --- a/libraries/nestjs-libraries/src/dtos/posts/get.posts.dto.ts +++ b/libraries/nestjs-libraries/src/dtos/posts/get.posts.dto.ts @@ -1,14 +1,22 @@ import { Type } from 'class-transformer'; -import { IsIn, IsNumber, IsString, Max, Min } from 'class-validator'; +import { IsIn, IsNumber, IsString, Max, Min, ValidateIf } from 'class-validator'; import dayjs from 'dayjs'; export class GetPostsDto { + @ValidateIf((o) => !o.month) @Type(() => Number) @IsNumber() @Max(52) @Min(1) week: number; + @ValidateIf((o) => !o.week) + @Type(() => Number) + @IsNumber() + @Max(52) + @Min(1) + month: number; + @Type(() => Number) @IsNumber() @Max(dayjs().add(10, 'year').year()) From 471bce7f15dfa2216966fa813309a3bcb79109c8 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Sun, 8 Sep 2024 20:42:10 +0700 Subject: [PATCH 10/62] feat: calendar change --- apps/frontend/src/components/launches/calendar.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/frontend/src/components/launches/calendar.tsx b/apps/frontend/src/components/launches/calendar.tsx index 5a048898..28b00763 100644 --- a/apps/frontend/src/components/launches/calendar.tsx +++ b/apps/frontend/src/components/launches/calendar.tsx @@ -169,6 +169,7 @@ export const CalendarColumn: FC<{ }); }, [posts, display, getDate]); + const canBeTrending = useMemo(() => { return !!trendings.find((trend) => { return dayjs From e165122a551c2509bdda20b06e865a95e52c3fd4 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Sun, 8 Sep 2024 23:38:48 +0700 Subject: [PATCH 11/62] feat: schedule fixing --- .../src/components/launches/calendar.tsx | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/apps/frontend/src/components/launches/calendar.tsx b/apps/frontend/src/components/launches/calendar.tsx index 28b00763..f1a79dd6 100644 --- a/apps/frontend/src/components/launches/calendar.tsx +++ b/apps/frontend/src/components/launches/calendar.tsx @@ -21,6 +21,10 @@ import { useToaster } from '@gitroom/react/toaster/toaster'; import { useUser } from '@gitroom/frontend/components/layout/user.context'; import { IntegrationContext } from '@gitroom/frontend/components/launches/helpers/use.integration'; import { PreviewPopup } from '@gitroom/frontend/components/marketplace/special.message'; +import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'; +import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'; +dayjs.extend(isSameOrAfter); +dayjs.extend(isSameOrBefore); export const days = [ 'Monday', @@ -163,9 +167,12 @@ export const CalendarColumn: FC<{ const postList = useMemo(() => { return posts.filter((post) => { const pList = dayjs.utc(post.publishDate).local(); - return display === 'week' - ? pList.isBetween(getDate.startOf('hour'), getDate.endOf('hour')) + const check = display === 'week' + ? pList.isSameOrAfter(getDate.startOf('hour')) && pList.isBefore(getDate.endOf('hour')) : pList.format('DD/MM/YYYY') === getDate.format('DD/MM/YYYY'); + + console.log('check', check); + return check; }); }, [posts, display, getDate]); @@ -180,7 +187,7 @@ export const CalendarColumn: FC<{ }, [trendings]); const isBeforeNow = useMemo(() => { - return getDate.isBefore(dayjs()); + return getDate.startOf('hour').isBefore(dayjs().startOf('hour')); }, [getDate]); const [{ canDrop }, drop] = useDrop(() => ({ @@ -310,12 +317,12 @@ export const CalendarColumn: FC<{ size: '80%', // title: `Adding posts for ${getDate.format('DD/MM/YYYY HH:mm')}`, }); - }, [integrations]); + }, [integrations, getDate]); const addProvider = useAddProvider(); return ( -
+
{display === 'month' && (
{getDate.date()} @@ -326,7 +333,6 @@ export const CalendarColumn: FC<{ 'relative flex flex-col flex-1', canDrop && 'bg-white/80' )} - ref={drop} >
From b82803501980d9d584d2b1b332a9b5faef5ba639 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 9 Sep 2024 00:57:18 +0700 Subject: [PATCH 12/62] feat: calendar context --- apps/frontend/src/components/launches/calendar.context.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/src/components/launches/calendar.context.tsx b/apps/frontend/src/components/launches/calendar.context.tsx index 5cb333b1..bc3e91d3 100644 --- a/apps/frontend/src/components/launches/calendar.context.tsx +++ b/apps/frontend/src/components/launches/calendar.context.tsx @@ -142,7 +142,7 @@ export const CalendarWeekProvider: FC<{ const data = (await fetch(`${url}?${params}`)).json(); return data; }, - [filters] + [filters, params] ); const swr = useSWR(`/posts`, loadData, { From 59923fa4100359e30d5e99c18108bc10470f5b7b Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 9 Sep 2024 01:00:56 +0700 Subject: [PATCH 13/62] feat: fix extend --- apps/frontend/src/components/launches/calendar.context.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/frontend/src/components/launches/calendar.context.tsx b/apps/frontend/src/components/launches/calendar.context.tsx index bc3e91d3..37644028 100644 --- a/apps/frontend/src/components/launches/calendar.context.tsx +++ b/apps/frontend/src/components/launches/calendar.context.tsx @@ -17,6 +17,11 @@ import { useFetch } from '@gitroom/helpers/utils/custom.fetch'; import { Post, Integration } from '@prisma/client'; import { useRouter, useSearchParams } from 'next/navigation'; import { isGeneral } from '@gitroom/react/helpers/is.general'; +import isoWeek from 'dayjs/plugin/isoWeek'; +import weekOfYear from 'dayjs/plugin/weekOfYear'; + +dayjs.extend(isoWeek); +dayjs.extend(weekOfYear); const CalendarContext = createContext({ currentWeek: dayjs().week(), From c6d68c8fffb17167afeb6ea94380edaf71a153a6 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 9 Sep 2024 01:07:51 +0700 Subject: [PATCH 14/62] feat: posts --- apps/frontend/src/components/launches/calendar.context.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/frontend/src/components/launches/calendar.context.tsx b/apps/frontend/src/components/launches/calendar.context.tsx index 37644028..16274952 100644 --- a/apps/frontend/src/components/launches/calendar.context.tsx +++ b/apps/frontend/src/components/launches/calendar.context.tsx @@ -113,7 +113,9 @@ export const CalendarWeekProvider: FC<{ display: 'week' | 'month'; }) => { setFilters(filters); - router.replace( + window.history.replaceState( + null, + '', `/launches?${ filters.currentWeek ? `week=${filters.currentWeek}` @@ -122,7 +124,7 @@ export const CalendarWeekProvider: FC<{ ); setTimeout(() => { mutate('/posts'); - }); + }, 10); }, [filters] ); From f1dece41717482589c47c381c0f591b951c7b0d7 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 9 Sep 2024 01:12:39 +0700 Subject: [PATCH 15/62] feat: internal data --- apps/frontend/src/components/launches/calendar.context.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/src/components/launches/calendar.context.tsx b/apps/frontend/src/components/launches/calendar.context.tsx index 16274952..01bb5609 100644 --- a/apps/frontend/src/components/launches/calendar.context.tsx +++ b/apps/frontend/src/components/launches/calendar.context.tsx @@ -113,6 +113,7 @@ export const CalendarWeekProvider: FC<{ display: 'week' | 'month'; }) => { setFilters(filters); + setInternalData([]); window.history.replaceState( null, '', @@ -145,7 +146,6 @@ export const CalendarWeekProvider: FC<{ const loadData = useCallback( async (url: string) => { - setInternalData([]); const data = (await fetch(`${url}?${params}`)).json(); return data; }, From c52faabb50213e883594a31128824a669cce91aa Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 9 Sep 2024 01:29:29 +0700 Subject: [PATCH 16/62] feat: reload --- apps/frontend/src/components/launches/calendar.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/frontend/src/components/launches/calendar.tsx b/apps/frontend/src/components/launches/calendar.tsx index f1a79dd6..354e2666 100644 --- a/apps/frontend/src/components/launches/calendar.tsx +++ b/apps/frontend/src/components/launches/calendar.tsx @@ -1,6 +1,6 @@ 'use client'; -import React, { FC, Fragment, useCallback, useMemo } from 'react'; +import React, { FC, Fragment, useCallback, useEffect, useMemo, useState } from 'react'; import { Integrations, useCalendar, @@ -145,6 +145,17 @@ export const MonthView = () => { export const Calendar = () => { const { display } = useCalendar(); + const [firstDisplay, setFirstDisplay] = useState(display); + + useEffect(() => { + setTimeout(() => { + setFirstDisplay(display); + }, 10); + }, [display]); + + if (display !== firstDisplay) { + return <>; + } return ( {display === 'week' ? : } @@ -171,7 +182,6 @@ export const CalendarColumn: FC<{ ? pList.isSameOrAfter(getDate.startOf('hour')) && pList.isBefore(getDate.endOf('hour')) : pList.format('DD/MM/YYYY') === getDate.format('DD/MM/YYYY'); - console.log('check', check); return check; }); }, [posts, display, getDate]); From 0c4d745569ccb3d746e0275b991ae56480c284b8 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 9 Sep 2024 01:32:32 +0700 Subject: [PATCH 17/62] feat: 1000ms --- apps/frontend/src/components/launches/calendar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/src/components/launches/calendar.tsx b/apps/frontend/src/components/launches/calendar.tsx index 354e2666..bc087c50 100644 --- a/apps/frontend/src/components/launches/calendar.tsx +++ b/apps/frontend/src/components/launches/calendar.tsx @@ -150,7 +150,7 @@ export const Calendar = () => { useEffect(() => { setTimeout(() => { setFirstDisplay(display); - }, 10); + }, 1000); }, [display]); if (display !== firstDisplay) { From 20217f6bef28531ff14e3b1a5cf5f30daea00e11 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 9 Sep 2024 01:39:14 +0700 Subject: [PATCH 18/62] feat: mutate --- .../components/launches/calendar.context.tsx | 51 ++++++++++--------- .../src/components/launches/calendar.tsx | 10 ---- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/apps/frontend/src/components/launches/calendar.context.tsx b/apps/frontend/src/components/launches/calendar.context.tsx index 01bb5609..d37b2ce1 100644 --- a/apps/frontend/src/components/launches/calendar.context.tsx +++ b/apps/frontend/src/components/launches/calendar.context.tsx @@ -105,31 +105,6 @@ export const CalendarWeekProvider: FC<{ display, }); - const setFiltersWrapper = useCallback( - (filters: { - currentWeek: number; - currentYear: number; - currentMonth: number; - display: 'week' | 'month'; - }) => { - setFilters(filters); - setInternalData([]); - window.history.replaceState( - null, - '', - `/launches?${ - filters.currentWeek - ? `week=${filters.currentWeek}` - : `month=${filters.currentMonth}` - }&year=${filters.currentYear}` - ); - setTimeout(() => { - mutate('/posts'); - }, 10); - }, - [filters] - ); - const params = useMemo(() => { return new URLSearchParams( filters.currentWeek @@ -158,6 +133,32 @@ export const CalendarWeekProvider: FC<{ refreshWhenHidden: false, revalidateOnFocus: false, }); + + const setFiltersWrapper = useCallback( + (filters: { + currentWeek: number; + currentYear: number; + currentMonth: number; + display: 'week' | 'month'; + }) => { + setFilters(filters); + setInternalData([]); + window.history.replaceState( + null, + '', + `/launches?${ + filters.currentWeek + ? `week=${filters.currentWeek}` + : `month=${filters.currentMonth}` + }&year=${filters.currentYear}` + ); + setTimeout(() => { + swr.mutate(); + }, 10); + }, + [filters, swr.mutate] + ); + const { isLoading } = swr; const { posts, comments } = swr?.data || { posts: [], comments: [] }; diff --git a/apps/frontend/src/components/launches/calendar.tsx b/apps/frontend/src/components/launches/calendar.tsx index bc087c50..b7c944f2 100644 --- a/apps/frontend/src/components/launches/calendar.tsx +++ b/apps/frontend/src/components/launches/calendar.tsx @@ -145,17 +145,7 @@ export const MonthView = () => { export const Calendar = () => { const { display } = useCalendar(); - const [firstDisplay, setFirstDisplay] = useState(display); - useEffect(() => { - setTimeout(() => { - setFirstDisplay(display); - }, 1000); - }, [display]); - - if (display !== firstDisplay) { - return <>; - } return ( {display === 'week' ? : } From a70ef27cb2a35869e677f18baa021e96c81388dd Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 02:45:41 +0100 Subject: [PATCH 19/62] wip: Arch, devcontainer + dist, supervisord --- .devcontainer/devcontainer.json | 14 ++++++ .dockerignore | 6 +++ Dockerfile | 77 ++++++++++++++++------------- package.json | 4 +- var/docker/entrypoint.sh | 36 ++++++++++++++ var/docker/supervisord/backend.ini | 5 ++ var/docker/supervisord/base.ini | 6 +++ var/docker/supervisord/cron.ini | 5 ++ var/docker/supervisord/frontend.ini | 5 ++ var/docker/supervisord/workers.ini | 5 ++ 10 files changed, 127 insertions(+), 36 deletions(-) create mode 100644 .devcontainer/devcontainer.json create mode 100644 .dockerignore create mode 100755 var/docker/entrypoint.sh create mode 100644 var/docker/supervisord/backend.ini create mode 100644 var/docker/supervisord/base.ini create mode 100644 var/docker/supervisord/cron.ini create mode 100644 var/docker/supervisord/frontend.ini create mode 100644 var/docker/supervisord/workers.ini diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..6854df0b --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,14 @@ +{ + "name": "Postiz Dev Container", + "image": "localhost/postiz-devcontainer", + "features": {}, + "customizations": { + "vscode": { + "settings": {}, + "extensions": [] + } + }, + "forwardPorts": ["4200:4200", "3000:3000"], + "mounts": ["source=/apps,destination=/apps/dist/,type=bind,consistency=cached"] +} + diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..6b6f71ee --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +# We want the docker builds to be clean, and as fast as possible. Don't send +# any half-built stuff in the build context as a pre-caution (also saves copying +# 180k files in node_modules that isn't used!). +node_modules +dist +.nx diff --git a/Dockerfile b/Dockerfile index 5e87f34a..46619784 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,43 +1,52 @@ -# Foundation image -FROM registry.fedoraproject.org/fedora-minimal:40 AS foundation +# Base image +FROM docker.io/node:20.17-alpine3.19 AS base -RUN microdnf install --nodocs --noplugins --setopt=keepcache=0 --setopt=install_weak_deps=0 -y \ - npm \ - node \ - && microdnf clean all +ENV NPM_CONFIG_UPDATE_NOTIFIER=false +ENV NEXT_TELEMETRY_DISABLED=1 -# Builder image -FROM foundation AS builder +RUN apk add --no-cache \ + bash=5.2.21-r0 \ + supervisor=4.2.5-r4 -RUN mkdir /src - -COPY . /src - -WORKDIR /src - -RUN npx nx reset -RUN npm run build - -# Output image -FROM foundation AS dist - -LABEL org.opencontainers.image.source=https://github.com/gitroomhq/postiz-app -LABEL org.opencontainers.image.title="Postiz App" - -RUN mkdir -p /config /app - -VOLUME /config - -COPY --from=builder /src/dist /app/dist/ -COPY --from=builder /src/package.json /app/ -COPY --from=builder /src/nx.json /app/ - -COPY .env.example /config/.env -COPY var/docker-entrypoint.sh /app/entrypoint.sh +WORKDIR /app EXPOSE 4200 EXPOSE 3000 -WORKDIR /app +RUN mkdir -p /config + +COPY .env.example /config/.env + +VOLUME /config + +LABEL org.opencontainers.image.source=https://github.com/gitroomhq/postiz-app + +# Builder image +FROM base AS devcontainer + +COPY nx.json tsconfig.base.json package.json package-lock.json /app/ +COPY apps /app/apps/ +COPY libraries /app/libraries/ + +RUN npm ci --no-fund && npm run build + +COPY var/docker/entrypoint.sh /app/entrypoint.sh +COPY var/docker/supervisord/* /app/supervisord_configs/ + +LABEL org.opencontainers.image.title="Postiz App (DevContainer)" + +ENTRYPOINT ["/app/entrypoint.sh"] + +# Output image +FROM base AS dist + +COPY --from=devcontainer /app/node_modules/ /app/node_modules/ +COPY --from=devcontainer /app/dist/ /app/dist/ + +COPY package.json nx.json /app/ +COPY var/docker/entrypoint.sh /app/entrypoint.sh + +## Labels at the bottom, because CI will eventially add dates, commit hashes, etc. +LABEL org.opencontainers.image.title="Postiz App (Production)" ENTRYPOINT ["/app/entrypoint.sh"] diff --git a/package.json b/package.json index 2ea2cf88..efd4a817 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,8 @@ "prisma-generate": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma generate", "prisma-db-push": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma db push", "prisma-reset": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma db push --force-reset && npx prisma db push", - "docker-build": "docker rmi localhost/postiz || true && docker build -t localhost/postiz . ", - "docker-create": "docker kill postiz || true && docker rm postiz || true && docker create --name postiz -p 3000:3000 -p 4200:4200 localhost/postiz", + "docker-build": "docker rmi localhost/postiz || true && docker build --target dist -t localhost/postiz -f Dockerfile . && docker build --target devcontainer -t localhost/postiz-devcontainer -f Dockerfile .", + "docker-create": "docker kill postiz || true && docker rm postiz || true && docker create --name postiz -p 3000:3000 -p 4200:4200 localhost/postiz", "postinstall": "npm run prisma-generate" }, "private": true, diff --git a/var/docker/entrypoint.sh b/var/docker/entrypoint.sh new file mode 100755 index 00000000..609fa7d0 --- /dev/null +++ b/var/docker/entrypoint.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +if [[ "$SKIP_CONFIG_CHECK" -ne "true" ]]; then + if [ ! -f /config/.env ]; then + echo "ERROR: No .env file found in /config/.env" + fi + + ln -s /config/env /app/.env +fi + +if [[ "$POSTIZ_APPS" -eq "" ]]; then + echo "POSTIZ_APPS is not set, starting everything!" + POSTIZ_APPS="frontend workers cron" +fi + +mkdir -p /etc/supervisor.d/ + +cp /app/supervisord_configs/base.conf /etc/supervisor.d/ + +if [[ "$POSTIZ_APPS" == *"frontend"* ]]; then + cp /app/supervisord_configs/frontend.conf /etc/supervisor.d/ +fi + +if [[ $POSTIZ_APPS == *"workers"* ]]; then + cp /app/supervisord_configs/workers.conf /etc/supervisor.d/ +fi + +if [[ $POSTIZ_APPS == *"cron"* ]]; then + cp /app/supervisord_configs/cron.conf /etc/supervisor.d/ +fi + +if [[ $POSTIZ_APPS == *"backend"* ]]; then + cp /app/supervisord_configs/backend.conf /etc/supervisor.d/ +fi + +/usr/bin/supervisord diff --git a/var/docker/supervisord/backend.ini b/var/docker/supervisord/backend.ini new file mode 100644 index 00000000..8e56645c --- /dev/null +++ b/var/docker/supervisord/backend.ini @@ -0,0 +1,5 @@ +[program:backend] +directory=/app +command=npm run start:prod +autostart=true +autorestart=false diff --git a/var/docker/supervisord/base.ini b/var/docker/supervisord/base.ini new file mode 100644 index 00000000..b220a983 --- /dev/null +++ b/var/docker/supervisord/base.ini @@ -0,0 +1,6 @@ +[supervisord] +nodaemon=true +logfile=/dev/null +logfile_maxbytes=0 + + diff --git a/var/docker/supervisord/cron.ini b/var/docker/supervisord/cron.ini new file mode 100644 index 00000000..ef22047a --- /dev/null +++ b/var/docker/supervisord/cron.ini @@ -0,0 +1,5 @@ +[program:cron] +directory=/app +command=npm run start:prod:cron +autostart=true +autorestart=false diff --git a/var/docker/supervisord/frontend.ini b/var/docker/supervisord/frontend.ini new file mode 100644 index 00000000..737aedd9 --- /dev/null +++ b/var/docker/supervisord/frontend.ini @@ -0,0 +1,5 @@ +[program:frontend] +directory=/app +command=npm run start:prod:frontend +autostart=true +autorestart=false diff --git a/var/docker/supervisord/workers.ini b/var/docker/supervisord/workers.ini new file mode 100644 index 00000000..fd84a708 --- /dev/null +++ b/var/docker/supervisord/workers.ini @@ -0,0 +1,5 @@ +[program:workers] +directory=/app +command=npm run start:prod:workers +autostart=true +autorestart=false From 260b281cb448c9a9c4f77a311c2202caaa02a556 Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 02:45:41 +0100 Subject: [PATCH 20/62] wip: Arch, devcontainer + dist, supervisord Co-Authored-By: jonathan-irvin --- .devcontainer/devcontainer.json | 14 ++++++ .dockerignore | 6 +++ Dockerfile | 77 ++++++++++++++++------------- package.json | 4 +- var/docker/entrypoint.sh | 36 ++++++++++++++ var/docker/supervisord/backend.ini | 5 ++ var/docker/supervisord/base.ini | 6 +++ var/docker/supervisord/cron.ini | 5 ++ var/docker/supervisord/frontend.ini | 5 ++ var/docker/supervisord/workers.ini | 5 ++ 10 files changed, 127 insertions(+), 36 deletions(-) create mode 100644 .devcontainer/devcontainer.json create mode 100644 .dockerignore create mode 100755 var/docker/entrypoint.sh create mode 100644 var/docker/supervisord/backend.ini create mode 100644 var/docker/supervisord/base.ini create mode 100644 var/docker/supervisord/cron.ini create mode 100644 var/docker/supervisord/frontend.ini create mode 100644 var/docker/supervisord/workers.ini diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..6854df0b --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,14 @@ +{ + "name": "Postiz Dev Container", + "image": "localhost/postiz-devcontainer", + "features": {}, + "customizations": { + "vscode": { + "settings": {}, + "extensions": [] + } + }, + "forwardPorts": ["4200:4200", "3000:3000"], + "mounts": ["source=/apps,destination=/apps/dist/,type=bind,consistency=cached"] +} + diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..6b6f71ee --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +# We want the docker builds to be clean, and as fast as possible. Don't send +# any half-built stuff in the build context as a pre-caution (also saves copying +# 180k files in node_modules that isn't used!). +node_modules +dist +.nx diff --git a/Dockerfile b/Dockerfile index 5e87f34a..46619784 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,43 +1,52 @@ -# Foundation image -FROM registry.fedoraproject.org/fedora-minimal:40 AS foundation +# Base image +FROM docker.io/node:20.17-alpine3.19 AS base -RUN microdnf install --nodocs --noplugins --setopt=keepcache=0 --setopt=install_weak_deps=0 -y \ - npm \ - node \ - && microdnf clean all +ENV NPM_CONFIG_UPDATE_NOTIFIER=false +ENV NEXT_TELEMETRY_DISABLED=1 -# Builder image -FROM foundation AS builder +RUN apk add --no-cache \ + bash=5.2.21-r0 \ + supervisor=4.2.5-r4 -RUN mkdir /src - -COPY . /src - -WORKDIR /src - -RUN npx nx reset -RUN npm run build - -# Output image -FROM foundation AS dist - -LABEL org.opencontainers.image.source=https://github.com/gitroomhq/postiz-app -LABEL org.opencontainers.image.title="Postiz App" - -RUN mkdir -p /config /app - -VOLUME /config - -COPY --from=builder /src/dist /app/dist/ -COPY --from=builder /src/package.json /app/ -COPY --from=builder /src/nx.json /app/ - -COPY .env.example /config/.env -COPY var/docker-entrypoint.sh /app/entrypoint.sh +WORKDIR /app EXPOSE 4200 EXPOSE 3000 -WORKDIR /app +RUN mkdir -p /config + +COPY .env.example /config/.env + +VOLUME /config + +LABEL org.opencontainers.image.source=https://github.com/gitroomhq/postiz-app + +# Builder image +FROM base AS devcontainer + +COPY nx.json tsconfig.base.json package.json package-lock.json /app/ +COPY apps /app/apps/ +COPY libraries /app/libraries/ + +RUN npm ci --no-fund && npm run build + +COPY var/docker/entrypoint.sh /app/entrypoint.sh +COPY var/docker/supervisord/* /app/supervisord_configs/ + +LABEL org.opencontainers.image.title="Postiz App (DevContainer)" + +ENTRYPOINT ["/app/entrypoint.sh"] + +# Output image +FROM base AS dist + +COPY --from=devcontainer /app/node_modules/ /app/node_modules/ +COPY --from=devcontainer /app/dist/ /app/dist/ + +COPY package.json nx.json /app/ +COPY var/docker/entrypoint.sh /app/entrypoint.sh + +## Labels at the bottom, because CI will eventially add dates, commit hashes, etc. +LABEL org.opencontainers.image.title="Postiz App (Production)" ENTRYPOINT ["/app/entrypoint.sh"] diff --git a/package.json b/package.json index 2ea2cf88..efd4a817 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,8 @@ "prisma-generate": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma generate", "prisma-db-push": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma db push", "prisma-reset": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma db push --force-reset && npx prisma db push", - "docker-build": "docker rmi localhost/postiz || true && docker build -t localhost/postiz . ", - "docker-create": "docker kill postiz || true && docker rm postiz || true && docker create --name postiz -p 3000:3000 -p 4200:4200 localhost/postiz", + "docker-build": "docker rmi localhost/postiz || true && docker build --target dist -t localhost/postiz -f Dockerfile . && docker build --target devcontainer -t localhost/postiz-devcontainer -f Dockerfile .", + "docker-create": "docker kill postiz || true && docker rm postiz || true && docker create --name postiz -p 3000:3000 -p 4200:4200 localhost/postiz", "postinstall": "npm run prisma-generate" }, "private": true, diff --git a/var/docker/entrypoint.sh b/var/docker/entrypoint.sh new file mode 100755 index 00000000..609fa7d0 --- /dev/null +++ b/var/docker/entrypoint.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +if [[ "$SKIP_CONFIG_CHECK" -ne "true" ]]; then + if [ ! -f /config/.env ]; then + echo "ERROR: No .env file found in /config/.env" + fi + + ln -s /config/env /app/.env +fi + +if [[ "$POSTIZ_APPS" -eq "" ]]; then + echo "POSTIZ_APPS is not set, starting everything!" + POSTIZ_APPS="frontend workers cron" +fi + +mkdir -p /etc/supervisor.d/ + +cp /app/supervisord_configs/base.conf /etc/supervisor.d/ + +if [[ "$POSTIZ_APPS" == *"frontend"* ]]; then + cp /app/supervisord_configs/frontend.conf /etc/supervisor.d/ +fi + +if [[ $POSTIZ_APPS == *"workers"* ]]; then + cp /app/supervisord_configs/workers.conf /etc/supervisor.d/ +fi + +if [[ $POSTIZ_APPS == *"cron"* ]]; then + cp /app/supervisord_configs/cron.conf /etc/supervisor.d/ +fi + +if [[ $POSTIZ_APPS == *"backend"* ]]; then + cp /app/supervisord_configs/backend.conf /etc/supervisor.d/ +fi + +/usr/bin/supervisord diff --git a/var/docker/supervisord/backend.ini b/var/docker/supervisord/backend.ini new file mode 100644 index 00000000..8e56645c --- /dev/null +++ b/var/docker/supervisord/backend.ini @@ -0,0 +1,5 @@ +[program:backend] +directory=/app +command=npm run start:prod +autostart=true +autorestart=false diff --git a/var/docker/supervisord/base.ini b/var/docker/supervisord/base.ini new file mode 100644 index 00000000..b220a983 --- /dev/null +++ b/var/docker/supervisord/base.ini @@ -0,0 +1,6 @@ +[supervisord] +nodaemon=true +logfile=/dev/null +logfile_maxbytes=0 + + diff --git a/var/docker/supervisord/cron.ini b/var/docker/supervisord/cron.ini new file mode 100644 index 00000000..ef22047a --- /dev/null +++ b/var/docker/supervisord/cron.ini @@ -0,0 +1,5 @@ +[program:cron] +directory=/app +command=npm run start:prod:cron +autostart=true +autorestart=false diff --git a/var/docker/supervisord/frontend.ini b/var/docker/supervisord/frontend.ini new file mode 100644 index 00000000..737aedd9 --- /dev/null +++ b/var/docker/supervisord/frontend.ini @@ -0,0 +1,5 @@ +[program:frontend] +directory=/app +command=npm run start:prod:frontend +autostart=true +autorestart=false diff --git a/var/docker/supervisord/workers.ini b/var/docker/supervisord/workers.ini new file mode 100644 index 00000000..fd84a708 --- /dev/null +++ b/var/docker/supervisord/workers.ini @@ -0,0 +1,5 @@ +[program:workers] +directory=/app +command=npm run start:prod:workers +autostart=true +autorestart=false From 19b838a84bfc7216052a08af85edb705772695f4 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 9 Sep 2024 11:51:03 +0700 Subject: [PATCH 21/62] feat: change name of swr --- .../src/components/launches/calendar.context.tsx | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/apps/frontend/src/components/launches/calendar.context.tsx b/apps/frontend/src/components/launches/calendar.context.tsx index d37b2ce1..2eb28c62 100644 --- a/apps/frontend/src/components/launches/calendar.context.tsx +++ b/apps/frontend/src/components/launches/calendar.context.tsx @@ -79,19 +79,8 @@ export const CalendarWeekProvider: FC<{ }> = ({ children, integrations }) => { const fetch = useFetch(); const [internalData, setInternalData] = useState([] as any[]); - const [trendings, setTrendings] = useState([]); - const { mutate } = useSWRConfig(); + const [trendings] = useState([]); const searchParams = useSearchParams(); - const router = useRouter(); - - useEffect(() => { - (async () => { - if (isGeneral()) { - return []; - } - setTrendings(await (await fetch('/posts/predict-trending')).json()); - })(); - }, []); const display = searchParams.get('month') ? 'month' : 'week'; const [filters, setFilters] = useState({ @@ -127,7 +116,7 @@ export const CalendarWeekProvider: FC<{ [filters, params] ); - const swr = useSWR(`/posts`, loadData, { + const swr = useSWR(`/posts-${params}`, loadData, { refreshInterval: 3600000, refreshWhenOffline: false, refreshWhenHidden: false, From 9974e71859ae080fa22a8b0ca658f3aba0ff4f69 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 9 Sep 2024 12:01:14 +0700 Subject: [PATCH 22/62] feat: fix fetch --- apps/frontend/src/components/launches/calendar.context.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/src/components/launches/calendar.context.tsx b/apps/frontend/src/components/launches/calendar.context.tsx index 2eb28c62..1d4990b7 100644 --- a/apps/frontend/src/components/launches/calendar.context.tsx +++ b/apps/frontend/src/components/launches/calendar.context.tsx @@ -110,7 +110,7 @@ export const CalendarWeekProvider: FC<{ const loadData = useCallback( async (url: string) => { - const data = (await fetch(`${url}?${params}`)).json(); + const data = (await fetch(`/posts${url}?${params}`)).json(); return data; }, [filters, params] From 048df4fb4426156bee9c43f77d6c83769d8c345d Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 9 Sep 2024 12:09:41 +0700 Subject: [PATCH 23/62] feat: it will auto load the new filters --- apps/frontend/src/components/launches/calendar.context.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/frontend/src/components/launches/calendar.context.tsx b/apps/frontend/src/components/launches/calendar.context.tsx index 1d4990b7..81dde56c 100644 --- a/apps/frontend/src/components/launches/calendar.context.tsx +++ b/apps/frontend/src/components/launches/calendar.context.tsx @@ -109,8 +109,8 @@ export const CalendarWeekProvider: FC<{ }, [filters]); const loadData = useCallback( - async (url: string) => { - const data = (await fetch(`/posts${url}?${params}`)).json(); + async () => { + const data = (await fetch(`/posts?${params}`)).json(); return data; }, [filters, params] @@ -141,9 +141,6 @@ export const CalendarWeekProvider: FC<{ : `month=${filters.currentMonth}` }&year=${filters.currentYear}` ); - setTimeout(() => { - swr.mutate(); - }, 10); }, [filters, swr.mutate] ); From a5cecc9d3337d4b72e590df2f775837c75eca933 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 9 Sep 2024 12:20:08 +0700 Subject: [PATCH 24/62] feat: reload calendar modal --- .../components/launches/add.edit.model.tsx | 10 ++--- .../components/launches/calendar.context.tsx | 2 + .../src/components/launches/calendar.tsx | 39 ++++++++++++++----- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/apps/frontend/src/components/launches/add.edit.model.tsx b/apps/frontend/src/components/launches/add.edit.model.tsx index 5bc20e65..b4de0725 100644 --- a/apps/frontend/src/components/launches/add.edit.model.tsx +++ b/apps/frontend/src/components/launches/add.edit.model.tsx @@ -32,7 +32,7 @@ import { TopTitle } from '@gitroom/frontend/components/launches/helpers/top.titl import { PickPlatforms } from '@gitroom/frontend/components/launches/helpers/pick.platform.component'; import { ProvidersOptions } from '@gitroom/frontend/components/launches/providers.options'; import { v4 as uuidv4 } from 'uuid'; -import useSWR, { useSWRConfig } from 'swr'; +import useSWR from 'swr'; import { useToaster } from '@gitroom/react/toaster/toaster'; import { UpDownArrow } from '@gitroom/frontend/components/launches/up.down.arrow'; import { DatePicker } from '@gitroom/frontend/components/launches/helpers/date.picker'; @@ -53,10 +53,10 @@ export const AddEditModal: FC<{ date: dayjs.Dayjs; integrations: Integrations[]; reopenModal: () => void; + mutate: () => void; }> = (props) => { - const { date, integrations, reopenModal } = props; + const { date, integrations, reopenModal, mutate } = props; const [dateState, setDateState] = useState(date); - const { mutate } = useSWRConfig(); // hook to open a new modal const modal = useModals(); @@ -243,7 +243,7 @@ export const AddEditModal: FC<{ await fetch(`/posts/${existingData.group}`, { method: 'DELETE', }); - mutate('/posts'); + mutate(); modal.closeAll(); return; } @@ -321,7 +321,7 @@ export const AddEditModal: FC<{ existingData.group = uuidv4(); - mutate('/posts'); + mutate(); toaster.show( !existingData.integration ? 'Added successfully' diff --git a/apps/frontend/src/components/launches/calendar.context.tsx b/apps/frontend/src/components/launches/calendar.context.tsx index 81dde56c..ae63d017 100644 --- a/apps/frontend/src/components/launches/calendar.context.tsx +++ b/apps/frontend/src/components/launches/calendar.context.tsx @@ -31,6 +31,7 @@ const CalendarContext = createContext({ integrations: [] as Integrations[], trendings: [] as string[], posts: [] as Array, + reloadCalendarView: () => {/** empty **/}, display: 'week', setFilters: (filters: { currentWeek: number; @@ -175,6 +176,7 @@ export const CalendarWeekProvider: FC<{ = (props) => { const { getDate, randomHour } = props; const user = useUser(); - const { integrations, posts, trendings, changeDate, display } = useCalendar(); + const { + integrations, + posts, + trendings, + changeDate, + display, + reloadCalendarView, + } = useCalendar(); const toaster = useToaster(); const modal = useModals(); @@ -168,15 +182,16 @@ export const CalendarColumn: FC<{ const postList = useMemo(() => { return posts.filter((post) => { const pList = dayjs.utc(post.publishDate).local(); - const check = display === 'week' - ? pList.isSameOrAfter(getDate.startOf('hour')) && pList.isBefore(getDate.endOf('hour')) - : pList.format('DD/MM/YYYY') === getDate.format('DD/MM/YYYY'); + const check = + display === 'week' + ? pList.isSameOrAfter(getDate.startOf('hour')) && + pList.isBefore(getDate.endOf('hour')) + : pList.format('DD/MM/YYYY') === getDate.format('DD/MM/YYYY'); return check; }); }, [posts, display, getDate]); - const canBeTrending = useMemo(() => { return !!trendings.find((trend) => { return dayjs @@ -282,6 +297,7 @@ export const CalendarColumn: FC<{ f.id === data.integration) @@ -308,6 +324,7 @@ export const CalendarColumn: FC<{ children: ( ({ ...p }))} + mutate={reloadCalendarView} date={ randomHour ? getDate.hour(Math.floor(Math.random() * 24)) : getDate } @@ -368,11 +385,15 @@ export const CalendarColumn: FC<{ ))}
{!isBeforeNow && ( -
+
Date: Mon, 9 Sep 2024 10:40:47 +0100 Subject: [PATCH 25/62] feat: eslint GitHub Action --- .github/workflows/eslint.yaml | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 .github/workflows/eslint.yaml diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml new file mode 100644 index 00000000..1e1f88f5 --- /dev/null +++ b/.github/workflows/eslint.yaml @@ -0,0 +1,41 @@ +--- +name: ESLint + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + eslint: + name: Run eslint scanning + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + strategy: + matrix: + service: ["backend", "frontend"] + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install ESLint + run: | + npm install eslint@8.10.0 + npm install @microsoft/eslint-formatter-sarif@2.1.7 + + - name: Run ESLint + run: npx eslint apps/${{ matrix.service }}/ + --config .eslintrc.json + --format @microsoft/eslint-formatter-sarif + --output-file eslint-results.sarif + continue-on-error: true + + - name: Upload analysis results to GitHub + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: eslint-results.sarif + wait-for-processing: true From c3510897238c30e6f3a7737564884acc659fbefd Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 10:42:28 +0100 Subject: [PATCH 26/62] feat: eslint GitHub Action --- .github/workflows/eslint.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index 1e1f88f5..90fe1d67 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -3,9 +3,7 @@ name: ESLint on: push: - branches: [ "main" ] pull_request: - branches: [ "main" ] jobs: eslint: @@ -24,7 +22,7 @@ jobs: - name: Install ESLint run: | - npm install eslint@8.10.0 + npm install eslint npm install @microsoft/eslint-formatter-sarif@2.1.7 - name: Run ESLint From a656e6b567ea6474c059df94c102ba22ff58c453 Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 11:14:25 +0100 Subject: [PATCH 27/62] feat: eslint GitHub Action --- .github/workflows/eslint.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index 90fe1d67..0d344447 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -29,11 +29,11 @@ jobs: run: npx eslint apps/${{ matrix.service }}/ --config .eslintrc.json --format @microsoft/eslint-formatter-sarif - --output-file eslint-results.sarif + --output-file apps/${{ matrix.service }}/eslint-results.sarif continue-on-error: true - name: Upload analysis results to GitHub uses: github/codeql-action/upload-sarif@v3 with: - sarif_file: eslint-results.sarif + sarif_file: apps/${{ matrix.service }}/eslint-results.sarif wait-for-processing: true From 149b52f76fddbeaab22dd3b0226b4e51d22d11de Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 13:16:26 +0100 Subject: [PATCH 28/62] feat: eslint GitHub Action --- .github/workflows/eslint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index 0d344447..13523039 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -27,7 +27,7 @@ jobs: - name: Run ESLint run: npx eslint apps/${{ matrix.service }}/ - --config .eslintrc.json + --config apps/${{ matrix.service }}/.eslintrc.json --format @microsoft/eslint-formatter-sarif --output-file apps/${{ matrix.service }}/eslint-results.sarif continue-on-error: true From 1909d2f2cf28339a15ec68b4fb45c949d3341977 Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 13:20:43 +0100 Subject: [PATCH 29/62] npm cache --- .github/workflows/eslint.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index 13523039..5eefe228 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -20,6 +20,14 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: | + **/package-lock.json + - name: Install ESLint run: | npm install eslint From 461023ba349f66f3110c12f985d69fc6ee88462a Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 13:30:31 +0100 Subject: [PATCH 30/62] feat: GitHub action codeql --- .github/workflows/codeql.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..d752c763 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,36 @@ +--- +name: "Code Quality Analysis" + +on: + push: + pull_request: + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + + runs-on: 'ubuntu-latest' + permissions: + security-events: write + + strategy: + fail-fast: false + matrix: + include: + - language: javascript-typescript + build-mode: none + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" From 56347063a0abb6471014a5163d11a90879b62f03 Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Mon, 9 Sep 2024 09:10:27 -0500 Subject: [PATCH 31/62] chore: enforce node 20.17.0 due to memory leak Signed-off-by: Jonathan Irvin --- .github/workflows/build.yaml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 3ef2ed05..a90380e5 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -2,11 +2,7 @@ name: Build on: push: - branches: - - main pull_request: - branches: - - main jobs: build: @@ -14,7 +10,7 @@ jobs: strategy: matrix: - node-version: [20.x, 22.x] + node-version: ['20.17.0'] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: @@ -25,4 +21,4 @@ jobs: node-version: ${{ matrix.node-version }} cache: 'npm' - run: npm ci - - run: npm run build --if-present + - run: npm run build From 049aa3a7ab7f6d9abe454a5f65a9e4a6b2441502 Mon Sep 17 00:00:00 2001 From: SanadKhan Date: Mon, 9 Sep 2024 19:42:47 +0530 Subject: [PATCH 32/62] implemented login page responsiveness --- apps/frontend/src/app/auth/layout.tsx | 6 +++--- apps/frontend/tailwind.config.js | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/frontend/src/app/auth/layout.tsx b/apps/frontend/src/app/auth/layout.tsx index b823afca..dc005197 100644 --- a/apps/frontend/src/app/auth/layout.tsx +++ b/apps/frontend/src/app/auth/layout.tsx @@ -17,8 +17,8 @@ export default async function AuthLayout({ <>
-
-
+
+
-
+
{children}
diff --git a/apps/frontend/tailwind.config.js b/apps/frontend/tailwind.config.js index 508e9f80..32b81732 100644 --- a/apps/frontend/tailwind.config.js +++ b/apps/frontend/tailwind.config.js @@ -149,6 +149,7 @@ module.exports = { }), screens: { custom: { raw: '(max-height: 800px)' }, + xs: { max: '401px'} , }, }, }, From 979f4e04d91f2f4aec03da8ef5a1f74c2faaa3dc Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Mon, 9 Sep 2024 09:52:20 -0500 Subject: [PATCH 33/62] fix: font reload issues with next/font Signed-off-by: Jonathan Irvin --- apps/frontend/src/app/layout.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/frontend/src/app/layout.tsx b/apps/frontend/src/app/layout.tsx index 6a77d17e..3ed9e2d0 100644 --- a/apps/frontend/src/app/layout.tsx +++ b/apps/frontend/src/app/layout.tsx @@ -12,7 +12,8 @@ import { isGeneral } from '@gitroom/react/helpers/is.general'; import PlausibleProvider from 'next-plausible'; import clsx from 'clsx'; -const chakra = Chakra_Petch({ weight: '400', subsets: ['latin'] }); +// See: https://stackoverflow.com/a/76484168 +const chakra = Chakra_Petch({ weight: '400', subsets: ['latin'], display: 'swap', adjustFontFallback: false }); export default async function AppLayout({ children }: { children: ReactNode }) { return ( From f38e79d198aaaf65cc52518f3592bc256a6fdce0 Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 16:46:19 +0100 Subject: [PATCH 34/62] feat: Dockerfile - fix supervisord, cron build --- Dockerfile | 8 ++++---- var/docker/entrypoint.sh | 18 +++++++++--------- var/docker/supervisord.conf | 10 ++++++++++ .../supervisord/{backend.ini => backend.conf} | 3 +++ var/docker/supervisord/base.ini | 6 ------ var/docker/supervisord/{cron.ini => cron.conf} | 3 +++ .../{frontend.ini => frontend.conf} | 3 +++ .../supervisord/{workers.ini => workers.conf} | 3 +++ 8 files changed, 35 insertions(+), 19 deletions(-) create mode 100644 var/docker/supervisord.conf rename var/docker/supervisord/{backend.ini => backend.conf} (56%) delete mode 100644 var/docker/supervisord/base.ini rename var/docker/supervisord/{cron.ini => cron.conf} (56%) rename var/docker/supervisord/{frontend.ini => frontend.conf} (58%) rename var/docker/supervisord/{workers.ini => workers.conf} (58%) diff --git a/Dockerfile b/Dockerfile index 46619784..08d6d846 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,9 @@ EXPOSE 3000 RUN mkdir -p /config +COPY var/docker/entrypoint.sh /app/entrypoint.sh +COPY var/docker/supervisord.conf /etc/supervisord.conf +COPY var/docker/supervisord /app/supervisord_available_configs/ COPY .env.example /config/.env VOLUME /config @@ -28,10 +31,7 @@ COPY nx.json tsconfig.base.json package.json package-lock.json /app/ COPY apps /app/apps/ COPY libraries /app/libraries/ -RUN npm ci --no-fund && npm run build - -COPY var/docker/entrypoint.sh /app/entrypoint.sh -COPY var/docker/supervisord/* /app/supervisord_configs/ +RUN npm ci --no-fund && npx nx run-many --target=build --projects=frontend,backend,workers,cron LABEL org.opencontainers.image.title="Postiz App (DevContainer)" diff --git a/var/docker/entrypoint.sh b/var/docker/entrypoint.sh index 609fa7d0..2e98950e 100755 --- a/var/docker/entrypoint.sh +++ b/var/docker/entrypoint.sh @@ -1,36 +1,36 @@ #!/bin/bash -if [[ "$SKIP_CONFIG_CHECK" -ne "true" ]]; then +if [[ "$SKIP_CONFIG_CHECK" != "true" ]]; then + echo "symlinking /config/.env into /app/.env" + if [ ! -f /config/.env ]; then echo "ERROR: No .env file found in /config/.env" fi - ln -s /config/env /app/.env + ln -sf /config/.env /app/.env fi if [[ "$POSTIZ_APPS" -eq "" ]]; then echo "POSTIZ_APPS is not set, starting everything!" - POSTIZ_APPS="frontend workers cron" + POSTIZ_APPS="frontend workers cron backend" fi mkdir -p /etc/supervisor.d/ -cp /app/supervisord_configs/base.conf /etc/supervisor.d/ - if [[ "$POSTIZ_APPS" == *"frontend"* ]]; then - cp /app/supervisord_configs/frontend.conf /etc/supervisor.d/ + ln -sf /app/supervisord_available_configs/frontend.conf /etc/supervisor.d/ fi if [[ $POSTIZ_APPS == *"workers"* ]]; then - cp /app/supervisord_configs/workers.conf /etc/supervisor.d/ + ln -sf /app/supervisord_available_configs/workers.conf /etc/supervisor.d/ fi if [[ $POSTIZ_APPS == *"cron"* ]]; then - cp /app/supervisord_configs/cron.conf /etc/supervisor.d/ + ln -sf /app/supervisord_available_configs/cron.conf /etc/supervisor.d/ fi if [[ $POSTIZ_APPS == *"backend"* ]]; then - cp /app/supervisord_configs/backend.conf /etc/supervisor.d/ + ln -sf /app/supervisord_available_configs/backend.conf /etc/supervisor.d/ fi /usr/bin/supervisord diff --git a/var/docker/supervisord.conf b/var/docker/supervisord.conf new file mode 100644 index 00000000..c74f511b --- /dev/null +++ b/var/docker/supervisord.conf @@ -0,0 +1,10 @@ +[supervisord] +nodaemon=true +logfile=/dev/null +logfile_maxbytes=0 + +[unix_http_server] +file=/run/supervisord.sock + +[include] +files = /etc/supervisor.d/*.conf diff --git a/var/docker/supervisord/backend.ini b/var/docker/supervisord/backend.conf similarity index 56% rename from var/docker/supervisord/backend.ini rename to var/docker/supervisord/backend.conf index 8e56645c..be803a93 100644 --- a/var/docker/supervisord/backend.ini +++ b/var/docker/supervisord/backend.conf @@ -3,3 +3,6 @@ directory=/app command=npm run start:prod autostart=true autorestart=false +redirect_stderr=true +stdout_logfile=/dev/fd/1 +stdout_logfile_maxbytes=0 diff --git a/var/docker/supervisord/base.ini b/var/docker/supervisord/base.ini deleted file mode 100644 index b220a983..00000000 --- a/var/docker/supervisord/base.ini +++ /dev/null @@ -1,6 +0,0 @@ -[supervisord] -nodaemon=true -logfile=/dev/null -logfile_maxbytes=0 - - diff --git a/var/docker/supervisord/cron.ini b/var/docker/supervisord/cron.conf similarity index 56% rename from var/docker/supervisord/cron.ini rename to var/docker/supervisord/cron.conf index ef22047a..ab653f5a 100644 --- a/var/docker/supervisord/cron.ini +++ b/var/docker/supervisord/cron.conf @@ -3,3 +3,6 @@ directory=/app command=npm run start:prod:cron autostart=true autorestart=false +redirect_stderr=true +stdout_logfile=/dev/fd/1 +stdout_logfile_maxbytes=0 diff --git a/var/docker/supervisord/frontend.ini b/var/docker/supervisord/frontend.conf similarity index 58% rename from var/docker/supervisord/frontend.ini rename to var/docker/supervisord/frontend.conf index 737aedd9..c157a205 100644 --- a/var/docker/supervisord/frontend.ini +++ b/var/docker/supervisord/frontend.conf @@ -3,3 +3,6 @@ directory=/app command=npm run start:prod:frontend autostart=true autorestart=false +redirect_stderr=true +stdout_logfile=/dev/fd/1 +stdout_logfile_maxbytes=0 diff --git a/var/docker/supervisord/workers.ini b/var/docker/supervisord/workers.conf similarity index 58% rename from var/docker/supervisord/workers.ini rename to var/docker/supervisord/workers.conf index fd84a708..5653ec8b 100644 --- a/var/docker/supervisord/workers.ini +++ b/var/docker/supervisord/workers.conf @@ -3,3 +3,6 @@ directory=/app command=npm run start:prod:workers autostart=true autorestart=false +redirect_stderr=true +stdout_logfile=/dev/fd/1 +stdout_logfile_maxbytes=0 From 5f8e1380360706ecc2cae3f4b51fd0a9014e4d4b Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Mon, 9 Sep 2024 10:57:51 -0500 Subject: [PATCH 35/62] fix: load chakra-petch from fontsource instead of nextjs --- apps/frontend/src/app/layout.tsx | 9 ++------- package-lock.json | 7 +++++++ package.json | 1 + 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/frontend/src/app/layout.tsx b/apps/frontend/src/app/layout.tsx index 3ed9e2d0..7b4912c4 100644 --- a/apps/frontend/src/app/layout.tsx +++ b/apps/frontend/src/app/layout.tsx @@ -1,19 +1,14 @@ import interClass from '@gitroom/react/helpers/inter.font'; - export const dynamic = 'force-dynamic'; import './global.scss'; import 'react-tooltip/dist/react-tooltip.css'; import '@copilotkit/react-ui/styles.css'; - import LayoutContext from '@gitroom/frontend/components/layout/layout.context'; import { ReactNode } from 'react'; -import { Chakra_Petch } from 'next/font/google'; import { isGeneral } from '@gitroom/react/helpers/is.general'; import PlausibleProvider from 'next-plausible'; import clsx from 'clsx'; - -// See: https://stackoverflow.com/a/76484168 -const chakra = Chakra_Petch({ weight: '400', subsets: ['latin'], display: 'swap', adjustFontFallback: false }); +import "@fontsource/chakra-petch"; export default async function AppLayout({ children }: { children: ReactNode }) { return ( @@ -25,7 +20,7 @@ export default async function AppLayout({ children }: { children: ReactNode }) { sizes="any" /> - + {children} diff --git a/package-lock.json b/package-lock.json index 37a0b0c6..398ea7b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "@copilotkit/react-textarea": "1.1.0", "@copilotkit/react-ui": "1.1.0", "@copilotkit/runtime": "1.1.0", + "@fontsource/chakra-petch": "^5.0.22", "@hookform/resolvers": "^3.3.4", "@mantine/core": "^5.10.5", "@mantine/dates": "^5.10.5", @@ -6242,6 +6243,12 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.4.tgz", "integrity": "sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==" }, + "node_modules/@fontsource/chakra-petch": { + "version": "5.0.22", + "resolved": "https://registry.npmjs.org/@fontsource/chakra-petch/-/chakra-petch-5.0.22.tgz", + "integrity": "sha512-dYhrz0As8T7H7NGeMbcwAf84xzlxzdfcXBqcgO5lWAGezud8zrrJKGHB/9To5fNQ1ZoqDVplXy3Hu+Ye7tFbvw==", + "license": "OFL-1.1" + }, "node_modules/@google/generative-ai": { "version": "0.11.5", "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.11.5.tgz", diff --git a/package.json b/package.json index 9a5c2dc6..5f92d796 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "@copilotkit/react-textarea": "1.1.0", "@copilotkit/react-ui": "1.1.0", "@copilotkit/runtime": "1.1.0", + "@fontsource/chakra-petch": "^5.0.22", "@hookform/resolvers": "^3.3.4", "@mantine/core": "^5.10.5", "@mantine/dates": "^5.10.5", From 5a854aa45147c47bb3ff33c36ed40b253fafdbca Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 17:20:25 +0100 Subject: [PATCH 36/62] Add container workflow --- .github/workflows/build-containers.yml | 42 ++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/build-containers.yml diff --git a/.github/workflows/build-containers.yml b/.github/workflows/build-containers.yml new file mode 100644 index 00000000..e8240303 --- /dev/null +++ b/.github/workflows/build-containers.yml @@ -0,0 +1,42 @@ +--- +name: "Build Tag" + +on: + push: + tags: + - '*' + +jobs: + build-tag: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: | + **/package-lock.json + + - name: Login to ghcr + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.CONTAINER_TOKEN }} + + - name: docker build + run: npm run docker-build + + - name: docker tag + run: | + docker tag localhost/postiz ghcr.io/githubhq/postiz-app:${{ GITHUB_REF_NAME }} + docker push ghcr.io/githubhq/postiz-app:${{ GITHUB_REF_NAME }} + + docker tag localhost/postiz-devcontainer ghcr.io/githubhq/postiz-app:${{ GITHUB_REF_NAME }} + docker push ghcr.io/githubhq/postiz-devcontainer:${{ GITHUB_REF_NAME }} From 81fd96f6d7f660024ad6f9a0ac14f2c7422f51ef Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 17:26:20 +0100 Subject: [PATCH 37/62] doc: Remove more junk from build context Co-Authored-By: jonathan-irvin --- .dockerignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.dockerignore b/.dockerignore index 6b6f71ee..a04f7947 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,3 +4,6 @@ node_modules dist .nx +.devcontainer +.git +*.md From c466f08c80e24d18df5a58ebd0b5409871dd7567 Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 17:35:39 +0100 Subject: [PATCH 38/62] ci: Remove /config as it's created anyway Co-Authored-By: jonathan-irvin --- Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 08d6d846..b5775218 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,8 +13,6 @@ WORKDIR /app EXPOSE 4200 EXPOSE 3000 -RUN mkdir -p /config - COPY var/docker/entrypoint.sh /app/entrypoint.sh COPY var/docker/supervisord.conf /etc/supervisord.conf COPY var/docker/supervisord /app/supervisord_available_configs/ From 9c9698c59869edeb3df8ebfe949dff810ec4df7f Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 17:40:19 +0100 Subject: [PATCH 39/62] ci: Consolidate entrypoint into the base image Co-Authored-By: jonathan-irvin --- Dockerfile | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index b5775218..34b19b4e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,7 @@ # Base image FROM docker.io/node:20.17-alpine3.19 AS base +## Just reduce unccessary noise in the logs. ENV NPM_CONFIG_UPDATE_NOTIFIER=false ENV NEXT_TELEMETRY_DISABLED=1 @@ -22,6 +23,8 @@ VOLUME /config LABEL org.opencontainers.image.source=https://github.com/gitroomhq/postiz-app +ENTRYPOINT ["/app/entrypoint.sh"] + # Builder image FROM base AS devcontainer @@ -33,8 +36,6 @@ RUN npm ci --no-fund && npx nx run-many --target=build --projects=frontend,backe LABEL org.opencontainers.image.title="Postiz App (DevContainer)" -ENTRYPOINT ["/app/entrypoint.sh"] - # Output image FROM base AS dist @@ -42,9 +43,6 @@ COPY --from=devcontainer /app/node_modules/ /app/node_modules/ COPY --from=devcontainer /app/dist/ /app/dist/ COPY package.json nx.json /app/ -COPY var/docker/entrypoint.sh /app/entrypoint.sh -## Labels at the bottom, because CI will eventially add dates, commit hashes, etc. +## Labels at the bottom, because CI will eventually add dates, commit hashes, etc. LABEL org.opencontainers.image.title="Postiz App (Production)" - -ENTRYPOINT ["/app/entrypoint.sh"] From 33a304f7b70d0e220d0cd59b0713b19ab4a7473c Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 17:53:52 +0100 Subject: [PATCH 40/62] ci: Add cache key to build job --- .github/workflows/build.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a90380e5..4dd75430 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -20,5 +20,8 @@ jobs: with: node-version: ${{ matrix.node-version }} cache: 'npm' + cache-dependency-path: | + **/package-lock.json + - run: npm ci - run: npm run build From afbeda159b9338d1e5412a03dc5d0779d49403c4 Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 18:08:30 +0100 Subject: [PATCH 41/62] ci: Switch to GITHUB_TOKEN --- .github/workflows/build-containers.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-containers.yml b/.github/workflows/build-containers.yml index e8240303..39439e5e 100644 --- a/.github/workflows/build-containers.yml +++ b/.github/workflows/build-containers.yml @@ -28,7 +28,7 @@ jobs: with: registry: ghcr.io username: ${{ github.actor }} - password: ${{ secrets.CONTAINER_TOKEN }} + password: ${{ github.token }} - name: docker build run: npm run docker-build From c674f699c9f0bbd44ac5e8a7361bb63a616eb6bd Mon Sep 17 00:00:00 2001 From: Nevo David Date: Tue, 10 Sep 2024 00:09:46 +0700 Subject: [PATCH 42/62] feat: cron --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9a5c2dc6..e281ef17 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "scripts": { "dev": "npx nx run-many --target=serve --projects=frontend,backend,workers --parallel=4", "dev:stripe": "npx concurrently \"stripe listen --forward-to localhost:3000/stripe\" \"npm run dev\"", - "build": "npx nx run-many --target=build --projects=frontend,backend,workers", + "build": "npx nx run-many --target=build --projects=frontend,backend,workers,cron", "start:prod": "node dist/apps/backend/main.js", "start:prod:frontend": "nx run frontend:serve:production", "start:prod:workers": "node dist/apps/workers/main.js", From 08adb43d63a2278cc66700339d9d39d74b07590b Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 20:12:08 +0100 Subject: [PATCH 43/62] ci: Use 20.17 for builds --- .github/workflows/build-containers.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-containers.yml b/.github/workflows/build-containers.yml index 39439e5e..b6ec927b 100644 --- a/.github/workflows/build-containers.yml +++ b/.github/workflows/build-containers.yml @@ -18,7 +18,7 @@ jobs: - name: Setup node uses: actions/setup-node@v4 with: - node-version: '20' + node-version: '20.17' cache: 'npm' cache-dependency-path: | **/package-lock.json From 56d04d962e560de0b629cc75dc362b228d923ea6 Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 20:22:58 +0100 Subject: [PATCH 44/62] Add NEXT JS Build cache --- .github/workflows/build.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a90380e5..9c421bbf 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,3 +1,4 @@ +--- name: Build on: @@ -20,5 +21,18 @@ jobs: with: node-version: ${{ matrix.node-version }} cache: 'npm' + + # https://nextjs.org/docs/pages/building-your-application/deploying/ci-build-caching#github-actions + - uses: actions/cache@v4 + with: + path: | + ~/.npm + ${{ github.workspace }}/.next/cache + + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} + restore-keys: | + ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- + + - run: npm ci - run: npm run build From 9e58dd06243dd0c3c92ab2f40111d62a9944bbbd Mon Sep 17 00:00:00 2001 From: Jonathan Irvin Date: Mon, 9 Sep 2024 14:34:56 -0500 Subject: [PATCH 45/62] fix: update dockerfile with additional build to support different arch --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 34b19b4e..45498003 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,9 @@ ENV NEXT_TELEMETRY_DISABLED=1 RUN apk add --no-cache \ bash=5.2.21-r0 \ - supervisor=4.2.5-r4 + supervisor=4.2.5-r4 \ + make \ + build-base WORKDIR /app From 79ed89060eb7cd819ca527be03799627fc15d71c Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 20:46:17 +0100 Subject: [PATCH 46/62] ci: Move docker build instructions into separate scripts --- .github/workflows/build-containers.yml | 10 +--------- package.json | 4 ++-- var/docker/docker-build.sh | 5 +++++ var/docker/docker-create.sh | 5 +++++ 4 files changed, 13 insertions(+), 11 deletions(-) create mode 100755 var/docker/docker-build.sh create mode 100644 var/docker/docker-create.sh diff --git a/.github/workflows/build-containers.yml b/.github/workflows/build-containers.yml index b6ec927b..4d089a88 100644 --- a/.github/workflows/build-containers.yml +++ b/.github/workflows/build-containers.yml @@ -15,14 +15,6 @@ jobs: with: fetch-depth: 0 - - name: Setup node - uses: actions/setup-node@v4 - with: - node-version: '20.17' - cache: 'npm' - cache-dependency-path: | - **/package-lock.json - - name: Login to ghcr uses: docker/login-action@v3 with: @@ -31,7 +23,7 @@ jobs: password: ${{ github.token }} - name: docker build - run: npm run docker-build + run: /var/run/docker-build.sh - name: docker tag run: | diff --git a/package.json b/package.json index efd4a817..bda70c5e 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,8 @@ "prisma-generate": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma generate", "prisma-db-push": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma db push", "prisma-reset": "cd ./libraries/nestjs-libraries/src/database/prisma && npx prisma db push --force-reset && npx prisma db push", - "docker-build": "docker rmi localhost/postiz || true && docker build --target dist -t localhost/postiz -f Dockerfile . && docker build --target devcontainer -t localhost/postiz-devcontainer -f Dockerfile .", - "docker-create": "docker kill postiz || true && docker rm postiz || true && docker create --name postiz -p 3000:3000 -p 4200:4200 localhost/postiz", + "docker-build": "./var/docker/docker-build.sh", + "docker-create": "./var/docker/docker-create.sh", "postinstall": "npm run prisma-generate" }, "private": true, diff --git a/var/docker/docker-build.sh b/var/docker/docker-build.sh new file mode 100755 index 00000000..bdbc83d8 --- /dev/null +++ b/var/docker/docker-build.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +docker rmi localhost/postiz || true +docker build --target dist -t localhost/postiz -f Dockerfile . +docker build --target devcontainer -t localhost/postiz-devcontainer -f Dockerfile . diff --git a/var/docker/docker-create.sh b/var/docker/docker-create.sh new file mode 100644 index 00000000..9b8fda99 --- /dev/null +++ b/var/docker/docker-create.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +docker kill postiz || true +docker rm postiz || true +docker create --name postiz -p 3000:3000 -p 4200:4200 localhost/postiz From 7216f2135d757046d7cec5373e25294b00389bc0 Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 20:57:49 +0100 Subject: [PATCH 47/62] ci: Dockerfile, add NODE_VERSION param --- Dockerfile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 45498003..d5c0016d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,13 @@ +# This Dockerfile is used for producing 3 container images. +# +# base - which is thrown away, that contains node and the basic infrastructure. +# devcontainer - which is used for development, and contains the source code and the node_modules. +# dist - which is used for production, and contains the built source code and the node_modules. + +ARG NODE_VERSION="20.17" + # Base image -FROM docker.io/node:20.17-alpine3.19 AS base +FROM docker.io/node:${NODE_VERSION}-alpine3.19 AS base ## Just reduce unccessary noise in the logs. ENV NPM_CONFIG_UPDATE_NOTIFIER=false From e5387dd52c5d20ddae9243ca27e01c6fdf8d644d Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 22:13:05 +0100 Subject: [PATCH 48/62] ci: Allow building containers as a manually started job --- .github/workflows/build-containers.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-containers.yml b/.github/workflows/build-containers.yml index 4d089a88..f1d0182a 100644 --- a/.github/workflows/build-containers.yml +++ b/.github/workflows/build-containers.yml @@ -2,6 +2,7 @@ name: "Build Tag" on: + workflow_dispatch: push: tags: - '*' From 01afa4336378f1a4df65cdaf7d6953f6c0058274 Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 22:19:22 +0100 Subject: [PATCH 49/62] ci: Run actions only on certain path changes --- .github/workflows/build.yaml | 11 +++++++++++ .github/workflows/codeql.yml | 9 +++++++++ .github/workflows/eslint.yaml | 11 +++++++++++ 3 files changed, 31 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 9280e5c4..5f1de21f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -3,7 +3,18 @@ name: Build on: push: + branches: + - main + paths: + - package.json + - apps/* + - libraries/* + pull_request: + paths: + - package.json + - apps/* + - libraries/* jobs: build: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index d752c763..c2ba24dd 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -3,7 +3,16 @@ name: "Code Quality Analysis" on: push: + branches: + - main + paths: + - apps/* + - libraries/* + pull_request: + paths: + - apps/* + - libraries/* jobs: analyze: diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index 5eefe228..b67331fc 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -3,7 +3,18 @@ name: ESLint on: push: + branches: + - main + paths: + - package.json + - apps/* + - libraries/* + pull_request: + paths: + - package.json + - apps/* + - libraries/* jobs: eslint: From 55006cb7a568c613c2c6eabe6a598bdf9b8f82b4 Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 22:20:12 +0100 Subject: [PATCH 50/62] ci: Run actions only on certain path changes --- .github/workflows/build.yaml | 8 ++++---- .github/workflows/codeql.yml | 8 ++++---- .github/workflows/eslint.yaml | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 5f1de21f..a1163412 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -7,14 +7,14 @@ on: - main paths: - package.json - - apps/* - - libraries/* + - apps/** + - libraries/** pull_request: paths: - package.json - - apps/* - - libraries/* + - apps/** + - libraries/** jobs: build: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c2ba24dd..e8648af2 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -6,13 +6,13 @@ on: branches: - main paths: - - apps/* - - libraries/* + - apps/** + - libraries/** pull_request: paths: - - apps/* - - libraries/* + - apps/** + - libraries/** jobs: analyze: diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index b67331fc..7e64f645 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -7,14 +7,14 @@ on: - main paths: - package.json - - apps/* - - libraries/* + - apps/** + - libraries/** pull_request: paths: - package.json - - apps/* - - libraries/* + - apps/** + - libraries/** jobs: eslint: From 27aaf6e584514589d58a5690f8db96d882f918ff Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 22:30:25 +0100 Subject: [PATCH 51/62] ci: Add timestamp to container as primitive version --- .github/workflows/build-containers.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-containers.yml b/.github/workflows/build-containers.yml index 4d089a88..119bda5e 100644 --- a/.github/workflows/build-containers.yml +++ b/.github/workflows/build-containers.yml @@ -1,5 +1,5 @@ --- -name: "Build Tag" +name: "Build Containers" on: push: @@ -25,10 +25,14 @@ jobs: - name: docker build run: /var/run/docker-build.sh + - name: Get date + run: | + echo "DATE=$(date +'%s')" >> "$GITHUB_ENV" + - name: docker tag run: | - docker tag localhost/postiz ghcr.io/githubhq/postiz-app:${{ GITHUB_REF_NAME }} - docker push ghcr.io/githubhq/postiz-app:${{ GITHUB_REF_NAME }} + docker tag localhost/postiz ghcr.io/githubhq/postiz-app:${{ env.DATE }} + docker push ghcr.io/githubhq/postiz-app:${{ env.DATE }} - docker tag localhost/postiz-devcontainer ghcr.io/githubhq/postiz-app:${{ GITHUB_REF_NAME }} - docker push ghcr.io/githubhq/postiz-devcontainer:${{ GITHUB_REF_NAME }} + docker tag localhost/postiz-devcontainer ghcr.io/githubhq/postiz-app:${{ env.DATE }} + docker push ghcr.io/githubhq/postiz-devcontainer:${{ env.DATE }} From 58c6fd5908e37f37b2b2bade17c46fe0cd4a851e Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 22:33:51 +0100 Subject: [PATCH 52/62] ci: Correct buildscript in container --- .github/workflows/build-containers.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-containers.yml b/.github/workflows/build-containers.yml index 4d089a88..af267362 100644 --- a/.github/workflows/build-containers.yml +++ b/.github/workflows/build-containers.yml @@ -23,7 +23,7 @@ jobs: password: ${{ github.token }} - name: docker build - run: /var/run/docker-build.sh + run: ./var/run/docker-build.sh - name: docker tag run: | From f6daecacd44e2fa55f03e56b87380e40ae48ac8d Mon Sep 17 00:00:00 2001 From: jamesread Date: Mon, 9 Sep 2024 22:38:21 +0100 Subject: [PATCH 53/62] ci: Correct path to buildscript --- .github/workflows/build-containers.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-containers.yml b/.github/workflows/build-containers.yml index cb2e3609..0950c770 100644 --- a/.github/workflows/build-containers.yml +++ b/.github/workflows/build-containers.yml @@ -24,7 +24,7 @@ jobs: password: ${{ github.token }} - name: docker build - run: ./var/run/docker-build.sh + run: ./var/docker/docker-build.sh - name: Get date run: | From 7a8631124b4974c9eaed4b5d6c06f1487b248cb0 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Tue, 10 Sep 2024 12:02:02 +0700 Subject: [PATCH 54/62] feat: dockerdev --- Dockerfile => Dockerfile.dev | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Dockerfile => Dockerfile.dev (100%) diff --git a/Dockerfile b/Dockerfile.dev similarity index 100% rename from Dockerfile rename to Dockerfile.dev From 3b72e01377c27c625ad393ad9db42893f67864db Mon Sep 17 00:00:00 2001 From: jamesread Date: Tue, 10 Sep 2024 09:28:13 +0100 Subject: [PATCH 55/62] bugfix: Docker filename and supervisorctl fix --- var/docker/docker-build.sh | 4 ++-- var/docker/supervisord.conf | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/var/docker/docker-build.sh b/var/docker/docker-build.sh index bdbc83d8..48ff1e2e 100755 --- a/var/docker/docker-build.sh +++ b/var/docker/docker-build.sh @@ -1,5 +1,5 @@ #!/bin/bash docker rmi localhost/postiz || true -docker build --target dist -t localhost/postiz -f Dockerfile . -docker build --target devcontainer -t localhost/postiz-devcontainer -f Dockerfile . +docker build --target dist -t localhost/postiz -f Dockerfile.dev . +docker build --target devcontainer -t localhost/postiz-devcontainer -f Dockerfile.dev . diff --git a/var/docker/supervisord.conf b/var/docker/supervisord.conf index c74f511b..a957fc23 100644 --- a/var/docker/supervisord.conf +++ b/var/docker/supervisord.conf @@ -8,3 +8,9 @@ file=/run/supervisord.sock [include] files = /etc/supervisor.d/*.conf + +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface + +[supervisorctl] +serverurl=unix:///run/supervisord.sock From 7bee234a2824253c88e929a62ebfb1735bc6d863 Mon Sep 17 00:00:00 2001 From: jamesread Date: Tue, 10 Sep 2024 09:28:38 +0100 Subject: [PATCH 56/62] bugfix: Docker filename and supervisorctl fix --- var/docker/docker-create.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 var/docker/docker-create.sh diff --git a/var/docker/docker-create.sh b/var/docker/docker-create.sh old mode 100644 new mode 100755 From c52f486940ff1e24c9053d0307e999513673bba9 Mon Sep 17 00:00:00 2001 From: jamesread Date: Tue, 10 Sep 2024 10:10:52 +0100 Subject: [PATCH 57/62] bugfix: github typo in docker workflow --- .github/workflows/build-containers.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-containers.yml b/.github/workflows/build-containers.yml index 0950c770..8c2087a0 100644 --- a/.github/workflows/build-containers.yml +++ b/.github/workflows/build-containers.yml @@ -32,8 +32,8 @@ jobs: - name: docker tag run: | - docker tag localhost/postiz ghcr.io/githubhq/postiz-app:${{ env.DATE }} - docker push ghcr.io/githubhq/postiz-app:${{ env.DATE }} + docker tag localhost/postiz ghcr.io/gitroomhq/postiz-app:${{ env.DATE }} + docker push ghcr.io/gitroomhq/postiz-app:${{ env.DATE }} - docker tag localhost/postiz-devcontainer ghcr.io/githubhq/postiz-app:${{ env.DATE }} - docker push ghcr.io/githubhq/postiz-devcontainer:${{ env.DATE }} + docker tag localhost/postiz-devcontainer ghcr.io/gitroomhq/postiz-app:${{ env.DATE }} + docker push ghcr.io/gitroomhq/postiz-devcontainer:${{ env.DATE }} From f2a2179fad0399aa8334c35d384ebd555915db26 Mon Sep 17 00:00:00 2001 From: jamesread Date: Tue, 10 Sep 2024 13:54:47 +0100 Subject: [PATCH 58/62] ci: Container for dev had wrong name, and a few other fixes --- .dockerignore | 10 +++++++--- .github/workflows/build-containers.yml | 8 ++++++-- .gitignore | 4 ++++ Dockerfile.dev | 2 +- var/docker/docker-build.sh | 2 ++ 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/.dockerignore b/.dockerignore index a04f7947..7acfe507 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,9 +1,13 @@ # We want the docker builds to be clean, and as fast as possible. Don't send # any half-built stuff in the build context as a pre-caution (also saves copying # 180k files in node_modules that isn't used!). -node_modules +**/node_modules dist .nx .devcontainer -.git -*.md +**/.git +**/dist +**/*.md +**/LICENSE +**/npm-debug.log +**/*.vscode diff --git a/.github/workflows/build-containers.yml b/.github/workflows/build-containers.yml index 8c2087a0..2e7b116a 100644 --- a/.github/workflows/build-containers.yml +++ b/.github/workflows/build-containers.yml @@ -8,7 +8,7 @@ on: - '*' jobs: - build-tag: + build-containers: runs-on: ubuntu-latest steps: - name: Checkout @@ -30,10 +30,14 @@ jobs: run: | echo "DATE=$(date +'%s')" >> "$GITHUB_ENV" + - name: Print post-build debug info + run: | + docker images + - name: docker tag run: | docker tag localhost/postiz ghcr.io/gitroomhq/postiz-app:${{ env.DATE }} docker push ghcr.io/gitroomhq/postiz-app:${{ env.DATE }} - docker tag localhost/postiz-devcontainer ghcr.io/gitroomhq/postiz-app:${{ env.DATE }} + docker tag localhost/postiz-devcontainer ghcr.io/gitroomhq/postiz-devcontainer:${{ env.DATE }} docker push ghcr.io/gitroomhq/postiz-devcontainer:${{ env.DATE }} diff --git a/.gitignore b/.gitignore index 02ae82bc..a45f48df 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,7 @@ Thumbs.db # Next.js .next + +# Vim files +**/*.swp +**/*.swo diff --git a/Dockerfile.dev b/Dockerfile.dev index d5c0016d..deb667e4 100644 --- a/Dockerfile.dev +++ b/Dockerfile.dev @@ -1,4 +1,4 @@ -# This Dockerfile is used for producing 3 container images. +# This Dockerfile is used for producing 3 container images. # # base - which is thrown away, that contains node and the basic infrastructure. # devcontainer - which is used for development, and contains the source code and the node_modules. diff --git a/var/docker/docker-build.sh b/var/docker/docker-build.sh index 48ff1e2e..5393edec 100755 --- a/var/docker/docker-build.sh +++ b/var/docker/docker-build.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -o xtrace + docker rmi localhost/postiz || true docker build --target dist -t localhost/postiz -f Dockerfile.dev . docker build --target devcontainer -t localhost/postiz-devcontainer -f Dockerfile.dev . From 72e8ef868ff2245294c4a3938127d31bcd3e1f16 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Wed, 11 Sep 2024 00:17:30 +0700 Subject: [PATCH 59/62] feat: font change --- apps/frontend/src/app/layout.tsx | 7 +++++-- package-lock.json | 7 ------- package.json | 1 - 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/apps/frontend/src/app/layout.tsx b/apps/frontend/src/app/layout.tsx index 7b4912c4..5a0ad298 100644 --- a/apps/frontend/src/app/layout.tsx +++ b/apps/frontend/src/app/layout.tsx @@ -3,12 +3,15 @@ export const dynamic = 'force-dynamic'; import './global.scss'; import 'react-tooltip/dist/react-tooltip.css'; import '@copilotkit/react-ui/styles.css'; + import LayoutContext from '@gitroom/frontend/components/layout/layout.context'; import { ReactNode } from 'react'; +import { Chakra_Petch } from 'next/font/google'; import { isGeneral } from '@gitroom/react/helpers/is.general'; import PlausibleProvider from 'next-plausible'; import clsx from 'clsx'; -import "@fontsource/chakra-petch"; + +const chakra = Chakra_Petch({ weight: '400', subsets: ['latin'] }); export default async function AppLayout({ children }: { children: ReactNode }) { return ( @@ -20,7 +23,7 @@ export default async function AppLayout({ children }: { children: ReactNode }) { sizes="any" /> - + {children} diff --git a/package-lock.json b/package-lock.json index 398ea7b8..37a0b0c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,6 @@ "@copilotkit/react-textarea": "1.1.0", "@copilotkit/react-ui": "1.1.0", "@copilotkit/runtime": "1.1.0", - "@fontsource/chakra-petch": "^5.0.22", "@hookform/resolvers": "^3.3.4", "@mantine/core": "^5.10.5", "@mantine/dates": "^5.10.5", @@ -6243,12 +6242,6 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.4.tgz", "integrity": "sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==" }, - "node_modules/@fontsource/chakra-petch": { - "version": "5.0.22", - "resolved": "https://registry.npmjs.org/@fontsource/chakra-petch/-/chakra-petch-5.0.22.tgz", - "integrity": "sha512-dYhrz0As8T7H7NGeMbcwAf84xzlxzdfcXBqcgO5lWAGezud8zrrJKGHB/9To5fNQ1ZoqDVplXy3Hu+Ye7tFbvw==", - "license": "OFL-1.1" - }, "node_modules/@google/generative-ai": { "version": "0.11.5", "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.11.5.tgz", diff --git a/package.json b/package.json index 2a9ba71b..4318b733 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,6 @@ "@copilotkit/react-textarea": "1.1.0", "@copilotkit/react-ui": "1.1.0", "@copilotkit/runtime": "1.1.0", - "@fontsource/chakra-petch": "^5.0.22", "@hookform/resolvers": "^3.3.4", "@mantine/core": "^5.10.5", "@mantine/dates": "^5.10.5", From 42e4468ef1d755d11b3eefef3e10e551b338345f Mon Sep 17 00:00:00 2001 From: jamesread Date: Tue, 10 Sep 2024 19:40:29 +0100 Subject: [PATCH 60/62] doc: Docker, and various doc cleanup --- .../how-to-add-provider.mdx | 2 +- apps/docs/installation/development.mdx | 144 ++++++++++++++++++ apps/docs/installation/docker-compose.mdx | 69 +++++++++ apps/docs/installation/docker.mdx | 20 +++ apps/docs/installation/kubernetes-helm.mdx | 13 ++ apps/docs/mint.json | 19 ++- apps/docs/quickstart.mdx | 114 +------------- apps/docs/snippets/docker-database.mdx | 6 + apps/docs/snippets/docker-envvar-apps.mdx | 7 + apps/docs/snippets/earlydoc.mdx | 6 + apps/docs/snippets/snippet-example.mdx | 3 + apps/docs/support.mdx | 35 +++++ 12 files changed, 327 insertions(+), 111 deletions(-) rename apps/docs/{providers => developer-guide}/how-to-add-provider.mdx (99%) create mode 100644 apps/docs/installation/development.mdx create mode 100644 apps/docs/installation/docker-compose.mdx create mode 100644 apps/docs/installation/docker.mdx create mode 100644 apps/docs/installation/kubernetes-helm.mdx create mode 100644 apps/docs/snippets/docker-database.mdx create mode 100644 apps/docs/snippets/docker-envvar-apps.mdx create mode 100644 apps/docs/snippets/earlydoc.mdx create mode 100644 apps/docs/snippets/snippet-example.mdx create mode 100644 apps/docs/support.mdx diff --git a/apps/docs/providers/how-to-add-provider.mdx b/apps/docs/developer-guide/how-to-add-provider.mdx similarity index 99% rename from apps/docs/providers/how-to-add-provider.mdx rename to apps/docs/developer-guide/how-to-add-provider.mdx index 87ba7fde..a813633e 100644 --- a/apps/docs/providers/how-to-add-provider.mdx +++ b/apps/docs/developer-guide/how-to-add-provider.mdx @@ -169,4 +169,4 @@ You can look at the other integration to understand what data to put inside. And add the new provider to the list. ```typescript show.all.providers.tsx {identifier: 'providerName', component: DefaultImportFromHighOrderProvider}, -``` \ No newline at end of file +``` diff --git a/apps/docs/installation/development.mdx b/apps/docs/installation/development.mdx new file mode 100644 index 00000000..c6e5f932 --- /dev/null +++ b/apps/docs/installation/development.mdx @@ -0,0 +1,144 @@ +--- +title: Development Environment +--- + +This is currently the recommended option to install Postiz in a supportable configuration. The docker images are in active and heavy development for now. + +## Tested configurations + +- MacOS +- Linux (Fedora 40) + +Naturally you can use these instructions to setup a development environment on any platform, but there may not be much experience in the community to help you with any issues you may encounter. + +## Prerequisites + +This guide will ask you to install & configure several services exaplained below. + +### Prerequisite Cloud Services + +- **[Resend account](https://resend.com)** - for user activation and email notifications. +- **[Cloudflare R2](https://cloudfalre.com)** - for uploads (optional, can use local machine), and storing account data. +- **Social Media API details** - various API keys and secrets (more details later) for services you want to use; reddit, X, Instagram, etc.. + +### Prerequisite Local Services + +- **Node.js** - for running the code! (version 18+) +- **PostgreSQL** - or any other SQL database (instructions beleow suggest Docker) +- **Redis** - for handling worker queues (instructions below suggest Docker) + +We have some messages from users who are using Windows, which should work, but they are not tested well yet. + +## Installation Instructions + +### NodeJS (version 18+) + +A complete guide of how to install NodeJS can be found [here](https://nodejs.org/en/download/). + +### PostgreSQL (or any other SQL database) & Redis + +You can choose **Option A** to **Option B** to install the database. + +#### Option A) Postgres and Redis as Single containers + +You can install [Docker](https://www.docker.com/products/docker-desktop) and run: + +```bash Terminal +docker run -e POSTGRES_USER=root -e POSTGRES_PASSWORD=your_password --name postgres -p 5432:5432 -d postgres +docker run --name redis -p 6379:6379 -d redis +``` + +#### Option B) Postgres and Redis as docker-compose + +Download the [docker-compose.yaml file here](https://raw.githubusercontent.com/gitroomhq/postiz-app/main/docker-compose.dev.yaml), +or grab it from the repository in the next step. + +```bash Terminal +docker compose -f "docker-compose.dev.yaml" up +``` + +## Build Postiz + + + +```bash Terminal +git clone https://github.com/gitroomhq/gitroom +``` + + + +Copy the `.env.example` file to `.env` and fill in the values + +```bash .env +# Required Settings +DATABASE_URL="postgresql://postiz-user:postiz-password@localhost:5432/postiz-db-local" +REDIS_URL="redis://localhost:6379" +JWT_SECRET="random string for your JWT secret, make it long" +FRONTEND_URL="http://localhost:4200" +NEXT_PUBLIC_BACKEND_URL="http://localhost:3000" +BACKEND_INTERNAL_URL="http://localhost:3000" + +# Social Media API Settings +X_API_KEY="Twitter API key for normal oAuth not oAuth2" +X_API_SECRET="Twitter API secret for normal oAuth not oAuth2" +LINKEDIN_CLIENT_ID="Linkedin Client ID" +LINKEDIN_CLIENT_SECRET="Linkedin Client Secret" +REDDIT_CLIENT_ID="Reddit Client ID" +REDDIT_CLIENT_SECRET="Linkedin Client Secret" +GITHUB_CLIENT_ID="GitHub Client ID" +GITHUB_CLIENT_SECRET="GitHub Client Secret" +RESEND_API_KEY="Resend API KEY" +UPLOAD_DIRECTORY="optional: your upload directory path if you host your files locally" +NEXT_PUBLIC_UPLOAD_STATIC_DIRECTORY="optional: your upload directory slug if you host your files locally" +CLOUDFLARE_ACCOUNT_ID="Cloudflare R2 Account ID" +CLOUDFLARE_ACCESS_KEY="Cloudflare R2 Access Key" +CLOUDFLARE_SECRET_ACCESS_KEY="Cloudflare R2 Secret Access Key" +CLOUDFLARE_BUCKETNAME="Cloudflare R2 Bucket Name" +CLOUDFLARE_BUCKET_URL="Cloudflare R2 Backet URL" + +# Developer Settings +NX_ADD_PLUGINS=false +IS_GENERAL="true" # required for now +``` + + + + +```bash Terminal +npm install +``` + + + +```bash Terminal +npm run prisma-db-push +``` + + + +```bash Terminal +npm run dev +``` + + + +If everything is running successfully, open http://localhost:4200 in your browser! + +If everything is not running - you had errors in the steps above, please head over to our [support](/support) page. + +## Next Steps + + + + Learn the architecture of the project + + + Set up email for notifications + + + Set up github for authentication and sync + + + Set up providers such as Linkedin, X and Reddit + + diff --git a/apps/docs/installation/docker-compose.mdx b/apps/docs/installation/docker-compose.mdx new file mode 100644 index 00000000..21b01799 --- /dev/null +++ b/apps/docs/installation/docker-compose.mdx @@ -0,0 +1,69 @@ +--- +title: Docker Compose +--- + +import EarlyDoc from '/snippets/earlydoc.mdx'; +import DockerDatabase from '/snippets/docker-database.mdx'; +import DockerEnvvarApps from '/snippets/docker-envvar-apps.mdx'; + + + + +# Example `docker-compose.yml` file + +```yaml +services: + postiz: + image: ghcr.io/gitroomhq/postiz-app:latest + container_name: postiz + restart: always + volumes: + - ./config:/config/ # Should contain your .env file + ports: + - 4200:4200 + - 3000:3000 + networks: + - postiz-network + + postiz-postgres: + image: postgres:14.5 + container_name: postiz-postgres + restart: always + environment: + POSTGRES_PASSWORD: postiz-local-pwd + POSTGRES_USER: postiz-local + POSTGRES_DB: postiz-db-local + volumes: + - postgres-volume:/var/lib/postgresql/data + ports: + - 5432:5432 + networks: + - postiz-network + postiz-pg-admin: + image: dpage/pgadmin4 + container_name: postiz-pg-admin + restart: always + ports: + - 8081:80 + environment: + PGADMIN_DEFAULT_EMAIL: admin@admin.com + PGADMIN_DEFAULT_PASSWORD: admin + networks: + - postiz-network + postiz-redis: + image: redis:7.2 + container_name: postiz-redis + restart: always + ports: + - 6379:6379 + +volumes: + postgres-volume: + external: false + +networks: + postiz-network: + external: false +``` + + diff --git a/apps/docs/installation/docker.mdx b/apps/docs/installation/docker.mdx new file mode 100644 index 00000000..487bf23c --- /dev/null +++ b/apps/docs/installation/docker.mdx @@ -0,0 +1,20 @@ +--- +title: Docker +--- + +import EarlyDoc from '/snippets/earlydoc.mdx'; +import DockerDatabase from '/snippets/docker-database.mdx'; +import DockerEnvvarApps from '/snippets/docker-envvar-apps.mdx'; + + + + + + +# Create the container on command line + +```bash +docker create --name postiz -v ./config:/config -p 4200:4200 -p 3000:3000 ghcr.io/postiz/postiz:latest +``` + + diff --git a/apps/docs/installation/kubernetes-helm.mdx b/apps/docs/installation/kubernetes-helm.mdx new file mode 100644 index 00000000..819a6498 --- /dev/null +++ b/apps/docs/installation/kubernetes-helm.mdx @@ -0,0 +1,13 @@ +--- +title: Helm +--- + +import EarlyDoc from '/snippets/earlydoc.mdx'; +import DockerDatabase from '/snippets/docker-database.mdx'; + + + + +Postiz has a helm chart that is in very active development. You can find it here; + +https://github.com/gitroomhq/postiz-helmchart diff --git a/apps/docs/mint.json b/apps/docs/mint.json index 30a445ca..7fa169e0 100644 --- a/apps/docs/mint.json +++ b/apps/docs/mint.json @@ -61,6 +61,15 @@ "pages": [ "introduction", "quickstart", + { + "group": "Install", + "pages": [ + "installation/development", + "installation/docker", + "installation/docker-compose", + "installation/kubernetes-helm" + ] + }, "howitworks", "emails", "github", @@ -73,9 +82,15 @@ "providers/articles" ] }, - "providers/how-to-add-provider" + "support" ] - } + }, + { + "group": "Developer Guide", + "pages": [ + "developer-guide/how-to-add-provider" + ] + } ], "footerSocials": { "twitter": "https://twitter.com/nevodavid", diff --git a/apps/docs/quickstart.mdx b/apps/docs/quickstart.mdx index 5af8c0af..c2d7f3e1 100644 --- a/apps/docs/quickstart.mdx +++ b/apps/docs/quickstart.mdx @@ -6,115 +6,13 @@ At the moment it is necessary to build the project locally - some dependencies like redis and postgres can run as docker containers, but there is no docker container for Postiz just yet. -## Prerequisites +## Self Hosted installation options -To run the project you need to have multiple things: +You can choose between the following installation options; -- Node.js (version 18+) -- PostgreSQL (or any other SQL database) -- Redis -- Resend account -- Cloudflare R2 for uploads (optional, can use local machine) -- Social Media Client and Secret (more details later) +* [Development](/installation/development) - The only installation option that is offically supported at the moment. +* [Docker (standalone)](/installation/docker) - Run from the command line with Docker. +* [Docker Compose](/installation/docker-compose) - Run with Docker Compose. +* [Helm](/installation/kubernetes-helm) - Run with Kubernetes + Helm. -### NodeJS (version 18+) -A complete guide of how to install NodeJS can be found [here](https://nodejs.org/en/download/). - -### PostgreSQL (or any other SQL database) & Redis - -Make sure you have PostgreSQL installed on your machine. - -#### Option A) Postgres and Redis as Single containers - -You can install [Docker](https://www.docker.com/products/docker-desktop) and run: - -```bash Terminal -docker run -e POSTGRES_USER=root -e POSTGRES_PASSWORD=your_password --name postgres -p 5432:5432 -d postgres -docker run --name redis -p 6379:6379 -d redis -``` - -#### Option B) Postgres and Redis as docker-compose - -Download the [docker-compose.yaml file here](https://raw.githubusercontent.com/gitroomhq/postiz-app/main/docker-compose.dev.yaml), -or grab it from the repository in the next step. - -```bash Terminal -docker compose -f "docker-compose.dev.yaml" up -``` - -## Build Postiz - - - -```bash Terminal -git clone https://github.com/gitroomhq/gitroom -``` - - - -Copy the `.env.example` file to `.env` and fill in the values - -```bash .env -DATABASE_URL="postgres database URL i.g. postgresql://postiz-local:postiz-local-pwd@0.0.0.0:5432/postiz-db-local" -REDIS_URL="redis database URL" -JWT_SECRET="random string for your JWT secret, make it long" -FRONTEND_URL="By default: http://localhost:4200" -NEXT_PUBLIC_BACKEND_URL="By default: http://localhost:3000" -BACKEND_INTERNAL_URL="If you use docker, you might want something like: http://backend:3000" -X_API_KEY="Twitter API key for normal oAuth not oAuth2" -X_API_SECRET="Twitter API secret for normal oAuth not oAuth2" -LINKEDIN_CLIENT_ID="Linkedin Client ID" -LINKEDIN_CLIENT_SECRET="Linkedin Client Secret" -REDDIT_CLIENT_ID="Reddit Client ID" -REDDIT_CLIENT_SECRET="Linkedin Client Secret" -GITHUB_CLIENT_ID="GitHub Client ID" -GITHUB_CLIENT_SECRET="GitHub Client Secret" -RESEND_API_KEY="Resend API KEY" -UPLOAD_DIRECTORY="optional: your upload directory path if you host your files locally" -NEXT_PUBLIC_UPLOAD_STATIC_DIRECTORY="optional: your upload directory slug if you host your files locally" -CLOUDFLARE_ACCOUNT_ID="Cloudflare R2 Account ID" -CLOUDFLARE_ACCESS_KEY="Cloudflare R2 Access Key" -CLOUDFLARE_SECRET_ACCESS_KEY="Cloudflare R2 Secret Access Key" -CLOUDFLARE_BUCKETNAME="Cloudflare R2 Bucket Name" -CLOUDFLARE_BUCKET_URL="Cloudflare R2 Backet URL" -NX_ADD_PLUGINS=false -IS_GENERAL="true" # required for now -``` - - - - -```bash Terminal -npm install -``` - - - -```bash Terminal -npm run prisma-db-push -``` - - - -```bash Terminal -npm run dev -``` - - -You have to follow all the tabs in the "Developers" menu to install Gitroom - - - - Learn the architecture of the project - - - Set up email for notifications - - - Set up github for authentication and sync - - - Set up providers such as Linkedin, X and Reddit - - diff --git a/apps/docs/snippets/docker-database.mdx b/apps/docs/snippets/docker-database.mdx new file mode 100644 index 00000000..babd2cf5 --- /dev/null +++ b/apps/docs/snippets/docker-database.mdx @@ -0,0 +1,6 @@ + +The container images do not yet provide automatic database "installation" +(migrations). This must be done manually outside of the docker containers for now. + +This is being worked on with a high priority. + diff --git a/apps/docs/snippets/docker-envvar-apps.mdx b/apps/docs/snippets/docker-envvar-apps.mdx new file mode 100644 index 00000000..967daf40 --- /dev/null +++ b/apps/docs/snippets/docker-envvar-apps.mdx @@ -0,0 +1,7 @@ +## Controlling container services +The environment variable POSTIZ_APPS defaults to "", which means that all +services will be started in a single container. However, you can only start +specific services within the docker container by changing this environement variable. + +For most deployments, starting all services is fine. To scale out, you might want +to start individual containers for "frontend", "backend", "worker" and "cron". diff --git a/apps/docs/snippets/earlydoc.mdx b/apps/docs/snippets/earlydoc.mdx new file mode 100644 index 00000000..c6ef810f --- /dev/null +++ b/apps/docs/snippets/earlydoc.mdx @@ -0,0 +1,6 @@ + + **NOTE:** This page is marked "earlydoc", or "early documentation", which means it might + be brief, or contain information about parts of the app that are under heavy development. + If you encounter issues with instructions found here, please check out the [support](/support) + page for options. + diff --git a/apps/docs/snippets/snippet-example.mdx b/apps/docs/snippets/snippet-example.mdx new file mode 100644 index 00000000..089334c5 --- /dev/null +++ b/apps/docs/snippets/snippet-example.mdx @@ -0,0 +1,3 @@ +## My Snippet + +This is an example of a reusable snippet diff --git a/apps/docs/support.mdx b/apps/docs/support.mdx new file mode 100644 index 00000000..837f6c86 --- /dev/null +++ b/apps/docs/support.mdx @@ -0,0 +1,35 @@ +--- +title: Support +--- + +Sometimes, things can go wrong, or you need some help! + +Note that the Self Hosted version of Postiz is supported by the community in their +free time, on a best-efforts basis. Please post your question and be patient. + +- [Discord](https://discord.com/invite/sf7QjTcX37) - Flexible chat, with screenshots and screen sharing, probably the best option for support. +- [GitHub issue](https://github.com/gitroomhq/postiz-app/issues/new/choose) - backup option if you are unable to use Discord. + +## How to effectively ask for support + +Try to follow this guide when asking for support, in this order; **Goal, Environment, Changes, Results**. + +- **Goal:** Start off by explaining what you were trying to do + - _I want to schedule a post on Reddit at 6pm_ + - _I want to run in a Linux container on a Raspberry Pi_ + - _I want to use a custom domain name_ + +- **Environment:** - Share the relevant parts about your environment. Web App issues; Are you using Firefox, Chrome, etc? Installation/Other issues; a Mac, Linux, Windows, how did you install? + - _I'm using Firefox on Windows 10_ + - _I'm using a Raspberry Pi 4 with Ubuntu 20.04, and Node version 18_ + - _This is a new installation on a Mac_ + +- **Changed:** - Most likely something has changed, what is it? + - _I updated my browser to the latest version and now ..._ + - _I found a change in the latest version and now ..._ + - _I think this used to work, but now..._ + +- **Results:** - What happened? What did you expect to happen? + - _I see a blank screen_ + - _I see an error message_ + - _I see a 404 page_ From 53e4b4604c3dbf36fb91294642bb41d149a33ec2 Mon Sep 17 00:00:00 2001 From: jamesread Date: Tue, 10 Sep 2024 19:49:52 +0100 Subject: [PATCH 61/62] ci: Disable CI jobs when docs change --- .github/workflows/build.yaml | 2 ++ .github/workflows/codeql.yml | 2 ++ .github/workflows/eslint.yaml | 2 ++ apps/docs/_snippets/snippet-example.mdx | 3 --- 4 files changed, 6 insertions(+), 3 deletions(-) delete mode 100644 apps/docs/_snippets/snippet-example.mdx diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a1163412..dc333bf9 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -8,12 +8,14 @@ on: paths: - package.json - apps/** + - !apps/docs/** - libraries/** pull_request: paths: - package.json - apps/** + - !apps/docs/** - libraries/** jobs: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e8648af2..34a6ffc7 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -7,11 +7,13 @@ on: - main paths: - apps/** + - !apps/docs/** - libraries/** pull_request: paths: - apps/** + - !apps/docs/** - libraries/** jobs: diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index 7e64f645..4b55adf2 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -8,12 +8,14 @@ on: paths: - package.json - apps/** + - !apps/docs/** - libraries/** pull_request: paths: - package.json - apps/** + - !apps/docs/** - libraries/** jobs: diff --git a/apps/docs/_snippets/snippet-example.mdx b/apps/docs/_snippets/snippet-example.mdx deleted file mode 100644 index 089334c5..00000000 --- a/apps/docs/_snippets/snippet-example.mdx +++ /dev/null @@ -1,3 +0,0 @@ -## My Snippet - -This is an example of a reusable snippet From 39ecf5c072f34cf7ebbd25a50ef598d0cda11692 Mon Sep 17 00:00:00 2001 From: jamesread Date: Tue, 10 Sep 2024 19:58:38 +0100 Subject: [PATCH 62/62] ci: Fix yaml issues in changed paths --- .github/workflows/build.yaml | 4 ++-- .github/workflows/codeql.yml | 4 ++-- .github/workflows/eslint.yaml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index dc333bf9..9223504b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -8,14 +8,14 @@ on: paths: - package.json - apps/** - - !apps/docs/** + - '!apps/docs/**' - libraries/** pull_request: paths: - package.json - apps/** - - !apps/docs/** + - '!apps/docs/**' - libraries/** jobs: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 34a6ffc7..6f1d8dc2 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -7,13 +7,13 @@ on: - main paths: - apps/** - - !apps/docs/** + - '!apps/docs/**' - libraries/** pull_request: paths: - apps/** - - !apps/docs/** + - '!apps/docs/**' - libraries/** jobs: diff --git a/.github/workflows/eslint.yaml b/.github/workflows/eslint.yaml index 4b55adf2..8579a8e1 100644 --- a/.github/workflows/eslint.yaml +++ b/.github/workflows/eslint.yaml @@ -8,14 +8,14 @@ on: paths: - package.json - apps/** - - !apps/docs/** + - '!apps/docs/**' - libraries/** pull_request: paths: - package.json - apps/** - - !apps/docs/** + - '!apps/docs/**' - libraries/** jobs: