├── .devcontainer └── devcontainer.json ├── .dockerignore ├── .env.example ├── .eslintignore ├── .github ├── Dependabot.yml ├── ISSUE_TEMPLATE │ ├── 01_installation.prolem.yml │ ├── 02_bug_report.yml │ └── 03_feature_request.yml ├── PULL_REQUEST_TEMPLATE.md ├── assets │ ├── gitroom-darkmode-logo.png │ ├── gitroom-lightmode-logo.png │ ├── gitroom-main-youtube.png │ ├── screen-002.png │ ├── screen-003.png │ └── screen-004.png └── workflows │ ├── build-containers-enterprise.yml │ ├── build-containers.yml │ ├── build-extension.yaml │ ├── build.yaml │ ├── codeql.yml │ ├── eslint │ ├── issue-label-triggers.yml │ ├── pr-docker-build.yml │ ├── publish-extension.yml │ └── stale.yml ├── .gitignore ├── .gitmodules ├── .npmrc ├── .prettierignore ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Dockerfile.dev ├── Jenkinsfile ├── LICENSE ├── README.md ├── SECURITY.md ├── apps ├── backend │ ├── .gitignore │ ├── .swcrc │ ├── nest-cli.json │ ├── package.json │ ├── src │ │ ├── api │ │ │ ├── api.module.ts │ │ │ └── routes │ │ │ │ ├── agencies.controller.ts │ │ │ │ ├── analytics.controller.ts │ │ │ │ ├── auth.controller.ts │ │ │ │ ├── autopost.controller.ts │ │ │ │ ├── billing.controller.ts │ │ │ │ ├── copilot.controller.ts │ │ │ │ ├── integrations.controller.ts │ │ │ │ ├── marketplace.controller.ts │ │ │ │ ├── mcp.controller.ts │ │ │ │ ├── media.controller.ts │ │ │ │ ├── messages.controller.ts │ │ │ │ ├── notifications.controller.ts │ │ │ │ ├── posts.controller.ts │ │ │ │ ├── public.controller.ts │ │ │ │ ├── root.controller.ts │ │ │ │ ├── settings.controller.ts │ │ │ │ ├── signature.controller.ts │ │ │ │ ├── stripe.controller.ts │ │ │ │ ├── users.controller.ts │ │ │ │ └── webhooks.controller.ts │ │ ├── app.module.ts │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── main.ts │ │ ├── mcp │ │ │ ├── main.mcp.ts │ │ │ └── mcp.module.ts │ │ ├── public-api │ │ │ ├── public.api.module.ts │ │ │ └── routes │ │ │ │ └── v1 │ │ │ │ └── public.integrations.controller.ts │ │ └── services │ │ │ └── auth │ │ │ ├── auth.middleware.ts │ │ │ ├── auth.service.ts │ │ │ ├── permissions │ │ │ ├── permissions.ability.ts │ │ │ ├── permissions.guard.ts │ │ │ ├── permissions.service.test.ts │ │ │ ├── permissions.service.ts │ │ │ └── subscription.exception.ts │ │ │ ├── providers.interface.ts │ │ │ ├── providers │ │ │ ├── farcaster.provider.ts │ │ │ ├── github.provider.ts │ │ │ ├── google.provider.ts │ │ │ ├── oauth.provider.ts │ │ │ ├── providers.factory.ts │ │ │ └── wallet.provider.ts │ │ │ └── public.auth.middleware.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── commands │ ├── .gitignore │ ├── nest-cli.json │ ├── package.json │ ├── src │ │ ├── command.module.ts │ │ ├── main.ts │ │ └── tasks │ │ │ ├── agent.run.ts │ │ │ ├── check.stars.ts │ │ │ ├── configuration.ts │ │ │ └── refresh.tokens.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── cron │ ├── .gitignore │ ├── .swcrc │ ├── nest-cli.json │ ├── package.json │ ├── src │ │ ├── cron.module.ts │ │ ├── main.ts │ │ └── tasks │ │ │ ├── check.stars.ts │ │ │ └── sync.trending.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── extension │ ├── .gitignore │ ├── custom-vite-plugins.ts │ ├── manifest.dev.json │ ├── manifest.json │ ├── nodemon.chrome.json │ ├── nodemon.firefox.json │ ├── package.json │ ├── public │ │ ├── contentStyle.css │ │ ├── dev-icon-128.png │ │ ├── dev-icon-32.png │ │ ├── icon-128.png │ │ └── icon-32.png │ ├── src │ │ ├── assets │ │ │ ├── img │ │ │ │ └── logo.svg │ │ │ └── styles │ │ │ │ └── tailwind.css │ │ ├── global.d.ts │ │ ├── locales │ │ │ └── en │ │ │ │ └── messages.json │ │ ├── pages │ │ │ ├── background │ │ │ │ └── index.ts │ │ │ ├── content │ │ │ │ ├── elements │ │ │ │ │ └── action.component.tsx │ │ │ │ ├── index.tsx │ │ │ │ ├── main.content.tsx │ │ │ │ └── style.css │ │ │ ├── options │ │ │ │ ├── Options.css │ │ │ │ ├── Options.tsx │ │ │ │ ├── index.css │ │ │ │ ├── index.html │ │ │ │ └── index.tsx │ │ │ ├── panel │ │ │ │ ├── Panel.css │ │ │ │ ├── Panel.tsx │ │ │ │ ├── index.css │ │ │ │ ├── index.html │ │ │ │ └── index.tsx │ │ │ └── popup │ │ │ │ ├── Popup.tsx │ │ │ │ ├── index.css │ │ │ │ ├── index.html │ │ │ │ └── index.tsx │ │ ├── providers │ │ │ ├── list │ │ │ │ ├── linkedin.provider.ts │ │ │ │ └── x.provider.ts │ │ │ ├── provider.interface.ts │ │ │ └── provider.list.ts │ │ ├── utils │ │ │ ├── load.cookie.ts │ │ │ ├── load.storage.ts │ │ │ ├── request.util.ts │ │ │ └── save.storage.ts │ │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── vite.config.base.ts │ ├── vite.config.chrome.ts │ └── vite.config.firefox.ts ├── frontend │ ├── .gitignore │ ├── README.md │ ├── next.config.js │ ├── package.json │ ├── postcss.config.mjs │ ├── public │ │ ├── .gitkeep │ │ ├── auth │ │ │ ├── bg-login.png │ │ │ └── login-box.png │ │ ├── f.js │ │ ├── favicon.ico │ │ ├── favicon.png │ │ ├── form │ │ │ └── checked.svg │ │ ├── icons │ │ │ ├── generic-oauth.svg │ │ │ ├── github.svg │ │ │ ├── platforms │ │ │ │ ├── bluesky.png │ │ │ │ ├── devto.png │ │ │ │ ├── discord.png │ │ │ │ ├── dribbble.png │ │ │ │ ├── facebook.png │ │ │ │ ├── hashnode.png │ │ │ │ ├── instagram-standalone.png │ │ │ │ ├── instagram.png │ │ │ │ ├── lemmy.png │ │ │ │ ├── linkedin-page.png │ │ │ │ ├── linkedin.png │ │ │ │ ├── mastodon-custom.png │ │ │ │ ├── mastodon.png │ │ │ │ ├── medium.png │ │ │ │ ├── nostr.png │ │ │ │ ├── pinterest.png │ │ │ │ ├── reddit.png │ │ │ │ ├── slack.png │ │ │ │ ├── telegram.png │ │ │ │ ├── threads.png │ │ │ │ ├── tiktok.png │ │ │ │ ├── vk.png │ │ │ │ ├── wrapcast.png │ │ │ │ ├── x.png │ │ │ │ ├── youtube.png │ │ │ │ └── youtube.svg │ │ │ ├── star-circle.svg │ │ │ └── trending.svg │ │ ├── logo.svg │ │ ├── magic.svg │ │ ├── no-picture.jpg │ │ ├── peoplemarketplace.svg │ │ ├── postiz-fav.png │ │ ├── postiz-text.svg │ │ ├── postiz.svg │ │ └── success.svg │ ├── src │ │ ├── app │ │ │ ├── (app) │ │ │ │ ├── (preview) │ │ │ │ │ └── p │ │ │ │ │ │ └── [id] │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ └── page.tsx │ │ │ │ ├── (site) │ │ │ │ │ ├── analytics │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── billing │ │ │ │ │ │ ├── lifetime │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── err │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── integrations │ │ │ │ │ │ └── social │ │ │ │ │ │ │ ├── [provider] │ │ │ │ │ │ │ ├── continue │ │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ │ └── layout.tsx │ │ │ │ │ ├── launches │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── layout.tsx │ │ │ │ │ ├── marketplace │ │ │ │ │ │ ├── buyer │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ ├── page.tsx │ │ │ │ │ │ └── seller │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── messages │ │ │ │ │ │ ├── [id] │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ ├── layout.tsx │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── plugs │ │ │ │ │ │ └── page.tsx │ │ │ │ │ └── settings │ │ │ │ │ │ └── page.tsx │ │ │ │ ├── api │ │ │ │ │ └── uploads │ │ │ │ │ │ └── [[...path]] │ │ │ │ │ │ └── route.ts │ │ │ │ ├── auth │ │ │ │ │ ├── activate │ │ │ │ │ │ ├── [code] │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── forgot │ │ │ │ │ │ ├── [token] │ │ │ │ │ │ │ └── page.tsx │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── layout.tsx │ │ │ │ │ ├── login │ │ │ │ │ │ └── page.tsx │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── return.url.component.tsx │ │ │ │ └── layout.tsx │ │ │ ├── (extension) │ │ │ │ ├── layout.tsx │ │ │ │ └── modal │ │ │ │ │ ├── [style] │ │ │ │ │ └── [platform] │ │ │ │ │ │ └── page.tsx │ │ │ │ │ └── layout.tsx │ │ │ ├── colors.scss │ │ │ ├── global.scss │ │ │ └── polonto.css │ │ ├── components │ │ │ ├── analytics │ │ │ │ ├── analytics.component.tsx │ │ │ │ ├── chart-social.tsx │ │ │ │ ├── chart.tsx │ │ │ │ ├── stars.and.forks.interface.ts │ │ │ │ ├── stars.and.forks.tsx │ │ │ │ └── stars.table.component.tsx │ │ │ ├── auth │ │ │ │ ├── activate.tsx │ │ │ │ ├── after.activate.tsx │ │ │ │ ├── forgot-return.tsx │ │ │ │ ├── forgot.tsx │ │ │ │ ├── login.tsx │ │ │ │ ├── nayner.auth.button.tsx │ │ │ │ ├── providers │ │ │ │ │ ├── farcaster.provider.tsx │ │ │ │ │ ├── github.provider.tsx │ │ │ │ │ ├── google.provider.tsx │ │ │ │ │ ├── oauth.provider.tsx │ │ │ │ │ ├── placeholder │ │ │ │ │ │ └── wallet.ui.provider.tsx │ │ │ │ │ └── wallet.provider.tsx │ │ │ │ └── register.tsx │ │ │ ├── autopost │ │ │ │ └── autopost.tsx │ │ │ ├── billing │ │ │ │ ├── billing.component.tsx │ │ │ │ ├── faq.component.tsx │ │ │ │ ├── lifetime.deal.tsx │ │ │ │ ├── main.billing.component.tsx │ │ │ │ └── purchase.crypto.tsx │ │ │ ├── launches │ │ │ │ ├── add.edit.model.tsx │ │ │ │ ├── add.post.button.tsx │ │ │ │ ├── add.provider.component.tsx │ │ │ │ ├── ai.image.tsx │ │ │ │ ├── bold.text.tsx │ │ │ │ ├── bot.picture.tsx │ │ │ │ ├── calendar.context.tsx │ │ │ │ ├── calendar.tsx │ │ │ │ ├── comments │ │ │ │ │ └── comment.component.tsx │ │ │ │ ├── connect.with.wallet.tsx │ │ │ │ ├── customer.modal.tsx │ │ │ │ ├── editor.tsx │ │ │ │ ├── filters.tsx │ │ │ │ ├── finisher │ │ │ │ │ └── thread.finisher.tsx │ │ │ │ ├── general.preview.component.tsx │ │ │ │ ├── generator │ │ │ │ │ └── generator.tsx │ │ │ │ ├── helpers │ │ │ │ │ ├── date.picker.tsx │ │ │ │ │ ├── dnd.provider.tsx │ │ │ │ │ ├── isuscitizen.utils.tsx │ │ │ │ │ ├── linkedin.component.tsx │ │ │ │ │ ├── new.image.component.tsx │ │ │ │ │ ├── pick.platform.component.tsx │ │ │ │ │ ├── top.title.component.tsx │ │ │ │ │ ├── use.custom.provider.function.ts │ │ │ │ │ ├── use.existing.data.tsx │ │ │ │ │ ├── use.expend.tsx │ │ │ │ │ ├── use.formatting.ts │ │ │ │ │ ├── use.hide.top.editor.tsx │ │ │ │ │ ├── use.integration.ts │ │ │ │ │ ├── use.move.to.integration.tsx │ │ │ │ │ └── use.values.ts │ │ │ │ ├── integration.redirect.component.tsx │ │ │ │ ├── internal.channels.tsx │ │ │ │ ├── launches.component.tsx │ │ │ │ ├── layout.standalone.tsx │ │ │ │ ├── menu │ │ │ │ │ └── menu.tsx │ │ │ │ ├── merge.post.tsx │ │ │ │ ├── new.post.tsx │ │ │ │ ├── polonto.tsx │ │ │ │ ├── polonto │ │ │ │ │ └── polonto.picture.generation.tsx │ │ │ │ ├── post.to.organization.tsx │ │ │ │ ├── providers.options.tsx │ │ │ │ ├── providers │ │ │ │ │ ├── bluesky │ │ │ │ │ │ └── bluesky.provider.tsx │ │ │ │ │ ├── continue-provider │ │ │ │ │ │ ├── facebook │ │ │ │ │ │ │ └── facebook.continue.tsx │ │ │ │ │ │ ├── instagram │ │ │ │ │ │ │ └── instagram.continue.tsx │ │ │ │ │ │ ├── linkedin │ │ │ │ │ │ │ └── linkedin.continue.tsx │ │ │ │ │ │ └── list.tsx │ │ │ │ │ ├── devto │ │ │ │ │ │ ├── devto.provider.tsx │ │ │ │ │ │ ├── devto.tags.tsx │ │ │ │ │ │ ├── fonts │ │ │ │ │ │ │ └── SFNS.woff2 │ │ │ │ │ │ └── select.organization.tsx │ │ │ │ │ ├── discord │ │ │ │ │ │ ├── discord.channel.select.tsx │ │ │ │ │ │ └── discord.provider.tsx │ │ │ │ │ ├── dribbble │ │ │ │ │ │ ├── dribbble.provider.tsx │ │ │ │ │ │ └── dribbble.teams.tsx │ │ │ │ │ ├── facebook │ │ │ │ │ │ └── facebook.provider.tsx │ │ │ │ │ ├── hashnode │ │ │ │ │ │ ├── hashnode.provider.tsx │ │ │ │ │ │ ├── hashnode.publications.tsx │ │ │ │ │ │ └── hashnode.tags.tsx │ │ │ │ │ ├── high.order.provider.tsx │ │ │ │ │ ├── instagram │ │ │ │ │ │ ├── instagram.collaborators.tsx │ │ │ │ │ │ └── instagram.tags.tsx │ │ │ │ │ ├── lemmy │ │ │ │ │ │ ├── lemmy.provider.tsx │ │ │ │ │ │ └── subreddit.tsx │ │ │ │ │ ├── linkedin │ │ │ │ │ │ └── linkedin.provider.tsx │ │ │ │ │ ├── mastodon │ │ │ │ │ │ └── mastodon.provider.tsx │ │ │ │ │ ├── medium │ │ │ │ │ │ ├── fonts │ │ │ │ │ │ │ ├── Charter Bold Italic.ttf │ │ │ │ │ │ │ ├── Charter Bold.ttf │ │ │ │ │ │ │ ├── Charter Italic.ttf │ │ │ │ │ │ │ ├── Charter Regular.ttf │ │ │ │ │ │ │ └── stylesheet.css │ │ │ │ │ │ ├── medium.provider.tsx │ │ │ │ │ │ ├── medium.publications.tsx │ │ │ │ │ │ └── medium.tags.tsx │ │ │ │ │ ├── nostr │ │ │ │ │ │ └── nostr.provider.tsx │ │ │ │ │ ├── pinterest │ │ │ │ │ │ ├── pinterest.board.tsx │ │ │ │ │ │ └── pinterest.provider.tsx │ │ │ │ │ ├── reddit │ │ │ │ │ │ ├── reddit.provider.tsx │ │ │ │ │ │ └── subreddit.tsx │ │ │ │ │ ├── show.all.providers.tsx │ │ │ │ │ ├── slack │ │ │ │ │ │ ├── slack.channel.select.tsx │ │ │ │ │ │ └── slack.provider.tsx │ │ │ │ │ ├── telegram │ │ │ │ │ │ └── telegram.provider.tsx │ │ │ │ │ ├── threads │ │ │ │ │ │ └── threads.provider.tsx │ │ │ │ │ ├── tiktok │ │ │ │ │ │ └── tiktok.provider.tsx │ │ │ │ │ ├── vk │ │ │ │ │ │ └── vk.provider.tsx │ │ │ │ │ ├── warpcast │ │ │ │ │ │ ├── subreddit.tsx │ │ │ │ │ │ └── warpcast.provider.tsx │ │ │ │ │ ├── x │ │ │ │ │ │ ├── fonts │ │ │ │ │ │ │ ├── Chirp-Bold.woff2 │ │ │ │ │ │ │ └── Chirp-Regular.woff2 │ │ │ │ │ │ └── x.provider.tsx │ │ │ │ │ └── youtube │ │ │ │ │ │ └── youtube.provider.tsx │ │ │ │ ├── repeat.component.tsx │ │ │ │ ├── select.customer.tsx │ │ │ │ ├── settings.modal.tsx │ │ │ │ ├── statistics.tsx │ │ │ │ ├── submitted.tsx │ │ │ │ ├── tags.component.tsx │ │ │ │ ├── time.table.tsx │ │ │ │ ├── u.text.tsx │ │ │ │ ├── up.down.arrow.tsx │ │ │ │ └── web3 │ │ │ │ │ ├── providers │ │ │ │ │ ├── nostr.provider.tsx │ │ │ │ │ ├── telegram.provider.tsx │ │ │ │ │ └── wrapcaster.provider.tsx │ │ │ │ │ ├── web3.list.tsx │ │ │ │ │ └── web3.provider.interface.ts │ │ │ ├── layout │ │ │ │ ├── check.payment.tsx │ │ │ │ ├── chrome.extension.component.tsx │ │ │ │ ├── click.outside.tsx │ │ │ │ ├── continue.provider.tsx │ │ │ │ ├── drop.files.tsx │ │ │ │ ├── facebook.component.tsx │ │ │ │ ├── html.component.tsx │ │ │ │ ├── impersonate.tsx │ │ │ │ ├── language.component.tsx │ │ │ │ ├── layout.context.tsx │ │ │ │ ├── layout.settings.tsx │ │ │ │ ├── loading.tsx │ │ │ │ ├── logout.component.tsx │ │ │ │ ├── mode.component.tsx │ │ │ │ ├── new.subscription.tsx │ │ │ │ ├── organization.selector.tsx │ │ │ │ ├── redirect.tsx │ │ │ │ ├── settings.component.tsx │ │ │ │ ├── support.tsx │ │ │ │ ├── title.tsx │ │ │ │ ├── tolt.script.tsx │ │ │ │ ├── top.menu.tsx │ │ │ │ ├── top.tip.tsx │ │ │ │ └── user.context.tsx │ │ │ ├── marketplace │ │ │ │ ├── buyer.seller.tsx │ │ │ │ ├── buyer.tsx │ │ │ │ ├── marketplace.provider.tsx │ │ │ │ ├── marketplace.tsx │ │ │ │ ├── order.list.tsx │ │ │ │ ├── order.top.actions.tsx │ │ │ │ ├── preview.popup.dynamic.tsx │ │ │ │ ├── seller.tsx │ │ │ │ └── special.message.tsx │ │ │ ├── media │ │ │ │ ├── media.component.tsx │ │ │ │ └── new.uploader.tsx │ │ │ ├── messages │ │ │ │ ├── layout.tsx │ │ │ │ └── messages.tsx │ │ │ ├── notifications │ │ │ │ └── notification.component.tsx │ │ │ ├── onboarding │ │ │ │ ├── connect.channels.tsx │ │ │ │ ├── github.onboarding.tsx │ │ │ │ └── onboarding.tsx │ │ │ ├── platform-analytics │ │ │ │ ├── platform.analytics.tsx │ │ │ │ └── render.analytics.tsx │ │ │ ├── plugs │ │ │ │ ├── plug.tsx │ │ │ │ ├── plugs.context.ts │ │ │ │ └── plugs.tsx │ │ │ ├── post-url-selector │ │ │ │ └── post.url.selector.tsx │ │ │ ├── preview │ │ │ │ ├── comments.components.tsx │ │ │ │ ├── copy.client.tsx │ │ │ │ └── preview.wrapper.tsx │ │ │ ├── public-api │ │ │ │ └── public.component.tsx │ │ │ ├── settings │ │ │ │ ├── github.component.tsx │ │ │ │ ├── settings.component.tsx │ │ │ │ ├── signatures.component.tsx │ │ │ │ └── teams.component.tsx │ │ │ ├── signature.tsx │ │ │ ├── standalone-modal │ │ │ │ └── standalone.modal.tsx │ │ │ ├── ui │ │ │ │ └── translated-label.tsx │ │ │ └── webhooks │ │ │ │ └── webhooks.tsx │ │ └── middleware.ts │ ├── tailwind.config.js │ └── tsconfig.json └── workers │ ├── .gitignore │ ├── .swcrc │ ├── nest-cli.json │ ├── package.json │ ├── src │ ├── app │ │ ├── app.module.ts │ │ ├── plugs.controller.ts │ │ ├── posts.controller.ts │ │ └── stars.controller.ts │ └── main.ts │ ├── tsconfig.build.json │ └── tsconfig.json ├── build.plugins.js ├── docker-compose.dev.yaml ├── eslint.config.mjs ├── i18n.json ├── i18n.lock ├── jest.config.ts ├── jest.preset.js ├── libraries ├── helpers │ └── src │ │ ├── auth │ │ └── auth.service.ts │ │ ├── configuration │ │ └── configuration.checker.ts │ │ ├── decorators │ │ ├── plug.decorator.ts │ │ └── post.plug.ts │ │ ├── subdomain │ │ ├── all.two.level.subdomain.ts │ │ └── subdomain.management.ts │ │ ├── swagger │ │ └── load.swagger.ts │ │ └── utils │ │ ├── count.length.ts │ │ ├── custom.fetch.func.ts │ │ ├── custom.fetch.tsx │ │ ├── internal.fetch.ts │ │ ├── is.dev.ts │ │ ├── is.general.server.side.ts │ │ ├── linkedin.company.prevent.remove.ts │ │ ├── read.or.fetch.ts │ │ ├── remove.markdown.ts │ │ ├── timer.ts │ │ ├── use.fire.events.ts │ │ └── utm.saver.tsx ├── nestjs-libraries │ ├── .eslintrc.json │ ├── README.md │ ├── src │ │ ├── agent │ │ │ ├── agent.categories.ts │ │ │ ├── agent.graph.insert.service.ts │ │ │ ├── agent.graph.service.ts │ │ │ ├── agent.module.ts │ │ │ └── agent.topics.ts │ │ ├── bull-mq-transport-new │ │ │ ├── bull.mq.module.ts │ │ │ ├── client.ts │ │ │ └── strategy.ts │ │ ├── crypto │ │ │ └── nowpayments.ts │ │ ├── database │ │ │ └── prisma │ │ │ │ ├── agencies │ │ │ │ ├── agencies.repository.ts │ │ │ │ └── agencies.service.ts │ │ │ │ ├── autopost │ │ │ │ ├── autopost.repository.ts │ │ │ │ └── autopost.service.ts │ │ │ │ ├── database.module.ts │ │ │ │ ├── integrations │ │ │ │ ├── integration.repository.ts │ │ │ │ └── integration.service.ts │ │ │ │ ├── marketplace │ │ │ │ ├── item.user.repository.ts │ │ │ │ ├── item.user.service.ts │ │ │ │ ├── messages.repository.ts │ │ │ │ ├── messages.service.ts │ │ │ │ └── tags.list.ts │ │ │ │ ├── media │ │ │ │ ├── media.repository.ts │ │ │ │ └── media.service.ts │ │ │ │ ├── notifications │ │ │ │ ├── notification.service.ts │ │ │ │ └── notifications.repository.ts │ │ │ │ ├── organizations │ │ │ │ ├── organization.repository.ts │ │ │ │ └── organization.service.ts │ │ │ │ ├── posts │ │ │ │ ├── posts.repository.ts │ │ │ │ └── posts.service.ts │ │ │ │ ├── prisma.service.ts │ │ │ │ ├── schema.prisma │ │ │ │ ├── signatures │ │ │ │ ├── signature.repository.ts │ │ │ │ └── signature.service.ts │ │ │ │ ├── stars │ │ │ │ ├── stars.repository.ts │ │ │ │ └── stars.service.ts │ │ │ │ ├── subscriptions │ │ │ │ ├── pricing.ts │ │ │ │ ├── subscription.repository.ts │ │ │ │ └── subscription.service.ts │ │ │ │ ├── users │ │ │ │ ├── users.repository.ts │ │ │ │ └── users.service.ts │ │ │ │ └── webhooks │ │ │ │ ├── webhooks.repository.ts │ │ │ │ └── webhooks.service.ts │ │ ├── dtos │ │ │ ├── agencies │ │ │ │ └── create.agency.dto.ts │ │ │ ├── analytics │ │ │ │ └── stars.list.dto.ts │ │ │ ├── auth │ │ │ │ ├── create.org.user.dto.ts │ │ │ │ ├── forgot-return.password.dto.ts │ │ │ │ ├── forgot.password.dto.ts │ │ │ │ └── login.user.dto.ts │ │ │ ├── autopost │ │ │ │ └── autopost.dto.ts │ │ │ ├── billing │ │ │ │ └── billing.subscribe.dto.ts │ │ │ ├── comments │ │ │ │ └── add.comment.dto.ts │ │ │ ├── generator │ │ │ │ ├── create.generated.posts.dto.ts │ │ │ │ └── generator.dto.ts │ │ │ ├── integrations │ │ │ │ ├── api.key.dto.ts │ │ │ │ ├── connect.integration.dto.ts │ │ │ │ ├── integration.function.dto.ts │ │ │ │ └── integration.time.dto.ts │ │ │ ├── marketplace │ │ │ │ ├── add.remove.item.dto.ts │ │ │ │ ├── audience.dto.ts │ │ │ │ ├── change.active.dto.ts │ │ │ │ ├── create.offer.dto.ts │ │ │ │ ├── items.dto.ts │ │ │ │ └── new.conversation.dto.ts │ │ │ ├── media │ │ │ │ └── media.dto.ts │ │ │ ├── messages │ │ │ │ └── add.message.ts │ │ │ ├── plugs │ │ │ │ └── plug.dto.ts │ │ │ ├── posts │ │ │ │ ├── create.post.dto.ts │ │ │ │ ├── create.tag.dto.ts │ │ │ │ ├── get.posts.dto.ts │ │ │ │ ├── lemmy.dto.ts │ │ │ │ └── providers-settings │ │ │ │ │ ├── all.providers.settings.ts │ │ │ │ │ ├── dev.to.settings.dto.ts │ │ │ │ │ ├── dev.to.tags.settings.dto.ts │ │ │ │ │ ├── discord.dto.ts │ │ │ │ │ ├── dribbble.dto.ts │ │ │ │ │ ├── hashnode.settings.dto.ts │ │ │ │ │ ├── instagram.dto.ts │ │ │ │ │ ├── medium.settings.dto.ts │ │ │ │ │ ├── pinterest.dto.ts │ │ │ │ │ ├── reddit.dto.ts │ │ │ │ │ ├── slack.dto.ts │ │ │ │ │ ├── tiktok.dto.ts │ │ │ │ │ └── youtube.settings.dto.ts │ │ │ ├── settings │ │ │ │ └── add.team.member.dto.ts │ │ │ ├── signature │ │ │ │ └── signature.dto.ts │ │ │ ├── users │ │ │ │ └── user.details.dto.ts │ │ │ └── webhooks │ │ │ │ └── webhooks.dto.ts │ │ ├── emails │ │ │ ├── email.interface.ts │ │ │ ├── empty.provider.ts │ │ │ ├── node.mailer.provider.ts │ │ │ └── resend.provider.ts │ │ ├── integrations │ │ │ ├── article │ │ │ │ ├── article.integrations.interface.ts │ │ │ │ ├── dev.to.provider.ts │ │ │ │ ├── hashnode.provider.ts │ │ │ │ ├── hashnode.tags.ts │ │ │ │ └── medium.provider.ts │ │ │ ├── integration.manager.ts │ │ │ ├── integration.missing.scopes.ts │ │ │ ├── social.abstract.ts │ │ │ └── social │ │ │ │ ├── bluesky.provider.ts │ │ │ │ ├── discord.provider.ts │ │ │ │ ├── dribbble.provider.ts │ │ │ │ ├── facebook.provider.ts │ │ │ │ ├── farcaster.provider.ts │ │ │ │ ├── instagram.provider.ts │ │ │ │ ├── instagram.standalone.provider.ts │ │ │ │ ├── lemmy.provider.ts │ │ │ │ ├── linkedin.page.provider.ts │ │ │ │ ├── linkedin.provider.ts │ │ │ │ ├── mastodon.custom.provider.ts │ │ │ │ ├── mastodon.provider.ts │ │ │ │ ├── nostr.provider.ts │ │ │ │ ├── pinterest.provider.ts │ │ │ │ ├── reddit.provider.ts │ │ │ │ ├── slack.provider.ts │ │ │ │ ├── social.integrations.interface.ts │ │ │ │ ├── telegram.provider.ts │ │ │ │ ├── threads.provider.ts │ │ │ │ ├── tiktok.provider.ts │ │ │ │ ├── vk.provider.ts │ │ │ │ ├── x.provider.ts │ │ │ │ └── youtube.provider.ts │ │ ├── mcp │ │ │ ├── mcp.service.ts │ │ │ ├── mcp.settings.ts │ │ │ ├── mcp.tool.ts │ │ │ ├── mcp.transport.ts │ │ │ └── mcp.types.ts │ │ ├── openai │ │ │ ├── extract.content.service.ts │ │ │ └── openai.service.ts │ │ ├── redis │ │ │ └── redis.service.ts │ │ ├── services │ │ │ ├── codes.service.ts │ │ │ ├── email.service.ts │ │ │ ├── exception.filter.ts │ │ │ ├── make.is.ts │ │ │ ├── newsletter.service.ts │ │ │ ├── stripe.country.list.ts │ │ │ ├── stripe.service.ts │ │ │ ├── trending.service.ts │ │ │ └── trending.ts │ │ ├── short-linking │ │ │ ├── providers │ │ │ │ ├── dub.ts │ │ │ │ ├── empty.ts │ │ │ │ └── short.io.ts │ │ │ ├── short-linking.interface.ts │ │ │ └── short.link.service.ts │ │ ├── throttler │ │ │ └── throttler.provider.ts │ │ ├── track │ │ │ └── track.service.ts │ │ ├── upload │ │ │ ├── cloudflare.storage.ts │ │ │ ├── custom.upload.validation.ts │ │ │ ├── local.storage.ts │ │ │ ├── r2.uploader.ts │ │ │ ├── upload.factory.ts │ │ │ ├── upload.interface.ts │ │ │ └── upload.module.ts │ │ └── user │ │ │ ├── org.from.request.ts │ │ │ ├── track.enum.ts │ │ │ ├── user.agent.ts │ │ │ └── user.from.request.ts │ ├── tsconfig.json │ └── tsconfig.lib.json ├── plugins │ ├── .eslintrc.json │ ├── README.md │ ├── src │ │ └── plugin.module.ts │ ├── tsconfig.json │ └── tsconfig.lib.json └── react-shared-libraries │ ├── .eslintrc.json │ ├── README.md │ ├── src │ ├── form │ │ ├── button.tsx │ │ ├── canonical.tsx │ │ ├── checkbox.tsx │ │ ├── color.picker.tsx │ │ ├── custom.select.tsx │ │ ├── input.tsx │ │ ├── select.tsx │ │ ├── slider.tsx │ │ ├── textarea.tsx │ │ ├── total.tsx │ │ └── track.tsx │ ├── helpers │ │ ├── delete.dialog.tsx │ │ ├── image.with.fallback.tsx │ │ ├── inter.font.ts │ │ ├── is.general.tsx │ │ ├── mantine.wrapper.tsx │ │ ├── posthog.tsx │ │ ├── uppy.upload.ts │ │ ├── use.is.visible.tsx │ │ ├── use.media.directory.ts │ │ ├── use.prevent.window.unload.tsx │ │ ├── use.state.callback.ts │ │ ├── use.track.tsx │ │ ├── utc.date.render.tsx │ │ ├── variable.context.tsx │ │ ├── video.frame.tsx │ │ └── video.or.image.tsx │ ├── toaster │ │ └── toaster.tsx │ └── translation │ │ ├── get.transation.service.client.ts │ │ ├── get.translation.service.backend.ts │ │ ├── i18n.config.ts │ │ ├── i18next.ts │ │ ├── locales │ │ ├── ar │ │ │ └── translation.json │ │ ├── bn │ │ │ └── translation.json │ │ ├── de │ │ │ └── translation.json │ │ ├── en │ │ │ └── translation.json │ │ ├── es │ │ │ └── translation.json │ │ ├── fr │ │ │ └── translation.json │ │ ├── he │ │ │ └── translation.json │ │ ├── it │ │ │ └── translation.json │ │ ├── ja │ │ │ └── translation.json │ │ ├── ko │ │ │ └── translation.json │ │ ├── pt │ │ │ └── translation.json │ │ ├── ru │ │ │ └── translation.json │ │ ├── tr │ │ │ └── translation.json │ │ ├── vi │ │ │ └── translation.json │ │ └── zh │ │ │ └── translation.json │ │ └── translated-label.tsx │ ├── tsconfig.json │ └── tsconfig.lib.json ├── package.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── railway.toml ├── reports └── junit.xml ├── tsconfig.base.json ├── tsconfig.json ├── var └── docker │ ├── Caddyfile │ ├── docker-build.sh │ ├── docker-create.sh │ ├── entrypoint.sh │ ├── supervisord.conf │ └── supervisord │ └── caddy.conf └── version.txt /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Postiz Dev Container", 3 | "image": "localhost/postiz-devcontainer", 4 | "features": {}, 5 | "customizations": { 6 | "vscode": { 7 | "settings": {}, 8 | "extensions": [] 9 | } 10 | }, 11 | "forwardPorts": ["4200:4200", "3000:3000"], 12 | "mounts": ["source=/apps,destination=/apps/dist/,type=bind,consistency=cached"] 13 | } 14 | 15 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # We want the docker builds to be clean, and as fast as possible. Don't send 2 | # any half-built stuff in the build context as a pre-caution (also saves copying 3 | # 180k files in node_modules that isn't used!). 4 | **/node_modules 5 | node_modules/* 6 | node_modules 7 | docker-data/* 8 | dist 9 | .nx 10 | /apps/frontend/.next 11 | /apps/backend/dist 12 | /apps/workers/dist 13 | /apps/cron/dist 14 | /apps/commands/dist 15 | .devcontainer 16 | **/.git 17 | **/*.md 18 | **/LICENSE 19 | **/npm-debug.log 20 | **/*.vscode 21 | .git 22 | .github 23 | reports -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.github/Dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "npm" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "daily" 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/01_installation.prolem.yml: -------------------------------------------------------------------------------- 1 | name: "🙏🏻 Installation Problem" 2 | description: "Report an issue with installation" 3 | title: "Installation Problem" 4 | labels: ["type: installation"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: For installation issues, please visit our [Discord Support](https://discord.postiz.com) for assistance. 9 | - type: textarea 10 | id: feature-description 11 | validations: 12 | required: true 13 | attributes: 14 | label: For installation issues, please visit our https://discord.postiz.com for assistance. 15 | description: For installation issues, please visit our [Discord Support](https://discord.postiz.com) for assistance. 16 | placeholder: | 17 | For installation issues, please visit our https://discord.postiz.com for assistance. 18 | Please do not save this issue - do not submit installation issues on GitHub. 19 | 20 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # What kind of change does this PR introduce? 2 | 3 | eg: Bug fix, feature, docs update, ... 4 | 5 | # Why was this change needed? 6 | 7 | Please link to related issues when possible, and explain WHY you changed things, not WHAT you changed. 8 | 9 | # Other information: 10 | 11 | eg: Did you discuss this change with anybody before working on it (not required, but can be a good idea for bigger changes). Any plans for the future, etc? 12 | 13 | # Checklist: 14 | 15 | Put a "X" in the boxes below to indicate you have followed the checklist; 16 | 17 | - [ ] I have read the [CONTRIBUTING](https://github.com/gitroomhq/postiz-app/blob/main/CONTRIBUTING.md) guide. 18 | - [ ] I checked that there were not similar issues or PRs already open for this. 19 | - [ ] This PR fixes just ONE issue (do not include multiple issues or types of change in the same PR) For example, don't try and fix a UI issue and include new dependencies in the same PR. 20 | -------------------------------------------------------------------------------- /.github/assets/gitroom-darkmode-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/.github/assets/gitroom-darkmode-logo.png -------------------------------------------------------------------------------- /.github/assets/gitroom-lightmode-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/.github/assets/gitroom-lightmode-logo.png -------------------------------------------------------------------------------- /.github/assets/gitroom-main-youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/.github/assets/gitroom-main-youtube.png -------------------------------------------------------------------------------- /.github/assets/screen-002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/.github/assets/screen-002.png -------------------------------------------------------------------------------- /.github/assets/screen-003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/.github/assets/screen-003.png -------------------------------------------------------------------------------- /.github/assets/screen-004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/.github/assets/screen-004.png -------------------------------------------------------------------------------- /.github/workflows/build-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Build Extension 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | submit: 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v4 12 | 13 | - uses: pnpm/action-setup@v4 14 | 15 | - uses: actions/setup-node@v4 16 | with: 17 | node-version: 20 18 | cache: 'pnpm' 19 | 20 | - name: Install dependencies 21 | run: pnpm install 22 | 23 | - name: Zip extensions 24 | run: FRONTEND_URL=https://platform.postiz.com pnpm run build:extension 25 | 26 | - name: Upload to Nextcloud 27 | env: 28 | NEXTCLOUD_URL: ${{ secrets.NEXTCLOUD_URL }} 29 | NEXTCLOUD_USERNAME: ${{ secrets.NEXTCLOUD_USERNAME }} 30 | NEXTCLOUD_PASSWORD: ${{ secrets.NEXTCLOUD_PASSWORD }} 31 | run: | 32 | curl -T apps/extension/extension.zip \ 33 | -u "$NEXTCLOUD_USERNAME:$NEXTCLOUD_PASSWORD" \ 34 | "$NEXTCLOUD_URL/extension.zip" 35 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Code Quality Analysis" 3 | 4 | on: 5 | push: 6 | branches: 7 | - dev1 8 | paths: 9 | - apps/** 10 | - '!apps/docs/**' 11 | - libraries/** 12 | 13 | jobs: 14 | analyze: 15 | name: Analyze (${{ matrix.language }}) 16 | 17 | runs-on: 'ubuntu-latest' 18 | permissions: 19 | security-events: write 20 | 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | include: 25 | - language: javascript-typescript 26 | build-mode: none 27 | 28 | steps: 29 | - name: Checkout repository 30 | uses: actions/checkout@v4 31 | 32 | - name: Initialize CodeQL 33 | uses: github/codeql-action/init@v3 34 | with: 35 | languages: ${{ matrix.language }} 36 | build-mode: ${{ matrix.build-mode }} 37 | 38 | - name: Perform CodeQL Analysis 39 | uses: github/codeql-action/analyze@v3 40 | with: 41 | category: "/language:${{matrix.language}}" 42 | -------------------------------------------------------------------------------- /.github/workflows/issue-label-triggers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Issue Label Triggers 3 | on: 4 | issues: 5 | types: 6 | - labeled 7 | 8 | jobs: 9 | closed-public-website: 10 | if: github.event.label.name == 'trigger-public-website' 11 | runs-on: ubuntu-latest 12 | permissions: 13 | issues: write 14 | steps: 15 | - name: Add comment 16 | run: gh issue comment "$NUMBER" --body "$BODY" && gh issue close "$NUMBER" 17 | env: 18 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 19 | GH_REPO: ${{ github.repository }} 20 | NUMBER: ${{ github.event.issue.number }} 21 | BODY: > 22 | This issue concerns the public website, which is not open source and is not part of this repository. 23 | 24 | 25 | If you have a question or concern about the content of the public website, please contact Nevo David. 26 | 27 | 28 | If you are looking to contribute to the open source Postiz project code, this is the correct repository, and we welcome your contributions in a new GitHub issue. 29 | -------------------------------------------------------------------------------- /.github/workflows/pr-docker-build.yml: -------------------------------------------------------------------------------- 1 | name: Build and Publish PR Docker Image 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened, synchronize] 6 | 7 | permissions: write-all 8 | 9 | jobs: 10 | build-and-publish: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v4 16 | 17 | - name: Log in to GitHub Container Registry 18 | uses: docker/login-action@v3 19 | with: 20 | registry: ghcr.io 21 | username: ${{ github.actor }} 22 | password: ${{ github.token }} 23 | 24 | - name: Set image tag 25 | id: vars 26 | run: echo "IMAGE_TAG=ghcr.io/gitroomhq/postiz-app-pr:${{ github.event.pull_request.number }}" >> $GITHUB_ENV 27 | 28 | - name: Build Docker image from Dockerfile.dev 29 | run: docker build -f Dockerfile.dev -t $IMAGE_TAG . 30 | 31 | - name: Push Docker image to GHCR 32 | run: docker push $IMAGE_TAG 33 | -------------------------------------------------------------------------------- /.github/workflows/publish-extension.yml: -------------------------------------------------------------------------------- 1 | name: Publish Extension 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | submit: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | 12 | - uses: pnpm/action-setup@v4 13 | 14 | - uses: actions/setup-node@v4 15 | with: 16 | node-version: 20 17 | cache: 'pnpm' 18 | 19 | - name: Install dependencies 20 | run: pnpm install 21 | 22 | - name: Zip extensions 23 | run: FRONTEND_URL=https://platform.postiz.com pnpm run build:extension 24 | 25 | - name: Publish to Chrome Web Store 26 | uses: mnao305/chrome-extension-upload@v5.0.0 27 | with: 28 | extension-id: ${{ secrets.CHROME_EXTENSION_ID }} 29 | client-id: ${{ secrets.CHROME_CLIENT_ID }} 30 | client-secret: ${{ secrets.CHROME_CLIENT_SECRET }} 31 | refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }} 32 | file-path: apps/extension/extension.zip -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | dist 5 | tmp 6 | /out-tsc 7 | .env 8 | # dependencies 9 | node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | .vscode/* 20 | 21 | # IDE - VSCode 22 | .vscode/* 23 | !.vscode/settings.json 24 | !.vscode/tasks.json 25 | !.vscode/launch.json 26 | !.vscode/extensions.json 27 | 28 | # misc 29 | /.sass-cache 30 | /connect.lock 31 | /coverage 32 | /libpeerconnection.log 33 | npm-debug.log 34 | yarn-error.log 35 | testem.log 36 | /typings 37 | 38 | # System Files 39 | .DS_Store 40 | Thumbs.db 41 | 42 | .nx/cache 43 | .nx/workspace-data 44 | 45 | # Next.js 46 | .next 47 | 48 | # Vim files 49 | **/*.swp 50 | **/*.swo 51 | 52 | # Temporary files 53 | *.orig 54 | *.~*~ 55 | *.tsbuildinfo 56 | 57 | # ignore Secrets folder 58 | .secrets/ 59 | libraries/plugins/src/plugins.ts 60 | i18n.cache 61 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libraries/plugins/src/list/public-api"] 2 | path = libraries/plugins/src/list/public-api 3 | url = git@github.com:gitroomhq/public-api.git 4 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | ignore-workspace-root-check=true 2 | node-linker=hoisted 3 | restrict-manifest-changes=true 4 | sync-injected-deps-after-scripts[]=build 5 | inject-workspace-packages=true -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Add files here to ignore them from prettier formatting 2 | /dist 3 | /coverage 4 | /.nx/cache -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /Dockerfile.dev: -------------------------------------------------------------------------------- 1 | FROM node:20-alpine3.19 2 | RUN apk add --no-cache g++ make py3-pip supervisor bash caddy 3 | RUN npm --no-update-notifier --no-fund --global install pnpm@10.6.1 pm2 4 | 5 | WORKDIR /app 6 | 7 | COPY . /app 8 | COPY var/docker/supervisord.conf /etc/supervisord.conf 9 | COPY var/docker/Caddyfile /app/Caddyfile 10 | COPY var/docker/entrypoint.sh /app/entrypoint.sh 11 | COPY var/docker/supervisord/caddy.conf /etc/supervisor.d/caddy.conf 12 | RUN chmod +x /app/entrypoint.sh 13 | 14 | RUN pnpm install 15 | RUN pnpm run build 16 | 17 | EXPOSE 4200 18 | 19 | CMD ["pnpm", "run", "pm2"] 20 | -------------------------------------------------------------------------------- /apps/backend/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | [._]*.s[a-v][a-z] 4 | [._]*.sw[a-p] 5 | [._]s[a-rt-v][a-z] 6 | [._]ss[a-gi-z] 7 | [._]sw[a-p] 8 | 9 | -------------------------------------------------------------------------------- /apps/backend/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "typescript", 5 | "tsx": false, 6 | "decorators": true, 7 | "dynamicImport": true 8 | }, 9 | "target": "es2020", 10 | "baseUrl": "/Users/nevodavid/Projects/gitroom", 11 | "paths": { 12 | "@gitroom/backend/*": ["apps/backend/src/*"], 13 | "@gitroom/cron/*": ["apps/cron/src/*"], 14 | "@gitroom/frontend/*": ["apps/frontend/src/*"], 15 | "@gitroom/helpers/*": ["libraries/helpers/src/*"], 16 | "@gitroom/nestjs-libraries/*": ["libraries/nestjs-libraries/src/*"], 17 | "@gitroom/react/*": ["libraries/react-shared-libraries/src/*"], 18 | "@gitroom/plugins/*": ["libraries/plugins/src/*"], 19 | "@gitroom/workers/*": ["apps/workers/src/*"], 20 | "@gitroom/extension/*": ["apps/extension/src/*"] 21 | }, 22 | "keepClassNames": true, 23 | "transform": { 24 | "legacyDecorator": true, 25 | "decoratorMetadata": true 26 | }, 27 | "loose": true 28 | }, 29 | "module": { 30 | "type": "commonjs", 31 | "strict": false, 32 | "strictMode": true, 33 | "lazy": false, 34 | "noInterop": false 35 | }, 36 | "sourceMaps": true, 37 | "minify": false 38 | } -------------------------------------------------------------------------------- /apps/backend/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "monorepo": false, 5 | "sourceRoot": "src", 6 | "entryFile": "../../dist/backend/apps/backend/src/main", 7 | "language": "ts", 8 | "generateOptions": { 9 | "spec": false 10 | }, 11 | "compilerOptions": { 12 | "manualRestart": true, 13 | "tsConfigPath": "./tsconfig.build.json", 14 | "webpack": false, 15 | "deleteOutDir": true, 16 | "assets": [], 17 | "watchAssets": false, 18 | "plugins": [] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postiz-backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "dev": "dotenv -e ../../.env -- nest start --watch --entryFile=./apps/backend/src/main", 7 | "build": "NODE_ENV=production nest build", 8 | "start": "dotenv -e ../../.env -- node ./dist/apps/backend/src/main.js", 9 | "pm2": "pm2 start pnpm --name backend -- start" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC" 14 | } 15 | -------------------------------------------------------------------------------- /apps/backend/src/api/routes/root.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get } from '@nestjs/common'; 2 | @Controller('/') 3 | export class RootController { 4 | @Get('/') 5 | getRoot(): string { 6 | return 'App is running!'; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/backend/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/backend/src/assets/.gitkeep -------------------------------------------------------------------------------- /apps/backend/src/mcp/mcp.module.ts: -------------------------------------------------------------------------------- 1 | import { Global, Module } from '@nestjs/common'; 2 | import { MainMcp } from '@gitroom/backend/mcp/main.mcp'; 3 | 4 | @Global() 5 | @Module({ 6 | imports: [], 7 | controllers: [], 8 | providers: [MainMcp], 9 | get exports() { 10 | return [...this.providers]; 11 | }, 12 | }) 13 | export class McpModule {} 14 | -------------------------------------------------------------------------------- /apps/backend/src/services/auth/permissions/permissions.ability.ts: -------------------------------------------------------------------------------- 1 | import { SetMetadata } from '@nestjs/common'; 2 | import { 3 | AuthorizationActions, 4 | Sections, 5 | } from '@gitroom/backend/services/auth/permissions/permissions.service'; 6 | 7 | export const CHECK_POLICIES_KEY = 'check_policy'; 8 | export type AbilityPolicy = [AuthorizationActions, Sections]; 9 | export const CheckPolicies = (...handlers: AbilityPolicy[]) => 10 | SetMetadata(CHECK_POLICIES_KEY, handlers); 11 | -------------------------------------------------------------------------------- /apps/backend/src/services/auth/providers.interface.ts: -------------------------------------------------------------------------------- 1 | export interface ProvidersInterface { 2 | generateLink(query?: any): Promise | string; 3 | getToken(code: string): Promise; 4 | getUser( 5 | providerToken: string 6 | ): Promise<{ email: string; id: string }> | false; 7 | } 8 | -------------------------------------------------------------------------------- /apps/backend/src/services/auth/providers/providers.factory.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from '@prisma/client'; 2 | import { GithubProvider } from '@gitroom/backend/services/auth/providers/github.provider'; 3 | import { ProvidersInterface } from '@gitroom/backend/services/auth/providers.interface'; 4 | import { GoogleProvider } from '@gitroom/backend/services/auth/providers/google.provider'; 5 | import { FarcasterProvider } from '@gitroom/backend/services/auth/providers/farcaster.provider'; 6 | import { WalletProvider } from '@gitroom/backend/services/auth/providers/wallet.provider'; 7 | import { OauthProvider } from '@gitroom/backend/services/auth/providers/oauth.provider'; 8 | 9 | export class ProvidersFactory { 10 | static loadProvider(provider: Provider): ProvidersInterface { 11 | switch (provider) { 12 | case Provider.GITHUB: 13 | return new GithubProvider(); 14 | case Provider.GOOGLE: 15 | return new GoogleProvider(); 16 | case Provider.FARCASTER: 17 | return new FarcasterProvider(); 18 | case Provider.WALLET: 19 | return new WalletProvider(); 20 | case Provider.GENERIC: 21 | return new OauthProvider(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /apps/backend/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"], 4 | "compilerOptions": { 5 | "module": "CommonJS", 6 | "resolveJsonModule": true, 7 | "declaration": true, 8 | "removeComments": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "allowSyntheticDefaultImports": true, 12 | "target": "ES2021", 13 | "sourceMap": true, 14 | "incremental": true, 15 | "skipLibCheck": true, 16 | "strictNullChecks": false, 17 | "noImplicitAny": false, 18 | "strictBindCallApply": false, 19 | "forceConsistentCasingInFileNames": false, 20 | "noFallthroughCasesInSwitch": false, 21 | "outDir": "./dist" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /apps/backend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "declaration": true, 6 | "removeComments": true, 7 | "allowSyntheticDefaultImports": true, 8 | "target": "es2017", 9 | "sourceMap": true, 10 | "esModuleInterop": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/commands/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | [._]*.s[a-v][a-z] 4 | [._]*.sw[a-p] 5 | [._]s[a-rt-v][a-z] 6 | [._]ss[a-gi-z] 7 | [._]sw[a-p] 8 | 9 | -------------------------------------------------------------------------------- /apps/commands/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "monorepo": false, 5 | "sourceRoot": "src", 6 | "entryFile": "../../dist/commands/apps/commands/src/main", 7 | "language": "ts", 8 | "generateOptions": { 9 | "spec": false 10 | }, 11 | "compilerOptions": { 12 | "manualRestart": true, 13 | "tsConfigPath": "./tsconfig.build.json", 14 | "webpack": false, 15 | "deleteOutDir": true, 16 | "assets": [], 17 | "watchAssets": false, 18 | "plugins": [] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/commands/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postiz-command", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "dev": "dotenv -e ../../.env -- nest start --watch --entryFile=./apps/command/src/main", 7 | "build": "NODE_ENV=production nest build", 8 | "start": "node ./dist/apps/command/src/main.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC" 13 | } 14 | -------------------------------------------------------------------------------- /apps/commands/src/command.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { CommandModule as ExternalCommandModule } from 'nestjs-command'; 3 | import { CheckStars } from './tasks/check.stars'; 4 | import { DatabaseModule } from '@gitroom/nestjs-libraries/database/prisma/database.module'; 5 | import { RefreshTokens } from './tasks/refresh.tokens'; 6 | import { BullMqModule } from '@gitroom/nestjs-libraries/bull-mq-transport-new/bull.mq.module'; 7 | import { ConfigurationTask } from './tasks/configuration'; 8 | import { AgentRun } from './tasks/agent.run'; 9 | import { AgentModule } from '@gitroom/nestjs-libraries/agent/agent.module'; 10 | 11 | @Module({ 12 | imports: [ExternalCommandModule, DatabaseModule, BullMqModule, AgentModule], 13 | controllers: [], 14 | providers: [CheckStars, RefreshTokens, ConfigurationTask, AgentRun], 15 | get exports() { 16 | return [...this.imports, ...this.providers]; 17 | }, 18 | }) 19 | export class CommandModule {} 20 | -------------------------------------------------------------------------------- /apps/commands/src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from '@nestjs/core'; 2 | import { CommandModule } from './command.module'; 3 | import { CommandService } from 'nestjs-command'; 4 | 5 | async function bootstrap() { 6 | // some comment again 7 | const app = await NestFactory.createApplicationContext(CommandModule, { 8 | logger: ['error'], 9 | }); 10 | 11 | try { 12 | await app.select(CommandModule).get(CommandService).exec(); 13 | await app.close(); 14 | } catch (error) { 15 | console.error(error); 16 | await app.close(); 17 | process.exit(1); 18 | } 19 | } 20 | 21 | bootstrap(); 22 | -------------------------------------------------------------------------------- /apps/commands/src/tasks/agent.run.ts: -------------------------------------------------------------------------------- 1 | import { Command } from 'nestjs-command'; 2 | import { Injectable } from '@nestjs/common'; 3 | import { AgentGraphService } from '@gitroom/nestjs-libraries/agent/agent.graph.service'; 4 | 5 | @Injectable() 6 | export class AgentRun { 7 | constructor(private _agentGraphService: AgentGraphService) {} 8 | @Command({ 9 | command: 'run:agent', 10 | describe: 'Run the agent', 11 | }) 12 | async agentRun() { 13 | console.log(await this._agentGraphService.createGraph('hello', true)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /apps/commands/src/tasks/configuration.ts: -------------------------------------------------------------------------------- 1 | import { Command } from 'nestjs-command'; 2 | import { Injectable } from '@nestjs/common'; 3 | import { ConfigurationChecker } from '@gitroom/helpers/configuration/configuration.checker'; 4 | 5 | @Injectable() 6 | export class ConfigurationTask { 7 | @Command({ 8 | command: 'config:check', 9 | describe: 'Checks your configuration (.env) file for issues.', 10 | }) 11 | create() { 12 | const checker = new ConfigurationChecker(); 13 | checker.readEnvFromProcess(); 14 | checker.check(); 15 | 16 | if (checker.hasIssues()) { 17 | for (const issue of checker.getIssues()) { 18 | console.warn('Configuration issue:', issue); 19 | } 20 | 21 | console.error( 22 | 'Configuration check complete, issues: ', 23 | checker.getIssuesCount() 24 | ); 25 | } else { 26 | console.log('Configuration check complete, no issues found.'); 27 | } 28 | 29 | console.log('Press Ctrl+C to exit.'); 30 | return true; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /apps/commands/src/tasks/refresh.tokens.ts: -------------------------------------------------------------------------------- 1 | import { Command } from 'nestjs-command'; 2 | import { Injectable } from '@nestjs/common'; 3 | import { IntegrationService } from '@gitroom/nestjs-libraries/database/prisma/integrations/integration.service'; 4 | 5 | @Injectable() 6 | export class RefreshTokens { 7 | constructor(private _integrationService: IntegrationService) {} 8 | @Command({ 9 | command: 'refresh', 10 | describe: 'Refresh all tokens', 11 | }) 12 | async refresh() { 13 | await this._integrationService.refreshTokens(); 14 | return true; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apps/commands/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"], 4 | "compilerOptions": { 5 | "module": "CommonJS", 6 | "resolveJsonModule": true, 7 | "declaration": true, 8 | "removeComments": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "allowSyntheticDefaultImports": true, 12 | "target": "ES2021", 13 | "sourceMap": true, 14 | "incremental": true, 15 | "skipLibCheck": true, 16 | "strictNullChecks": false, 17 | "noImplicitAny": false, 18 | "strictBindCallApply": false, 19 | "forceConsistentCasingInFileNames": false, 20 | "noFallthroughCasesInSwitch": false, 21 | "outDir": "./dist" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /apps/commands/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "declaration": true, 6 | "removeComments": true, 7 | "allowSyntheticDefaultImports": true, 8 | "target": "es2017", 9 | "sourceMap": true, 10 | "esModuleInterop": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/cron/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | [._]*.s[a-v][a-z] 4 | [._]*.sw[a-p] 5 | [._]s[a-rt-v][a-z] 6 | [._]ss[a-gi-z] 7 | [._]sw[a-p] 8 | 9 | -------------------------------------------------------------------------------- /apps/cron/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "typescript", 5 | "tsx": false, 6 | "decorators": true, 7 | "dynamicImport": true 8 | }, 9 | "target": "es2020", 10 | "baseUrl": "/Users/nevodavid/Projects/gitroom", 11 | "paths": { 12 | "@gitroom/backend/*": ["apps/backend/src/*"], 13 | "@gitroom/cron/*": ["apps/cron/src/*"], 14 | "@gitroom/frontend/*": ["apps/frontend/src/*"], 15 | "@gitroom/helpers/*": ["libraries/helpers/src/*"], 16 | "@gitroom/nestjs-libraries/*": ["libraries/nestjs-libraries/src/*"], 17 | "@gitroom/react/*": ["libraries/react-shared-libraries/src/*"], 18 | "@gitroom/plugins/*": ["libraries/plugins/src/*"], 19 | "@gitroom/workers/*": ["apps/workers/src/*"], 20 | "@gitroom/extension/*": ["apps/extension/src/*"] 21 | }, 22 | "keepClassNames": true, 23 | "transform": { 24 | "legacyDecorator": true, 25 | "decoratorMetadata": true 26 | }, 27 | "loose": true 28 | }, 29 | "module": { 30 | "type": "commonjs", 31 | "strict": false, 32 | "strictMode": true, 33 | "lazy": false, 34 | "noInterop": false 35 | }, 36 | "sourceMaps": true, 37 | "minify": false 38 | } -------------------------------------------------------------------------------- /apps/cron/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "monorepo": false, 5 | "sourceRoot": "src", 6 | "entryFile": "../../dist/cron/apps/cron/src/main", 7 | "language": "ts", 8 | "generateOptions": { 9 | "spec": false 10 | }, 11 | "compilerOptions": { 12 | "manualRestart": true, 13 | "tsConfigPath": "./tsconfig.build.json", 14 | "webpack": false, 15 | "deleteOutDir": true, 16 | "assets": [], 17 | "watchAssets": false, 18 | "plugins": [] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/cron/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postiz-cron", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "dev": "dotenv -e ../../.env -- nest start --watch --entryFile=./apps/cron/src/main", 7 | "build": "NODE_ENV=production nest build", 8 | "start": "dotenv -e ../../.env -- node ./dist/apps/cron/src/main.js", 9 | "pm2": "pm2 start pnpm --name cron -- start" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC" 14 | } 15 | -------------------------------------------------------------------------------- /apps/cron/src/cron.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { ScheduleModule } from '@nestjs/schedule'; 3 | import { CheckStars } from '@gitroom/cron/tasks/check.stars'; 4 | import { DatabaseModule } from '@gitroom/nestjs-libraries/database/prisma/database.module'; 5 | import { SyncTrending } from '@gitroom/cron/tasks/sync.trending'; 6 | import { BullMqModule } from '@gitroom/nestjs-libraries/bull-mq-transport-new/bull.mq.module'; 7 | 8 | @Module({ 9 | imports: [DatabaseModule, ScheduleModule.forRoot(), BullMqModule], 10 | controllers: [], 11 | providers: [...(!process.env.IS_GENERAL ? [CheckStars, SyncTrending] : [])], 12 | }) 13 | export class CronModule {} 14 | -------------------------------------------------------------------------------- /apps/cron/src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from '@nestjs/core'; 2 | import { CronModule } from './cron.module'; 3 | 4 | async function bootstrap() { 5 | // some comment again 6 | await NestFactory.createApplicationContext(CronModule); 7 | } 8 | 9 | bootstrap(); 10 | -------------------------------------------------------------------------------- /apps/cron/src/tasks/check.stars.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { Cron } from '@nestjs/schedule'; 3 | import { StarsService } from '@gitroom/nestjs-libraries/database/prisma/stars/stars.service'; 4 | import { BullMqClient } from '@gitroom/nestjs-libraries/bull-mq-transport-new/client'; 5 | 6 | @Injectable() 7 | export class CheckStars { 8 | constructor( 9 | private _starsService: StarsService, 10 | private _workerServiceProducer: BullMqClient 11 | ) {} 12 | @Cron('30 0 * * *') 13 | async checkStars() { 14 | const allGitHubRepositories = 15 | await this._starsService.getAllGitHubRepositories(); 16 | 17 | for (const repository of allGitHubRepositories) { 18 | this._workerServiceProducer.emit('check_stars', { 19 | payload: { login: repository.login }, 20 | }); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /apps/cron/src/tasks/sync.trending.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { Cron } from '@nestjs/schedule'; 3 | import { BullMqClient } from '@gitroom/nestjs-libraries/bull-mq-transport-new/client'; 4 | 5 | @Injectable() 6 | export class SyncTrending { 7 | constructor(private _workerServiceProducer: BullMqClient) {} 8 | @Cron('0 * * * *') 9 | async syncTrending() { 10 | this._workerServiceProducer.emit('sync_trending', {}).subscribe(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/cron/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"], 4 | "compilerOptions": { 5 | "module": "CommonJS", 6 | "resolveJsonModule": true, 7 | "declaration": true, 8 | "removeComments": true, 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "allowSyntheticDefaultImports": true, 12 | "target": "ES2021", 13 | "sourceMap": true, 14 | "incremental": true, 15 | "skipLibCheck": true, 16 | "strictNullChecks": false, 17 | "noImplicitAny": false, 18 | "strictBindCallApply": false, 19 | "forceConsistentCasingInFileNames": false, 20 | "noFallthroughCasesInSwitch": false, 21 | "outDir": "./dist" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /apps/cron/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "declaration": true, 6 | "removeComments": true, 7 | "allowSyntheticDefaultImports": true, 8 | "noLib": false, 9 | "target": "ES2021", 10 | "sourceMap": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/extension/manifest.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "action": { 3 | "default_icon": "public/dev-icon-32.png", 4 | "default_popup": "src/pages/popup/index.html" 5 | }, 6 | "icons": { 7 | "128": "public/dev-icon-128.png" 8 | }, 9 | "web_accessible_resources": [ 10 | { 11 | "resources": ["contentStyle.css", "dev-icon-128.png", "dev-icon-32.png"], 12 | "matches": [] 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /apps/extension/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 3, 3 | "name": "Postiz", 4 | "description": "Your ultimate social media scheduling tool", 5 | "options_ui": { 6 | "page": "src/pages/options/index.html" 7 | }, 8 | "action": { 9 | "default_popup": "src/pages/popup/index.html", 10 | "default_icon": { 11 | "32": "icon-32.png" 12 | } 13 | }, 14 | "icons": { 15 | "128": "icon-128.png" 16 | }, 17 | "permissions": ["activeTab", "cookies", "tabs"], 18 | "content_scripts": [ 19 | { 20 | "matches": ["http://*/*", "https://*/*", ""], 21 | "js": ["src/pages/content/index.tsx"], 22 | "css": ["contentStyle.css"] 23 | } 24 | ], 25 | "web_accessible_resources": [ 26 | { 27 | "resources": ["contentStyle.css", "icon-128.png", "icon-32.png"], 28 | "matches": [] 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /apps/extension/nodemon.chrome.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "__DEV__": "true" 4 | }, 5 | "watch": [ 6 | "src", 7 | "utils", 8 | "vite.config.base.ts", 9 | "vite.config.chrome.ts", 10 | "manifest.json", 11 | "manifest.dev.json" 12 | ], 13 | "ext": "tsx,css,html,ts,json", 14 | "ignore": ["src/**/*.spec.ts"], 15 | "exec": "vite build --config vite.config.chrome.ts --mode development" 16 | } 17 | -------------------------------------------------------------------------------- /apps/extension/nodemon.firefox.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "__DEV__": "true" 4 | }, 5 | "watch": [ 6 | "src", 7 | "utils", 8 | "vite.config.base.ts", 9 | "vite.config.firefox.ts", 10 | "manifest.json", 11 | "manifest.dev.json" 12 | ], 13 | "ext": "tsx,css,html,ts,json", 14 | "ignore": ["src/**/*.spec.ts"], 15 | "exec": "vite build --config vite.config.firefox.ts --mode development" 16 | } 17 | -------------------------------------------------------------------------------- /apps/extension/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postiz-extension", 3 | "version": "1.0.3", 4 | "description": "A simple chrome & firefox extension template with Vite, React, TypeScript and Tailwind CSS.", 5 | "scripts": { 6 | "build": "rm -rf dist && vite build --config vite.config.chrome.ts && zip -r extension.zip dist", 7 | "build:chrome": "vite build --config vite.config.chrome.ts", 8 | "build:firefox": "vite build --config vite.config.firefox.ts", 9 | "dev": "rm -rf dist && dotenv -e ../../.env -- vite build --config vite.config.chrome.ts --mode development --watch", 10 | "dev:chrome": "nodemon --config nodemon.chrome.json", 11 | "dev:firefox": "nodemon --config nodemon.firefox.json" 12 | }, 13 | "type": "module" 14 | } 15 | -------------------------------------------------------------------------------- /apps/extension/public/contentStyle.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/extension/public/contentStyle.css -------------------------------------------------------------------------------- /apps/extension/public/dev-icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/extension/public/dev-icon-128.png -------------------------------------------------------------------------------- /apps/extension/public/dev-icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/extension/public/dev-icon-32.png -------------------------------------------------------------------------------- /apps/extension/public/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/extension/public/icon-128.png -------------------------------------------------------------------------------- /apps/extension/public/icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/extension/public/icon-32.png -------------------------------------------------------------------------------- /apps/extension/src/assets/styles/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @theme { 6 | --animate-spin-slow: spin 20s linear infinite; 7 | 8 | @keyframes spin { 9 | to { 10 | transform: rotate(360deg); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /apps/extension/src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.svg' { 2 | import React = require('react'); 3 | export const ReactComponent: React.SFC>; 4 | const src: string; 5 | export default src; 6 | } 7 | 8 | declare module '*.json' { 9 | const content: string; 10 | export default content; 11 | } 12 | -------------------------------------------------------------------------------- /apps/extension/src/locales/en/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "extName": { 3 | "message": "name in src/locales/en/messages.json", 4 | "description": "Extension name" 5 | }, 6 | "extDescription": { 7 | "message": "description in src/locales/en/messages.json", 8 | "description": "Extension description" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/extension/src/pages/background/index.ts: -------------------------------------------------------------------------------- 1 | import { fetchRequestUtil } from '@gitroom/extension/utils/request.util'; 2 | 3 | const isDevelopment = process.env.NODE_ENV === 'development'; 4 | 5 | chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { 6 | if (request.action === 'makeHttpRequest') { 7 | fetchRequestUtil(request).then((response) => { 8 | sendResponse(response); 9 | }); 10 | } 11 | 12 | if (request.action === 'loadStorage') { 13 | chrome.storage.local.get([request.key], function (storage) { 14 | sendResponse(storage[request.key]); 15 | }); 16 | } 17 | 18 | if (request.action === 'saveStorage') { 19 | chrome.storage.local.set({ [request.key]: request.value }, function () { 20 | sendResponse({ success: true }); 21 | }); 22 | } 23 | 24 | if (request.action === 'loadCookie') { 25 | chrome.cookies.get( 26 | { 27 | url: import.meta.env?.FRONTEND_URL || process?.env?.FRONTEND_URL, 28 | name: request.cookieName, 29 | }, 30 | function (cookies) { 31 | sendResponse(cookies?.value); 32 | } 33 | ); 34 | } 35 | 36 | return true; 37 | }); 38 | -------------------------------------------------------------------------------- /apps/extension/src/pages/content/index.tsx: -------------------------------------------------------------------------------- 1 | import { createRoot } from 'react-dom/client'; 2 | import './style.css'; 3 | import { MainContent } from '@gitroom/extension/pages/content/main.content'; 4 | const div = document.createElement('div'); 5 | div.id = '__root'; 6 | document.body.appendChild(div); 7 | 8 | const rootContainer = document.querySelector('#__root'); 9 | if (!rootContainer) throw new Error("Can't find Content root element"); 10 | const root = createRoot(rootContainer); 11 | root.render(); 12 | -------------------------------------------------------------------------------- /apps/extension/src/pages/content/style.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | .my-wrapper { 6 | left: 0 !important; 7 | top: 0 !important; 8 | position: fixed !important; 9 | width: 100% !important; 10 | height: 100% !important; 11 | z-index: 999999 !important; 12 | display: flex !important; 13 | justify-content: center !important; 14 | background: rgba(0, 0, 0, 0.5) !important; 15 | } 16 | 17 | .my-wrapper > div { 18 | background: white !important; 19 | width: 600px !important; 20 | height: 300px !important; 21 | border-radius: 10px !important; 22 | display: flex !important; 23 | flex-direction: column !important; 24 | justify-items: center !important; 25 | margin-top: 100px !important; 26 | color: black !important; 27 | } 28 | -------------------------------------------------------------------------------- /apps/extension/src/pages/options/Options.css: -------------------------------------------------------------------------------- 1 | .container { 2 | width: 100%; 3 | height: 50vh; 4 | font-size: 2rem; 5 | display: flex; 6 | align-items: center; 7 | justify-content: center; 8 | } 9 | -------------------------------------------------------------------------------- /apps/extension/src/pages/options/Options.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import '@gitroom/extension/pages/options/Options.css'; 3 | 4 | export default function Options() { 5 | return
Options
; 6 | } 7 | -------------------------------------------------------------------------------- /apps/extension/src/pages/options/index.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/extension/src/pages/options/index.css -------------------------------------------------------------------------------- /apps/extension/src/pages/options/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Options 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /apps/extension/src/pages/options/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import '@gitroom/extension/pages/options/index.css'; 4 | import Options from '@gitroom/extension/pages/options/Options'; 5 | 6 | function init() { 7 | const rootContainer = document.querySelector('#__root'); 8 | if (!rootContainer) throw new Error("Can't find Options root element"); 9 | const root = createRoot(rootContainer); 10 | root.render(); 11 | } 12 | 13 | init(); 14 | -------------------------------------------------------------------------------- /apps/extension/src/pages/panel/Panel.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #242424; 3 | } 4 | 5 | .container { 6 | color: #ffffff; 7 | } 8 | -------------------------------------------------------------------------------- /apps/extension/src/pages/panel/Panel.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import '@pages/panel/Panel.css'; 3 | 4 | export default function Panel() { 5 | return ( 6 |
7 |

Side Panel

8 |
9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /apps/extension/src/pages/panel/index.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/extension/src/pages/panel/index.css -------------------------------------------------------------------------------- /apps/extension/src/pages/panel/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Devtools Panel 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /apps/extension/src/pages/panel/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import Panel from '@pages/panel/Panel'; 4 | import '@pages/panel/index.css'; 5 | import '@assets/styles/tailwind.css'; 6 | 7 | function init() { 8 | const rootContainer = document.querySelector('#__root'); 9 | if (!rootContainer) throw new Error("Can't find Panel root element"); 10 | const root = createRoot(rootContainer); 11 | root.render(); 12 | } 13 | 14 | init(); 15 | -------------------------------------------------------------------------------- /apps/extension/src/pages/popup/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | body { 6 | width: 300px; 7 | height: 260px; 8 | margin: 0; 9 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 10 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 11 | sans-serif; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | 15 | position: relative; 16 | } 17 | -------------------------------------------------------------------------------- /apps/extension/src/pages/popup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Popup 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /apps/extension/src/pages/popup/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import './index.css'; 4 | import '@gitroom/extension/assets/styles/tailwind.css'; 5 | import Popup from '@gitroom/extension/pages/popup/Popup'; 6 | 7 | function init() { 8 | const rootContainer = document.querySelector('#__root'); 9 | if (!rootContainer) throw new Error("Can't find Popup root element"); 10 | const root = createRoot(rootContainer); 11 | root.render(); 12 | } 13 | 14 | init(); 15 | -------------------------------------------------------------------------------- /apps/extension/src/providers/list/linkedin.provider.ts: -------------------------------------------------------------------------------- 1 | import { ProviderInterface } from '@gitroom/extension/providers/provider.interface'; 2 | 3 | export class LinkedinProvider implements ProviderInterface { 4 | identifier = 'linkedin'; 5 | baseUrl = 'https://www.linkedin.com'; 6 | element = `.share-box-feed-entry__closed-share-box`; 7 | attachTo = `[role="main"]`; 8 | style = 'light' as 'light'; 9 | findIdentifier = (element: HTMLElement) => { 10 | return element.closest('[data-urn]').getAttribute('data-urn'); 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /apps/extension/src/providers/list/x.provider.ts: -------------------------------------------------------------------------------- 1 | import { ProviderInterface } from '@gitroom/extension/providers/provider.interface'; 2 | 3 | export class XProvider implements ProviderInterface { 4 | identifier = 'x'; 5 | baseUrl = 'https://x.com'; 6 | element = `[data-testid="primaryColumn"]:has([data-testid="toolBar"]) [data-testid="tweetTextarea_0_label"], [data-testid="SideNav_NewTweet_Button"]`; 7 | attachTo = `#react-root`; 8 | style = 'dark' as 'dark'; 9 | findIdentifier = (element: HTMLElement) => { 10 | return ( 11 | Array.from( 12 | ( 13 | element?.closest('article') || 14 | element?.closest(`[aria-labelledby="modal-header"]`) 15 | )?.querySelectorAll('a') || [] 16 | ) 17 | ?.find((p) => { 18 | return p?.getAttribute('href')?.includes('/status/'); 19 | }) 20 | ?.getAttribute('href') 21 | ?.split('/status/')?.[1] || window.location.href.split('/status/')?.[1] 22 | ); 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /apps/extension/src/providers/provider.interface.ts: -------------------------------------------------------------------------------- 1 | export interface ProviderInterface { 2 | identifier: string; 3 | baseUrl: string; 4 | element: string; 5 | findIdentifier: (element: HTMLElement) => string; 6 | attachTo: string; 7 | style: 'dark' | 'light'; 8 | } 9 | -------------------------------------------------------------------------------- /apps/extension/src/providers/provider.list.ts: -------------------------------------------------------------------------------- 1 | import { XProvider } from './list/x.provider'; 2 | import { ProviderInterface } from './provider.interface'; 3 | import { LinkedinProvider } from './list/linkedin.provider'; 4 | 5 | export const ProviderList = [ 6 | new XProvider(), 7 | new LinkedinProvider(), 8 | ] satisfies ProviderInterface[] as ProviderInterface[]; 9 | -------------------------------------------------------------------------------- /apps/extension/src/utils/load.cookie.ts: -------------------------------------------------------------------------------- 1 | export const fetchCookie = (cookieName: string) => { 2 | return chrome.runtime.sendMessage({ 3 | action: 'loadCookie', 4 | cookieName, 5 | }); 6 | }; 7 | 8 | export const getCookie = async ( 9 | cookies: chrome.cookies.Cookie[], 10 | cookie: string 11 | ) => { 12 | // return cookies.find((c) => c.name === cookie).value; 13 | }; 14 | -------------------------------------------------------------------------------- /apps/extension/src/utils/load.storage.ts: -------------------------------------------------------------------------------- 1 | export const fetchStorage = (key: string) => { 2 | return chrome.runtime.sendMessage({ 3 | action: 'loadStorage', 4 | key, 5 | }); 6 | }; 7 | -------------------------------------------------------------------------------- /apps/extension/src/utils/request.util.ts: -------------------------------------------------------------------------------- 1 | const isDev = process.env.NODE_ENV === 'development'; 2 | export const sendRequest = ( 3 | auth: string, 4 | url: string, 5 | method: 'GET' | 'POST', 6 | body?: string 7 | ) => { 8 | return chrome.runtime.sendMessage({ 9 | action: 'makeHttpRequest', 10 | url, 11 | method, 12 | body, 13 | auth, 14 | }); 15 | }; 16 | 17 | export const fetchRequestUtil = async (request: any) => { 18 | return ( 19 | await fetch( 20 | (import.meta.env?.FRONTEND_URL || process?.env?.FRONTEND_URL) + 21 | request.url, 22 | { 23 | method: request.method || 'GET', 24 | headers: { 25 | 'Content-Type': 'application/json', 26 | Authorization: request.auth, 27 | // Add any auth headers here if needed 28 | }, 29 | ...(request.body ? { body: request.body } : {}), 30 | } 31 | ) 32 | ).json(); 33 | }; 34 | -------------------------------------------------------------------------------- /apps/extension/src/utils/save.storage.ts: -------------------------------------------------------------------------------- 1 | export const saveStorage = (key: string, value: any) => { 2 | return chrome.runtime.sendMessage({ 3 | action: 'saveStorage', 4 | key, 5 | value, 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /apps/extension/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /apps/extension/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "types": ["vite/client", "node", "chrome"], 6 | "lib": ["dom", "dom.iterable", "esnext"], 7 | "allowJs": false, 8 | "skipLibCheck": true, 9 | "esModuleInterop": true, 10 | "allowSyntheticDefaultImports": true, 11 | "strict": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "module": "esnext", 15 | "moduleResolution": "bundler", 16 | "resolveJsonModule": true, 17 | "noEmit": true, 18 | "jsx": "react-jsx" 19 | }, 20 | "include": [ 21 | "src", 22 | "utils", 23 | "vite.config.base.ts", 24 | "vite.config.chrome.ts", 25 | "vite.config.firefox.ts" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /apps/extension/vite.config.firefox.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'path'; 2 | import { mergeConfig, defineConfig } from 'vite'; 3 | import { crx, ManifestV3Export } from '@crxjs/vite-plugin'; 4 | import baseConfig, { baseManifest, baseBuildOptions } from './vite.config.base'; 5 | 6 | const outDir = resolve(__dirname, 'dist_firefox'); 7 | 8 | export default mergeConfig( 9 | baseConfig, 10 | defineConfig({ 11 | plugins: [ 12 | crx({ 13 | manifest: { 14 | ...baseManifest, 15 | background: { 16 | scripts: ['src/pages/background/index.ts'], 17 | }, 18 | } as ManifestV3Export, 19 | browser: 'firefox', 20 | contentScripts: { 21 | injectCss: true, 22 | }, 23 | }), 24 | ], 25 | build: { 26 | ...baseBuildOptions, 27 | outDir, 28 | }, 29 | publicDir: resolve(__dirname, 'public'), 30 | }) 31 | ); 32 | -------------------------------------------------------------------------------- /apps/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env* 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | -------------------------------------------------------------------------------- /apps/frontend/next.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | /** @type {import('next').NextConfig} */ 3 | const nextConfig = { 4 | experimental: { 5 | proxyTimeout: 90_000, 6 | }, 7 | reactStrictMode: false, 8 | transpilePackages: ['crypto-hash'], 9 | images: { 10 | remotePatterns: [ 11 | { 12 | protocol: 'http', 13 | hostname: '**', 14 | }, 15 | { 16 | protocol: 'https', 17 | hostname: '**', 18 | }, 19 | ], 20 | }, 21 | async redirects() { 22 | return [ 23 | { 24 | source: '/api/uploads/:path*', 25 | destination: 26 | process.env.STORAGE_PROVIDER === 'local' ? '/uploads/:path*' : '/404', 27 | permanent: true, 28 | }, 29 | ]; 30 | }, 31 | async rewrites() { 32 | return [ 33 | { 34 | source: '/uploads/:path*', 35 | destination: 36 | process.env.STORAGE_PROVIDER === 'local' 37 | ? '/api/uploads/:path*' 38 | : '/404', 39 | }, 40 | ]; 41 | }, 42 | }; 43 | export default nextConfig; 44 | -------------------------------------------------------------------------------- /apps/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postiz-frontend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "dotenv -e ../../.env -- next dev -p 4200", 8 | "build": "next build", 9 | "start": "dotenv -e ../../.env -- next start -p 4200", 10 | "pm2": "pm2 start pnpm --name frontend -- start" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC" 15 | } 16 | -------------------------------------------------------------------------------- /apps/frontend/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /apps/frontend/public/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/.gitkeep -------------------------------------------------------------------------------- /apps/frontend/public/auth/bg-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/auth/bg-login.png -------------------------------------------------------------------------------- /apps/frontend/public/auth/login-box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/auth/login-box.png -------------------------------------------------------------------------------- /apps/frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/favicon.ico -------------------------------------------------------------------------------- /apps/frontend/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/favicon.png -------------------------------------------------------------------------------- /apps/frontend/public/form/checked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /apps/frontend/public/icons/generic-oauth.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/bluesky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/bluesky.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/devto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/devto.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/discord.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/discord.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/dribbble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/dribbble.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/facebook.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/hashnode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/hashnode.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/instagram-standalone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/instagram-standalone.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/instagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/instagram.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/lemmy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/lemmy.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/linkedin-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/linkedin-page.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/linkedin.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/mastodon-custom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/mastodon-custom.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/mastodon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/mastodon.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/medium.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/nostr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/nostr.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/pinterest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/pinterest.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/reddit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/reddit.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/slack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/slack.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/telegram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/telegram.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/threads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/threads.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/tiktok.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/tiktok.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/vk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/vk.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/wrapcast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/wrapcast.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/x.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/icons/platforms/youtube.png -------------------------------------------------------------------------------- /apps/frontend/public/icons/platforms/youtube.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/frontend/public/no-picture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/no-picture.jpg -------------------------------------------------------------------------------- /apps/frontend/public/postiz-fav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/public/postiz-fav.png -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(preview)/p/[id]/layout.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from 'react'; 2 | import { PreviewWrapper } from '@gitroom/frontend/components/preview/preview.wrapper'; 3 | export default async function AppLayout({ children }: { children: ReactNode }) { 4 | return ( 5 |
6 | {children} 7 |
8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/analytics/page.tsx: -------------------------------------------------------------------------------- 1 | export const dynamic = 'force-dynamic'; 2 | import { AnalyticsComponent } from '@gitroom/frontend/components/analytics/analytics.component'; 3 | import { Metadata } from 'next'; 4 | import { PlatformAnalytics } from '@gitroom/frontend/components/platform-analytics/platform.analytics'; 5 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 6 | export const metadata: Metadata = { 7 | title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Analytics`, 8 | description: '', 9 | }; 10 | export default async function Index() { 11 | return ( 12 | <> 13 | {isGeneralServerSide() ? : } 14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/billing/lifetime/page.tsx: -------------------------------------------------------------------------------- 1 | import { LifetimeDeal } from '@gitroom/frontend/components/billing/lifetime.deal'; 2 | export const dynamic = 'force-dynamic'; 3 | import { Metadata } from 'next'; 4 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 5 | export const metadata: Metadata = { 6 | title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Lifetime deal`, 7 | description: '', 8 | }; 9 | export default async function Page() { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/billing/page.tsx: -------------------------------------------------------------------------------- 1 | export const dynamic = 'force-dynamic'; 2 | import { BillingComponent } from '@gitroom/frontend/components/billing/billing.component'; 3 | import { Metadata } from 'next'; 4 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 5 | export const metadata: Metadata = { 6 | title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Billing`, 7 | description: '', 8 | }; 9 | export default async function Page() { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/err/page.tsx: -------------------------------------------------------------------------------- 1 | import { Metadata } from 'next'; 2 | import { getT } from '@gitroom/react/translation/get.translation.service.backend'; 3 | export const metadata: Metadata = { 4 | title: 'Error', 5 | description: '', 6 | }; 7 | export default async function Page() { 8 | const t = await getT(); 9 | return ( 10 |
11 | {t( 12 | 'we_are_experiencing_some_difficulty_try_to_refresh_the_page', 13 | 'We are experiencing some difficulty, try to refresh the page' 14 | )} 15 |
16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/integrations/social/[provider]/page.tsx: -------------------------------------------------------------------------------- 1 | import { IntegrationRedirectComponent } from '@gitroom/frontend/components/launches/integration.redirect.component'; 2 | export const dynamic = 'force-dynamic'; 3 | export default async function Page({ 4 | params: { provider }, 5 | searchParams, 6 | }: { 7 | params: { 8 | provider: string; 9 | }; 10 | searchParams: any; 11 | }) { 12 | return ; 13 | } 14 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/integrations/social/layout.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from 'react'; 2 | import { getT } from '@gitroom/react/translation/get.translation.service.backend'; 3 | export default async function IntegrationLayout({ 4 | children, 5 | }: { 6 | children: ReactNode; 7 | }) { 8 | const t = await getT(); 9 | 10 | return ( 11 |
12 | {t('adding_channel_redirecting_you', 'Adding channel, Redirecting You')} 13 | {children} 14 |
15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/launches/page.tsx: -------------------------------------------------------------------------------- 1 | export const dynamic = 'force-dynamic'; 2 | import { LaunchesComponent } from '@gitroom/frontend/components/launches/launches.component'; 3 | import { Metadata } from 'next'; 4 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 5 | export const metadata: Metadata = { 6 | title: `${isGeneralServerSide() ? 'Postiz Calendar' : 'Gitroom Launches'}`, 7 | description: '', 8 | }; 9 | export default async function Index() { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/layout.tsx: -------------------------------------------------------------------------------- 1 | import { LayoutSettings } from '@gitroom/frontend/components/layout/layout.settings'; 2 | export default async function Layout({ 3 | children, 4 | }: { 5 | children: React.ReactNode; 6 | }) { 7 | return {children}; 8 | } 9 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/marketplace/buyer/page.tsx: -------------------------------------------------------------------------------- 1 | import { Buyer } from '@gitroom/frontend/components/marketplace/buyer'; 2 | export const dynamic = 'force-dynamic'; 3 | import { Metadata } from 'next'; 4 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 5 | export const metadata: Metadata = { 6 | title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Marketplace`, 7 | description: '', 8 | }; 9 | export default async function Index({ 10 | searchParams, 11 | }: { 12 | searchParams: { 13 | code: string; 14 | }; 15 | }) { 16 | return ; 17 | } 18 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/marketplace/layout.tsx: -------------------------------------------------------------------------------- 1 | import { BuyerSeller } from '@gitroom/frontend/components/marketplace/buyer.seller'; 2 | import { ReactNode } from 'react'; 3 | export default function Layout({ children }: { children: ReactNode }) { 4 | return ( 5 | <> 6 | 7 | {children} 8 | 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/marketplace/page.tsx: -------------------------------------------------------------------------------- 1 | export const dynamic = 'force-dynamic'; 2 | import { Metadata } from 'next'; 3 | import { cookies } from 'next/headers'; 4 | import { redirect } from 'next/navigation'; 5 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 6 | export const metadata: Metadata = { 7 | title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Marketplace`, 8 | description: '', 9 | }; 10 | export default async function Index({ 11 | searchParams, 12 | }: { 13 | searchParams: { 14 | code: string; 15 | }; 16 | }) { 17 | const currentCookie = cookies()?.get('marketplace')?.value; 18 | return redirect( 19 | currentCookie === 'buyer' ? '/marketplace/buyer' : '/marketplace/seller' 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/marketplace/seller/page.tsx: -------------------------------------------------------------------------------- 1 | import { Seller } from '@gitroom/frontend/components/marketplace/seller'; 2 | export const dynamic = 'force-dynamic'; 3 | import { Metadata } from 'next'; 4 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 5 | export const metadata: Metadata = { 6 | title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Marketplace`, 7 | description: '', 8 | }; 9 | export default async function Index({ 10 | searchParams, 11 | }: { 12 | searchParams: { 13 | code: string; 14 | }; 15 | }) { 16 | return ; 17 | } 18 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/messages/[id]/page.tsx: -------------------------------------------------------------------------------- 1 | import { Messages } from '@gitroom/frontend/components/messages/messages'; 2 | export const dynamic = 'force-dynamic'; 3 | import { Metadata } from 'next'; 4 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 5 | export const metadata: Metadata = { 6 | title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Messages`, 7 | description: '', 8 | }; 9 | export default async function Index() { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/messages/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Layout } from '@gitroom/frontend/components/messages/layout'; 2 | export const dynamic = 'force-dynamic'; 3 | import { ReactNode } from 'react'; 4 | export default async function LayoutWrapper({ 5 | children, 6 | }: { 7 | children: ReactNode; 8 | }) { 9 | return ; 10 | } 11 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/messages/page.tsx: -------------------------------------------------------------------------------- 1 | import { getT } from '@gitroom/react/translation/get.translation.service.backend'; 2 | 3 | export const dynamic = 'force-dynamic'; 4 | import { Metadata } from 'next'; 5 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 6 | export const metadata: Metadata = { 7 | title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Messages`, 8 | description: '', 9 | }; 10 | export default async function Index() { 11 | const t = await getT(); 12 | 13 | return ( 14 |
15 |
16 |
17 | {t( 18 | 'select_a_conversation_and_chat_away', 19 | 'Select a conversation and chat away.' 20 | )} 21 |
22 |
23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/plugs/page.tsx: -------------------------------------------------------------------------------- 1 | import { Plugs } from '@gitroom/frontend/components/plugs/plugs'; 2 | export const dynamic = 'force-dynamic'; 3 | import { Metadata } from 'next'; 4 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 5 | export const metadata: Metadata = { 6 | title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Plugs`, 7 | description: '', 8 | }; 9 | export default async function Index() { 10 | return ( 11 | <> 12 | 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/(site)/settings/page.tsx: -------------------------------------------------------------------------------- 1 | import { SettingsPopup } from '@gitroom/frontend/components/layout/settings.component'; 2 | export const dynamic = 'force-dynamic'; 3 | import { Metadata } from 'next'; 4 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 5 | export const metadata: Metadata = { 6 | title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Settings`, 7 | description: '', 8 | }; 9 | export default async function Index({ 10 | searchParams, 11 | }: { 12 | searchParams: { 13 | code: string; 14 | }; 15 | }) { 16 | return ; 17 | } 18 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/auth/activate/[code]/page.tsx: -------------------------------------------------------------------------------- 1 | export const dynamic = 'force-dynamic'; 2 | import { Metadata } from 'next'; 3 | import { AfterActivate } from '@gitroom/frontend/components/auth/after.activate'; 4 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 5 | export const metadata: Metadata = { 6 | title: `${ 7 | isGeneralServerSide() ? 'Postiz' : 'Gitroom' 8 | } - Activate your account`, 9 | description: '', 10 | }; 11 | export default async function Auth() { 12 | return ; 13 | } 14 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/auth/activate/page.tsx: -------------------------------------------------------------------------------- 1 | export const dynamic = 'force-dynamic'; 2 | import { Metadata } from 'next'; 3 | import { Activate } from '@gitroom/frontend/components/auth/activate'; 4 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 5 | export const metadata: Metadata = { 6 | title: `${ 7 | isGeneralServerSide() ? 'Postiz' : 'Gitroom' 8 | } - Activate your account`, 9 | description: '', 10 | }; 11 | export default async function Auth() { 12 | return ; 13 | } 14 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/auth/forgot/[token]/page.tsx: -------------------------------------------------------------------------------- 1 | export const dynamic = 'force-dynamic'; 2 | import { ForgotReturn } from '@gitroom/frontend/components/auth/forgot-return'; 3 | import { Metadata } from 'next'; 4 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 5 | export const metadata: Metadata = { 6 | title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Forgot Password`, 7 | description: '', 8 | }; 9 | export default async function Auth(params: { 10 | params: { 11 | token: string; 12 | }; 13 | }) { 14 | return ; 15 | } 16 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/auth/forgot/page.tsx: -------------------------------------------------------------------------------- 1 | export const dynamic = 'force-dynamic'; 2 | import { Forgot } from '@gitroom/frontend/components/auth/forgot'; 3 | import { Metadata } from 'next'; 4 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 5 | export const metadata: Metadata = { 6 | title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Forgot Password`, 7 | description: '', 8 | }; 9 | export default async function Auth() { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/auth/login/page.tsx: -------------------------------------------------------------------------------- 1 | export const dynamic = 'force-dynamic'; 2 | import { Login } from '@gitroom/frontend/components/auth/login'; 3 | import { Metadata } from 'next'; 4 | import { isGeneralServerSide } from '@gitroom/helpers/utils/is.general.server.side'; 5 | export const metadata: Metadata = { 6 | title: `${isGeneralServerSide() ? 'Postiz' : 'Gitroom'} Login`, 7 | description: '', 8 | }; 9 | export default async function Auth() { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(app)/auth/return.url.component.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useSearchParams } from 'next/navigation'; 4 | import { FC, useCallback, useEffect } from 'react'; 5 | const ReturnUrlComponent: FC = () => { 6 | const params = useSearchParams(); 7 | const url = params.get('returnUrl'); 8 | useEffect(() => { 9 | if (url?.indexOf?.('http')! > -1) { 10 | localStorage.setItem('returnUrl', url!); 11 | } 12 | }, [url]); 13 | return null; 14 | }; 15 | export const useReturnUrl = () => { 16 | return { 17 | getAndClear: useCallback(() => { 18 | const data = localStorage.getItem('returnUrl'); 19 | localStorage.removeItem('returnUrl'); 20 | return data; 21 | }, []), 22 | }; 23 | }; 24 | export default ReturnUrlComponent; 25 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(extension)/modal/[style]/[platform]/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { StandaloneModal } from '@gitroom/frontend/components/standalone-modal/standalone.modal'; 4 | import { usePathname } from 'next/navigation'; 5 | export default async function Modal() { 6 | return ( 7 |
8 | 9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /apps/frontend/src/app/(extension)/modal/layout.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from 'react'; 2 | import { AppLayout } from '@gitroom/frontend/components/launches/layout.standalone'; 3 | export default async function AppLayoutIn({ 4 | children, 5 | }: { 6 | children: ReactNode; 7 | }) { 8 | return {children}; 9 | } 10 | -------------------------------------------------------------------------------- /apps/frontend/src/components/analytics/stars.and.forks.interface.ts: -------------------------------------------------------------------------------- 1 | export interface StarsList { 2 | totalStars: number; 3 | date: string; 4 | } 5 | export interface TotalList { 6 | total: number; 7 | date: string; 8 | } 9 | export interface ForksList { 10 | totalForks: number; 11 | date: string; 12 | } 13 | export interface Stars { 14 | id: string; 15 | stars: number; 16 | totalStars: number; 17 | login: string; 18 | date: string; 19 | } 20 | export interface StarsAndForksInterface { 21 | list: Array<{ 22 | login: string; 23 | stars: StarsList[]; 24 | forks: ForksList[]; 25 | }>; 26 | trending: { 27 | last: string; 28 | predictions: string; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /apps/frontend/src/components/auth/activate.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useT } from '@gitroom/react/translation/get.transation.service.client'; 4 | 5 | export function Activate() { 6 | const t = useT(); 7 | return ( 8 | <> 9 |
10 |

11 | {t('activate_your_account', 'Activate your account')} 12 |

13 |
14 |
15 | {t('thank_you_for_registering', 'Thank you for registering!')} 16 |
17 | {t( 18 | 'please_check_your_email_to_activate_your_account', 19 | 'Please check your email to activate your account.' 20 | )} 21 |
22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /apps/frontend/src/components/billing/billing.component.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useCallback, useEffect } from 'react'; 4 | import useSWR from 'swr'; 5 | import { LoadingComponent } from '@gitroom/frontend/components/layout/loading'; 6 | import { useFetch } from '@gitroom/helpers/utils/custom.fetch'; 7 | import { MainBillingComponent } from './main.billing.component'; 8 | export const BillingComponent = () => { 9 | const fetch = useFetch(); 10 | const load = useCallback(async (path: string) => { 11 | return await (await fetch(path)).json(); 12 | }, []); 13 | const { isLoading: isLoadingTier, data: tiers } = useSWR( 14 | '/user/subscription/tiers', 15 | load 16 | ); 17 | const { isLoading: isLoadingSubscription, data: subscription } = useSWR( 18 | '/user/subscription', 19 | load 20 | ); 21 | if (isLoadingSubscription || isLoadingTier) { 22 | return ; 23 | } 24 | return ; 25 | }; 26 | -------------------------------------------------------------------------------- /apps/frontend/src/components/billing/purchase.crypto.tsx: -------------------------------------------------------------------------------- 1 | import { FC, useCallback, useState } from 'react'; 2 | import { useFetch } from '@gitroom/helpers/utils/custom.fetch'; 3 | import { Button } from '@gitroom/react/form/button'; 4 | import { useT } from '@gitroom/react/translation/get.transation.service.client'; 5 | export const PurchaseCrypto: FC = () => { 6 | const fetch = useFetch(); 7 | const t = useT(); 8 | 9 | const [loading, setLoading] = useState(false); 10 | const load = useCallback(async () => { 11 | setLoading(true); 12 | const data = await (await fetch('/billing/crypto')).json(); 13 | window.location.href = data.invoice_url; 14 | }, []); 15 | return ( 16 |
17 |
18 | {t( 19 | 'purchase_a_life_time_pro_account_with_sol_199', 20 | 'Purchase a Life-time PRO account with SOL ($199)' 21 | )} 22 |
23 |
24 | 27 |
28 |
29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/connect.with.wallet.tsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/src/components/launches/connect.with.wallet.tsx -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/helpers/dnd.provider.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { FC, ReactNode } from 'react'; 4 | import { HTML5Backend } from 'react-dnd-html5-backend'; 5 | import { DndProvider } from 'react-dnd'; 6 | export const DNDProvider: FC<{ 7 | children: ReactNode; 8 | }> = ({ children }) => { 9 | return {children}; 10 | }; 11 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/helpers/isuscitizen.utils.tsx: -------------------------------------------------------------------------------- 1 | export const isUSCitizen = () => { 2 | const userLanguage = navigator.language || navigator.languages[0]; 3 | return userLanguage.startsWith('en-US'); 4 | }; 5 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/helpers/use.custom.provider.function.ts: -------------------------------------------------------------------------------- 1 | import { useIntegration } from '@gitroom/frontend/components/launches/helpers/use.integration'; 2 | import { useCallback } from 'react'; 3 | import { useFetch } from '@gitroom/helpers/utils/custom.fetch'; 4 | export const useCustomProviderFunction = () => { 5 | const { integration } = useIntegration(); 6 | const fetch = useFetch(); 7 | const get = useCallback( 8 | async (funcName: string, customData?: any) => { 9 | const load = await fetch('/integrations/function', { 10 | method: 'POST', 11 | body: JSON.stringify({ 12 | name: funcName, 13 | id: integration?.id!, 14 | data: customData, 15 | }), 16 | }); 17 | if (load.status > 299 && load.status < 200) { 18 | throw new Error('Failed to fetch'); 19 | } 20 | return load.json(); 21 | }, 22 | [integration] 23 | ); 24 | return { 25 | get, 26 | }; 27 | }; 28 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/helpers/use.existing.data.tsx: -------------------------------------------------------------------------------- 1 | import { createContext, FC, ReactNode, useContext } from 'react'; 2 | import { Post } from '@prisma/client'; 3 | const ExistingDataContext = createContext({ 4 | integration: '', 5 | group: undefined as undefined | string, 6 | posts: [] as Post[], 7 | settings: {} as any, 8 | }); 9 | export const ExistingDataContextProvider: FC<{ 10 | children: ReactNode; 11 | value: any; 12 | }> = ({ children, value }) => { 13 | return ( 14 | 15 | {children} 16 | 17 | ); 18 | }; 19 | export const useExistingData = () => useContext(ExistingDataContext); 20 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/helpers/use.expend.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import EventEmitter from 'events'; 4 | import { useEffect, useState } from 'react'; 5 | const emitter = new EventEmitter(); 6 | export const useExpend = () => { 7 | const [expend, setExpend] = useState(false); 8 | useEffect(() => { 9 | const hide = () => { 10 | setExpend(false); 11 | }; 12 | const show = () => { 13 | setExpend(true); 14 | }; 15 | emitter.on('hide', hide); 16 | emitter.on('show', show); 17 | return () => { 18 | emitter.off('hide', hide); 19 | emitter.off('show', show); 20 | }; 21 | }, []); 22 | return { 23 | expend, 24 | hide: () => { 25 | emitter.emit('hide'); 26 | }, 27 | show: () => { 28 | emitter.emit('show'); 29 | }, 30 | }; 31 | }; 32 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/helpers/use.hide.top.editor.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import EventEmitter from 'events'; 4 | import { useEffect, useState } from 'react'; 5 | const emitter = new EventEmitter(); 6 | export const useHideTopEditor = () => { 7 | const [hideTopEditor, setHideTopEditor] = useState(false); 8 | useEffect(() => { 9 | const hide = () => { 10 | setHideTopEditor(true); 11 | }; 12 | const show = () => { 13 | setHideTopEditor(false); 14 | }; 15 | emitter.on('hide', hide); 16 | emitter.on('show', show); 17 | return () => { 18 | emitter.off('hide', hide); 19 | emitter.off('show', show); 20 | }; 21 | }, []); 22 | return { 23 | hideTopEditor, 24 | hide: () => { 25 | emitter.emit('hide'); 26 | }, 27 | show: () => { 28 | emitter.emit('show'); 29 | }, 30 | }; 31 | }; 32 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/helpers/use.integration.ts: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { createContext, useContext } from 'react'; 4 | import { Integrations } from '@gitroom/frontend/components/launches/calendar.context'; 5 | import dayjs from 'dayjs'; 6 | export const IntegrationContext = createContext<{ 7 | date: dayjs.Dayjs; 8 | integration: Integrations | undefined; 9 | allIntegrations: Integrations[]; 10 | value: Array<{ 11 | content: string; 12 | id?: string; 13 | image?: Array<{ 14 | path: string; 15 | id: string; 16 | }>; 17 | }>; 18 | }>({ 19 | integration: undefined, 20 | value: [], 21 | date: dayjs(), 22 | allIntegrations: [], 23 | }); 24 | export const useIntegration = () => useContext(IntegrationContext); 25 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/helpers/use.move.to.integration.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import EventEmitter from 'events'; 4 | import { useCallback, useEffect } from 'react'; 5 | const emitter = new EventEmitter(); 6 | export const useMoveToIntegration = () => { 7 | return useCallback( 8 | ({ 9 | identifier, 10 | toPreview, 11 | }: { 12 | identifier: string; 13 | toPreview?: boolean; 14 | }) => { 15 | emitter.emit('moveToIntegration', { 16 | identifier, 17 | toPreview, 18 | }); 19 | }, 20 | [] 21 | ); 22 | }; 23 | export const useMoveToIntegrationListener = ( 24 | useEffectParams: any[], 25 | enabled: boolean, 26 | callback: ({ 27 | identifier, 28 | toPreview, 29 | }: { 30 | identifier: string; 31 | toPreview: boolean; 32 | }) => void 33 | ) => { 34 | useEffect(() => { 35 | if (!enabled) { 36 | return; 37 | } 38 | return load(); 39 | }, useEffectParams); 40 | const load = useCallback(() => { 41 | emitter.off('moveToIntegration', callback); 42 | emitter.on('moveToIntegration', callback); 43 | return () => { 44 | emitter.off('moveToIntegration', callback); 45 | }; 46 | }, useEffectParams); 47 | }; 48 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/integration.redirect.component.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import dayjs from 'dayjs'; 4 | import utc from 'dayjs/plugin/utc'; 5 | import timezone from 'dayjs/plugin/timezone'; 6 | import { usePathname, useRouter, useSearchParams } from 'next/navigation'; 7 | import { FC, useEffect } from 'react'; 8 | dayjs.extend(utc); 9 | dayjs.extend(timezone); 10 | export const IntegrationRedirectComponent: FC = () => { 11 | const offset = dayjs.tz().utcOffset(); 12 | const pathname = usePathname(); 13 | const searchParams = useSearchParams(); 14 | const router = useRouter(); 15 | const newUrl = `${pathname}/continue?${searchParams.toString()}&timezone=${offset}`; 16 | useEffect(() => { 17 | router.push(newUrl); 18 | }, [newUrl]); 19 | return null; 20 | }; 21 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/layout.standalone.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { ReactNode, useMemo } from 'react'; 4 | import { PreviewWrapper } from '@gitroom/frontend/components/preview/preview.wrapper'; 5 | import { usePathname } from 'next/navigation'; 6 | import dayjs from 'dayjs'; 7 | import utc from 'dayjs/plugin/utc'; 8 | dayjs.extend(utc); 9 | export const AppLayout = ({ children }: { children: ReactNode }) => { 10 | const params = usePathname(); 11 | const style = useMemo(() => { 12 | const all = params.split('/'); 13 | all.pop(); 14 | return all.pop(); 15 | }, [params]); 16 | return ( 17 |
20 | 30 | {children} 31 |
32 | ); 33 | }; 34 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/merge.post.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from '@gitroom/react/form/button'; 2 | import { deleteDialog } from '@gitroom/react/helpers/delete.dialog'; 3 | import { FC, useCallback } from 'react'; 4 | import { useT } from '@gitroom/react/translation/get.transation.service.client'; 5 | export const MergePost: FC<{ 6 | merge: () => void; 7 | }> = (props) => { 8 | const { merge } = props; 9 | const t = useT(); 10 | 11 | const notReversible = useCallback(async () => { 12 | if ( 13 | await deleteDialog( 14 | 'Are you sure you want to merge all comments into one post? This action is not reversible.', 15 | 'Yes' 16 | ) 17 | ) { 18 | merge(); 19 | } 20 | }, [merge]); 21 | return ( 22 | 25 | ); 26 | }; 27 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/bluesky/bluesky.provider.tsx: -------------------------------------------------------------------------------- 1 | import { withProvider } from '@gitroom/frontend/components/launches/providers/high.order.provider'; 2 | import { ThreadFinisher } from '@gitroom/frontend/components/launches/finisher/thread.finisher'; 3 | 4 | const SettingsComponent = () => { 5 | return ; 6 | }; 7 | 8 | export default withProvider( 9 | SettingsComponent, 10 | undefined, 11 | undefined, 12 | async (posts) => { 13 | if (posts.some((p) => p.some((a) => a.path.indexOf('mp4') > -1))) { 14 | return 'At the moment BlueSky does not support video posts.'; 15 | } 16 | if (posts.some((p) => p.length > 4)) { 17 | return 'There can be maximum 4 pictures in a post.'; 18 | } 19 | return true; 20 | }, 21 | 300 22 | ); 23 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/continue-provider/list.tsx: -------------------------------------------------------------------------------- 1 | import { InstagramContinue } from '@gitroom/frontend/components/launches/providers/continue-provider/instagram/instagram.continue'; 2 | import { FacebookContinue } from '@gitroom/frontend/components/launches/providers/continue-provider/facebook/facebook.continue'; 3 | import { LinkedinContinue } from '@gitroom/frontend/components/launches/providers/continue-provider/linkedin/linkedin.continue'; 4 | export const continueProviderList = { 5 | instagram: InstagramContinue, 6 | facebook: FacebookContinue, 7 | 'linkedin-page': LinkedinContinue, 8 | }; 9 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/devto/fonts/SFNS.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/src/components/launches/providers/devto/fonts/SFNS.woff2 -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/discord/discord.provider.tsx: -------------------------------------------------------------------------------- 1 | import { withProvider } from '@gitroom/frontend/components/launches/providers/high.order.provider'; 2 | import { FC } from 'react'; 3 | import { DiscordDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/discord.dto'; 4 | import { DiscordChannelSelect } from '@gitroom/frontend/components/launches/providers/discord/discord.channel.select'; 5 | import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values'; 6 | const DiscordComponent: FC = () => { 7 | const form = useSettings(); 8 | return ( 9 |
10 | 11 |
12 | ); 13 | }; 14 | export default withProvider( 15 | DiscordComponent, 16 | undefined, 17 | DiscordDto, 18 | undefined, 19 | 1980 20 | ); 21 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/facebook/facebook.provider.tsx: -------------------------------------------------------------------------------- 1 | import { withProvider } from '@gitroom/frontend/components/launches/providers/high.order.provider'; 2 | export default withProvider(null, undefined, undefined, undefined, 63206); 3 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/linkedin/linkedin.provider.tsx: -------------------------------------------------------------------------------- 1 | import { withProvider } from '@gitroom/frontend/components/launches/providers/high.order.provider'; 2 | export default withProvider( 3 | null, 4 | undefined, 5 | undefined, 6 | async (posts) => { 7 | const [firstPost, ...restPosts] = posts; 8 | if ( 9 | firstPost.length > 1 && 10 | firstPost.some((p) => p.path.indexOf('mp4') > -1) 11 | ) { 12 | return 'LinkedIn can have maximum 1 media when selecting a video.'; 13 | } 14 | if (restPosts.some((p) => p.length > 0)) { 15 | return 'LinkedIn comments can only contain text.'; 16 | } 17 | return true; 18 | }, 19 | 3000 20 | ); 21 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/mastodon/mastodon.provider.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from 'react'; 2 | import { withProvider } from '@gitroom/frontend/components/launches/providers/high.order.provider'; 3 | export default withProvider(null, undefined, undefined, undefined, 500); 4 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/medium/fonts/Charter Bold Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/src/components/launches/providers/medium/fonts/Charter Bold Italic.ttf -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/medium/fonts/Charter Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/src/components/launches/providers/medium/fonts/Charter Bold.ttf -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/medium/fonts/Charter Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/src/components/launches/providers/medium/fonts/Charter Italic.ttf -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/medium/fonts/Charter Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/src/components/launches/providers/medium/fonts/Charter Regular.ttf -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/nostr/nostr.provider.tsx: -------------------------------------------------------------------------------- 1 | import { withProvider } from '@gitroom/frontend/components/launches/providers/high.order.provider'; 2 | export default withProvider( 3 | null, 4 | undefined, 5 | undefined, 6 | async () => { 7 | return true; 8 | }, 9 | undefined 10 | ); 11 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/slack/slack.provider.tsx: -------------------------------------------------------------------------------- 1 | import { withProvider } from '@gitroom/frontend/components/launches/providers/high.order.provider'; 2 | import { FC } from 'react'; 3 | import { useSettings } from '@gitroom/frontend/components/launches/helpers/use.values'; 4 | import { SlackChannelSelect } from '@gitroom/frontend/components/launches/providers/slack/slack.channel.select'; 5 | import { SlackDto } from '@gitroom/nestjs-libraries/dtos/posts/providers-settings/slack.dto'; 6 | const SlackComponent: FC = () => { 7 | const form = useSettings(); 8 | return ( 9 |
10 | 11 |
12 | ); 13 | }; 14 | export default withProvider( 15 | SlackComponent, 16 | undefined, 17 | SlackDto, 18 | undefined, 19 | 280 20 | ); 21 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/telegram/telegram.provider.tsx: -------------------------------------------------------------------------------- 1 | import { withProvider } from '@gitroom/frontend/components/launches/providers/high.order.provider'; 2 | export default withProvider( 3 | null, 4 | undefined, 5 | undefined, 6 | async () => { 7 | return true; 8 | }, 9 | 4096 10 | ); 11 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/threads/threads.provider.tsx: -------------------------------------------------------------------------------- 1 | import { withProvider } from '@gitroom/frontend/components/launches/providers/high.order.provider'; 2 | import { ThreadFinisher } from '@gitroom/frontend/components/launches/finisher/thread.finisher'; 3 | const SettingsComponent = () => { 4 | return ; 5 | }; 6 | 7 | export default withProvider( 8 | SettingsComponent, 9 | undefined, 10 | undefined, 11 | async () => { 12 | return true; 13 | }, 14 | 500 15 | ); 16 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/vk/vk.provider.tsx: -------------------------------------------------------------------------------- 1 | import { withProvider } from '@gitroom/frontend/components/launches/providers/high.order.provider'; 2 | export default withProvider( 3 | null, 4 | undefined, 5 | undefined, 6 | async (posts) => { 7 | return true; 8 | }, 9 | 2048 10 | ); 11 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/x/fonts/Chirp-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/src/components/launches/providers/x/fonts/Chirp-Bold.woff2 -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/providers/x/fonts/Chirp-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gitroomhq/postiz-app/781e4d8fc0db242acf6d43a95050c6a8d3d35c45/apps/frontend/src/components/launches/providers/x/fonts/Chirp-Regular.woff2 -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/web3/web3.list.tsx: -------------------------------------------------------------------------------- 1 | import { FC } from 'react'; 2 | import { Web3ProviderInterface } from '@gitroom/frontend/components/launches/web3/web3.provider.interface'; 3 | import { WrapcasterProvider } from '@gitroom/frontend/components/launches/web3/providers/wrapcaster.provider'; 4 | import { TelegramProvider } from '@gitroom/frontend/components/launches/web3/providers/telegram.provider'; 5 | export const web3List: { 6 | identifier: string; 7 | component: FC; 8 | }[] = [ 9 | { 10 | identifier: 'telegram', 11 | component: TelegramProvider, 12 | }, 13 | { 14 | identifier: 'wrapcast', 15 | component: WrapcasterProvider, 16 | }, 17 | ]; 18 | -------------------------------------------------------------------------------- /apps/frontend/src/components/launches/web3/web3.provider.interface.ts: -------------------------------------------------------------------------------- 1 | export interface Web3ProviderInterface { 2 | onComplete: (code: string, state: string) => void; 3 | nonce: string; 4 | } 5 | -------------------------------------------------------------------------------- /apps/frontend/src/components/layout/click.outside.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | export const useClickOutside = (callback: () => Promise) => { 3 | const handleClick = (event: MouseEvent) => { 4 | const selector = document.querySelector('#add-edit-modal'); 5 | const copilotkit = document.querySelector('.copilotKitPopup'); 6 | const emoji = document.querySelector('.EmojiPickerReact'); 7 | if ( 8 | !selector?.contains(event.target as HTMLElement) && 9 | !copilotkit?.contains(event.target as HTMLElement) && 10 | !emoji 11 | ) { 12 | callback(); 13 | } 14 | }; 15 | useEffect(() => { 16 | document 17 | .querySelector('.mantine-Modal-root') 18 | // @ts-ignore 19 | ?.addEventListener('click', handleClick); 20 | return () => { 21 | document 22 | .querySelector('.mantine-Modal-root') 23 | // @ts-ignore 24 | ?.removeEventListener('click', handleClick); 25 | }; 26 | }); 27 | }; 28 | -------------------------------------------------------------------------------- /apps/frontend/src/components/layout/drop.files.tsx: -------------------------------------------------------------------------------- 1 | import { useDropzone } from 'react-dropzone'; 2 | import { FC, ReactNode } from 'react'; 3 | import { useT } from '@gitroom/react/translation/get.transation.service.client'; 4 | export const DropFiles: FC<{ 5 | children: ReactNode; 6 | onDrop: (files: File[]) => void; 7 | }> = (props) => { 8 | const t = useT(); 9 | 10 | const { getRootProps, isDragActive } = useDropzone({ 11 | onDrop: props.onDrop, 12 | }); 13 | return ( 14 |
15 | {isDragActive && ( 16 |
17 | {t('drag_n_drop_some_files_here', 'Drag n drop some files here')} 18 |
19 | )} 20 | {props.children} 21 |
22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /apps/frontend/src/components/layout/facebook.component.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import Script from 'next/script'; 4 | export const FacebookComponent = () => { 5 | if (!process.env.NEXT_PUBLIC_FACEBOOK_PIXEL) { 6 | return null; 7 | } 8 | return ( 9 | 21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /apps/frontend/src/components/layout/html.component.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | import { FC, ReactNode, useEffect, useState } from 'react'; 3 | import { useTranslationSettings } from '@gitroom/react/translation/get.transation.service.client'; 4 | 5 | export const HtmlComponent: FC = () => { 6 | const settings = useTranslationSettings(); 7 | const [dir, setDir] = useState(settings.dir()); 8 | 9 | useEffect(() => { 10 | settings.on('languageChanged', (lng) => { 11 | setDir(settings.dir()); 12 | }); 13 | }, []); 14 | 15 | useEffect(() => { 16 | const htmlElement = document.querySelector('html'); 17 | if (htmlElement) { 18 | htmlElement.setAttribute('dir', dir); 19 | } 20 | }, [dir]); 21 | 22 | return null; 23 | }; 24 | -------------------------------------------------------------------------------- /apps/frontend/src/components/layout/loading.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import ReactLoading from 'react-loading'; 4 | import { FC } from 'react'; 5 | export const LoadingComponent: FC<{ 6 | width?: number; 7 | height?: number; 8 | }> = (props) => { 9 | return ( 10 |
11 | 17 |
18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /apps/frontend/src/components/layout/new.subscription.tsx: -------------------------------------------------------------------------------- 1 | import { useSearchParams } from 'next/navigation'; 2 | import { FC, useEffect } from 'react'; 3 | import { useFireEvents } from '@gitroom/helpers/utils/use.fire.events'; 4 | export const NewSubscription: FC = () => { 5 | const query = useSearchParams(); 6 | const fireEvents = useFireEvents(); 7 | useEffect(() => { 8 | const check = query.get('check'); 9 | if (check) { 10 | fireEvents('purchase'); 11 | } 12 | }, [query]); 13 | return null; 14 | }; 15 | -------------------------------------------------------------------------------- /apps/frontend/src/components/layout/redirect.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { FC, useEffect } from 'react'; 4 | import { useRouter } from 'next/navigation'; 5 | export const Redirect: FC<{ 6 | url: string; 7 | delay: number; 8 | }> = (props) => { 9 | const { url, delay } = props; 10 | const router = useRouter(); 11 | useEffect(() => { 12 | setTimeout(() => { 13 | router.push(url); 14 | }, delay); 15 | }, []); 16 | return null; 17 | }; 18 | -------------------------------------------------------------------------------- /apps/frontend/src/components/layout/title.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { usePathname } from 'next/navigation'; 4 | import { useMemo } from 'react'; 5 | import { useMenuItems } from '@gitroom/frontend/components/layout/top.menu'; 6 | export const Title = () => { 7 | const path = usePathname(); 8 | const menuItems = useMenuItems(); 9 | const currentTitle = useMemo(() => { 10 | return menuItems.find((item) => path.indexOf(item.path) > -1)?.name; 11 | }, [path]); 12 | return ( 13 |
14 |

{currentTitle}

15 |
16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /apps/frontend/src/components/layout/tolt.script.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useVariables } from '@gitroom/react/helpers/variable.context'; 4 | import Script from 'next/script'; 5 | export const useTolt = () => { 6 | return () => { 7 | // @ts-ignore 8 | return window?.tolt_referral || ''; 9 | }; 10 | }; 11 | export const ToltScript = () => { 12 | const { tolt } = useVariables(); 13 | if (!tolt) return null; 14 | return ( 15 |