diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..b56e02f6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# Root shim so editors auto-discover project formatting rules. +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +[*.py] +indent_size = 4 diff --git a/.github/README.md b/.github/README.md index f9a24ed1..e32c56f1 100644 --- a/.github/README.md +++ b/.github/README.md @@ -10,14 +10,20 @@ **Create, optimize, and publish high‑quality content across platforms — in minutes, not months.** -[🌐 Live Demo](https://www.alwrity.com) • [📚 Docs Site](https://ajaysi.github.io/ALwrity/) • [📖 Wiki](https://github.com/AJaySi/AI-Writer/wiki) • [💬 Discussions](https://github.com/AJaySi/AI-Writer/discussions) • [🐛 Issues](https://github.com/AJaySi/AI-Writer/issues) +[🌐 Live Demo](https://www.alwrity.com) • [📚 Docs Site](https://ajaysi.github.io/ALwrity/) • [📖 Wiki](https://github.com/AJaySi/ALwrity/wiki) • [💬 Discussions](https://github.com/AJaySi/AI-Writer/discussions) • [🐛 Issues](https://github.com/AJaySi/AI-Writer/issues)

- ALwrity dashboard overview - Story Writer workflow - SEO dashboard insights + ALwrity dashboard overview + Blog Writer workflow + SEO dashboard insights +

+ +

+ Podcast Maker - AI Audio Content + Video Studio - AI Video Creation + Instagram Editor - Social Media Content

--- @@ -27,6 +33,7 @@ - **Grounded & reliable**: Google grounding, Exa/Tavily research, citation management. - **Secure & scalable**: JWT auth, OAuth2, rate limiting, monitoring, subscription/usage tracking. - **Built for solopreneurs**: Enterprise-grade capabilities with a fast, friendly UI. +- **Comprehensive documentation**: Detailed guides, user journeys, and contextual help throughout the platform. --- @@ -40,13 +47,17 @@ --- ### What’s functional now -- **AI Blog Writer (Phases)**: Research → Outline → Content → SEO → Publish, with guarded navigation and local persistence (`frontend/src/hooks/usePhaseNavigation.ts`). -- **SEO Dashboard**: Analysis, metadata, and Google Search Console insights (see docs under `docs-site/docs/features/seo-dashboard`). -- **Story Writer**: Setup (premise) → Outline → Writing → Export with phase navigation and reset (`frontend/src/hooks/useStoryWriterPhaseNavigation.ts`). -- **LinkedIn (Factual, Google‑Grounded)**: Real Google grounding + citations + quality metrics for posts/articles/carousels/scripts (see `frontend/docs/linkedin_factual_google_grounded_url_content.md`). -- **Persona System**: Core personas and platform adaptations via APIs (`backend/api/persona.py`). -- **Facebook Persona Service**: Gemini structured JSON for Facebook‑specific persona optimization (`backend/services/persona/facebook/facebook_persona_service.py`). -- **Personalization & Brand Voice**: Validation and configuration of writing style, tone, structure (`backend/services/component_logic/personalization_logic.py`). +- **AI Blog Writer (Phases)**: Research → Outline → Content → SEO → Publish, with guarded navigation and local persistence. +- **SEO Dashboard**: Analysis, metadata, and Google Search Console insights with comprehensive optimization tools. +- **Story Writer**: Setup (premise) → Outline → Writing → Export with phase navigation and multimedia integration. +- **LinkedIn Writer**: Factual, Google‑grounded content with citations and quality metrics for posts/articles/carousels/scripts. +- **Instagram Editor**: Multi-format content creation with CopilotKit integration for Feed, Stories, and Reels. +- **Podcast Maker**: AI-powered audio content creation with research, scripting, and voice synthesis. +- **Video Studio**: Comprehensive video creation with WaveSpeed AI integration and multiple modules. +- **YouTube Studio**: AI-powered YouTube content planning, scene building, and optimization. +- **Content Calendar**: AI-powered content planning and scheduling across all platforms. +- **ALwrity Researcher**: Intent-driven research with multi-source integration and structured outputs. +- **Persona System**: Core personas with platform-specific adaptations and brand voice management. See details in the Wiki: [Docs Home](https://github.com/AJaySi/AI-Writer/wiki) @@ -117,14 +128,31 @@ For module details, see `backend/services/llm_providers/README.md`. --- ### Documentation -- Docs Site (MkDocs): https://ajaysi.github.io/ALwrity/ -- Blog Writer (phases and UI): `docs-site/docs/features/blog-writer/overview.md` -- SEO Dashboard overview: `docs-site/docs/features/seo-dashboard/overview.md` -- SEO Dashboard GSC integration: `docs-site/docs/features/seo-dashboard/gsc-integration.md` -- LinkedIn factual, Google-grounded content: `frontend/docs/linkedin_factual_google_grounded_url_content.md` -- Persona Development (docs-site): `docs-site/docs/features/content-strategy/personas.md` +- **[📖 GitHub Wiki](https://github.com/AJaySi/ALwrity/wiki)**: Complete documentation, guides, and tutorials +- **[📚 Docs Site](https://ajaysi.github.io/ALwrity/)**: Interactive documentation with search + +#### 📖 **Wiki Documentation** +- **[Getting Started](https://github.com/AJaySi/ALwrity/wiki/Getting-started-with-ALwrity-AI-writer)** +- **[Configuration Options](https://github.com/AJaySi/ALwrity/wiki/Alwrity-AI-Writer-Configuration-options)** +- **[Interface Overview](https://github.com/AJaySi/ALwrity/wiki/ALwrity-Interface-first-page-explanation)** +- **[AI Web Research](https://github.com/AJaySi/ALwrity/wiki/Alwrity-AI-Web-Research-Details-for-content-writing)** +- **[Blog from Audio](https://github.com/AJaySi/ALwrity/wiki/How-to-use-AI-to-blog-from-Audio)** +- **[LLM Models](https://github.com/AJaySi/ALwrity/wiki/Changing-LLM-Models-in-Alwrity-AI-Writer)** + +#### 📖 **Internal Documentation** +For developers and contributors: +- **[Frontend Documentation Integration](docs/frontend-documentation-integration.md)**: Guide for implementing contextual help links +- **[Implementation Guides](docs/)**: Technical specifications and implementation details +- **[API Documentation](docs/Onboarding/README.md)**: Backend API and service documentation + +--- -For additional pages, browse the `docs-site/docs/` folder. +### 🎯 **Recent Updates** +- **📚 Enhanced Documentation**: Comprehensive GitHub Wiki with detailed feature guides and tutorials +- **🔗 Contextual Help**: Integrated documentation links throughout the frontend UI +- **📱 Multi-Platform Support**: Expanded content creation for YouTube, Instagram, LinkedIn, and more +- **🎙️ Audio & Video**: Podcast Maker and Video Studio with AI-powered creation tools +- **🤖 Advanced AI**: WaveSpeed AI integration for cutting-edge content generation --- @@ -134,9 +162,6 @@ ALwrity generates a core writing persona from onboarding data, then adapts it pe - Core Persona & API: `backend/api/persona.py` - Facebook Persona Service (Gemini structured JSON): `backend/services/persona/facebook/facebook_persona_service.py` - Personalization/Brand Voice logic: `backend/services/component_logic/personalization_logic.py` -- Docs (GitHub paths): - - Personas (docs-site): https://github.com/AJaySi/AI-Writer/blob/main/docs-site/docs/features/content-strategy/personas.md - - LinkedIn Grounded Content plan: https://github.com/AJaySi/AI-Writer/blob/main/frontend/docs/linkedin_factual_google_grounded_url_content.md At a glance: - Data → Persona: Onboarding + website analysis → core persona diff --git a/.github/config/commitlint.config.cjs b/.github/config/commitlint.config.cjs new file mode 100644 index 00000000..67c99189 --- /dev/null +++ b/.github/config/commitlint.config.cjs @@ -0,0 +1,19 @@ +module.exports = { + parserPreset: { + parserOpts: { + headerPattern: /^(\w+)(?:\(([^)]+)\))?!?: (.+)$/, + headerCorrespondence: ['type', 'scope', 'subject'], + }, + }, + rules: { + 'header-max-length': [2, 'always', 100], + 'subject-empty': [2, 'never'], + 'type-empty': [2, 'never'], + 'type-enum': [ + 2, + 'always', + ['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test'], + ], + 'body-max-line-length': [2, 'always', 120], + }, +}; diff --git a/.github/config/editorconfig b/.github/config/editorconfig new file mode 100644 index 00000000..de911105 --- /dev/null +++ b/.github/config/editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +[*.py] +indent_size = 4 diff --git a/.github/config/pre-commit-config.yaml b/.github/config/pre-commit-config.yaml new file mode 100644 index 00000000..71176ffa --- /dev/null +++ b/.github/config/pre-commit-config.yaml @@ -0,0 +1,30 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-json + - id: check-toml + - id: check-merge-conflict + - id: check-added-large-files + - id: mixed-line-ending + args: [--fix=lf] + - id: detect-private-key + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.8.2 + hooks: + - id: ruff + args: [--config=.github/config/pyproject.toml] + + - repo: local + hooks: + - id: pylint-backend + name: pylint-backend + entry: pylint --rcfile=.github/config/pylintrc backend + language: python + additional_dependencies: + - pylint + pass_filenames: false diff --git a/.github/config/pylintrc b/.github/config/pylintrc new file mode 100644 index 00000000..f7ce9668 --- /dev/null +++ b/.github/config/pylintrc @@ -0,0 +1,20 @@ +[MASTER] +ignore=ToBeMigrated +jobs=0 + +[MESSAGES CONTROL] +disable= + C, + R, + W, + import-error, + no-name-in-module + +[FORMAT] +max-line-length=120 + +[DESIGN] +max-args=10 +max-locals=25 +max-returns=8 +max-branches=20 diff --git a/.github/config/pyproject.toml b/.github/config/pyproject.toml new file mode 100644 index 00000000..0d70aa22 --- /dev/null +++ b/.github/config/pyproject.toml @@ -0,0 +1,14 @@ +[tool.ruff] +line-length = 120 +exclude = [ + "ToBeMigrated", + "frontend", + "docs-site", +] + +[tool.ruff.lint] +select = ["E9", "F", "I"] +ignore = ["E402"] + +[tool.ruff.lint.isort] +known-first-party = ["backend"] diff --git a/.github/config/stylelintrc.json b/.github/config/stylelintrc.json new file mode 100644 index 00000000..728f8cd9 --- /dev/null +++ b/.github/config/stylelintrc.json @@ -0,0 +1,13 @@ +{ + "extends": "stylelint-config-standard", + "ignoreFiles": [ + "**/node_modules/**", + "**/build/**", + "ToBeMigrated/**" + ], + "rules": { + "color-function-notation": "legacy", + "alpha-value-notation": "number", + "selector-class-pattern": null + } +} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..0fedb590 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,109 @@ +name: Comprehensive Linting + +on: + pull_request: + push: + branches: + - main + +permissions: + contents: read + pull-requests: read + +concurrency: + group: lint-${{ github.ref }} + cancel-in-progress: true + +jobs: + commit-messages: + name: Commitlint + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Lint PR commit messages + uses: wagoid/commitlint-github-action@v6 + with: + configFile: .github/config/commitlint.config.cjs + + frontend: + name: Frontend lint (ESLint + Stylelint) + runs-on: ubuntu-latest + defaults: + run: + working-directory: frontend + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + cache-dependency-path: frontend/package-lock.json + + - name: Install dependencies + run: npm ci + + - name: ESLint + run: npx eslint src --ext .js,.jsx,.ts,.tsx --max-warnings=0 + + - name: Stylelint + run: npx --yes --package stylelint --package stylelint-config-standard stylelint --config ../.github/config/stylelintrc.json "src/**/*.{css,scss}" + + python: + name: Python lint (Ruff + Pylint) + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + cache: pip + + - name: Install lint dependencies + run: | + python -m pip install --upgrade pip + pip install ruff pylint + + - name: Ruff + run: ruff check --config .github/config/pyproject.toml backend + + - name: Pylint + run: pylint --rcfile=.github/config/pylintrc backend + + pre-commit: + name: Pre-commit hooks + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + cache: pip + + - name: Install pre-commit + run: | + python -m pip install --upgrade pip + pip install pre-commit + + - name: Run pre-commit hooks + run: pre-commit run --config .github/config/pre-commit-config.yaml --all-files --show-diff-on-failure + + gitleaks: + name: Gitleaks + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Run gitleaks scan + uses: gitleaks/gitleaks-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 2b74bce9..bd98be61 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,9 @@ youtube_videos/ backend/podcast_images/ backend/podcast_videos/ +backend\alwrity.db + + backend/researchtools_text/projects/ youtube_avatars/ youtube_avatars/* @@ -241,3 +244,18 @@ docs/__pycache__/ backend/.onboarding_progress*.json backend/researchtools_text/projects/Draft__AI_advanc_c2f90698.json backend/researchtools_text/projects/Draft__AI_adv_388d4491.json +# Generated Media Content (MAJOR SIZE CONTRIBUTORS) +youtube_videos/ +podcast_images/ +podcast_audio/ +podcast_videos/ +story_audio/ +story_images/ +story_videos/ +transform_videos/ +researchtools_text/ + +# Backend Generated Images +backend/image_studio_images/ +backend/linkedin_images/ +backend/linkedin_images/** diff --git a/IMAGE_STUDIO_REVIEW.md b/IMAGE_STUDIO_REVIEW.md new file mode 100644 index 00000000..572621d5 --- /dev/null +++ b/IMAGE_STUDIO_REVIEW.md @@ -0,0 +1,80 @@ +# ALwrity Image Studio Review (End-User Perspective) + +## Scope Reviewed +This review is based on a code walkthrough of the Image Studio frontend modules, routing, hooks, and backend Image Studio routers/services. + +## What feels strong (as an end user) + +1. **Broad studio coverage in one place** + - The dashboard and module catalog expose a full visual workflow: creation, editing, upscaling, control, social optimization, processing, face swap, and asset library. +2. **Good UX framing and discoverability** + - The dashboard module cards include practical descriptions, highlights, and examples. This helps a non-technical marketer quickly choose the right tool. +3. **Strong backend modularity and service separation** + - The backend facade splits image workflows into generation, editing, advanced, and utilities routers. This is a good foundation for scale and maintainability. +4. **Coverage beyond generation** + - Image Studio includes practical post-processing capabilities (compression + format conversion), which are essential for publishing workflows. +5. **Cost-awareness signals exist** + - Cost estimate APIs and “preflight operation” patterns indicate cost transparency is a design consideration. + +## Robustness assessment + +### Positive robustness signals +- **Consistent top-level orchestration** via `ImageStudioManager`, which centralizes workflows for create/edit/upscale/control/social/transform/utilities. +- **Health and status endpoints** exist for operational introspection. +- **Input validation patterns** are visible in service layers (e.g., supported formats, platform validation), reducing invalid-request failures. + +### Robustness concerns / risks +1. **Transform Studio appears implemented but not route-mounted in app routing** + - The module list points to `/image-transform` and `TransformStudio` exists, but the route is not defined in `App.tsx`. + - End-user impact: users can see/expect this capability but may hit dead navigation or inaccessible feature entry. +2. **Mismatch between marketing copy and actual completion state in processing suite** + - Image Processing Studio advertises resizer/watermarking in copy but those tabs are disabled and marked “Coming Soon.” + - End-user impact: expectation gap and trust erosion. +3. **Create flow can return `success: true` even with failed variations** + - The generation loop captures per-variation exceptions and still returns success at the top-level with failure counts. + - End-user impact: ambiguous success state; users may think job completed fully when partial/total failure occurred. +4. **Operational observability is incomplete** + - `/metrics` is currently a placeholder, limiting production-level reliability visibility. +5. **Potentially stale pricing language in UI descriptors** + - Module cards contain highly specific pricing text while provider/model costs in service code are hard-coded estimates. + - End-user impact: confusion if invoiced pricing diverges from UI estimates. + +## Feature gaps observed (end-user lens) + +1. **No clearly surfaced asynchronous job UX for long-running transform workflows** + - Current hook/flow appears request-response centric; if generation times spike, users may need resilient background jobs, retries, and resumable status views. +2. **No integrated “workflow chaining” UX** + - A user likely wants: create → edit → upscale → social exports in a single guided flow with one asset lineage timeline. +3. **Limited confidence UX around failure states** + - Error messages exist, but there is room for richer recovery guidance (“try smaller resolution”, “switch model”, “reduce prompt complexity”). +4. **Expectation-setting around “planning” modules** + - Batch Processor is shown in dashboard catalog, but status is planning. That should be even more clearly gated for users. + +## Recommended enhancements (prioritized) + +### P0 (immediate trust & usability) +1. **Fix Transform Studio route parity** + - Add route or hide module until route is available. +2. **Harden top-level success semantics in Create Studio** + - Return `success: false` when all variations fail; return partial status explicitly when mixed. +3. **Align UI claims with implementation state** + - Mark resizer/watermark features as roadmap-only in all surfaces where they are advertised. + +### P1 (reliability & user confidence) +4. **Introduce first-class async jobs for transform operations** + - Add job IDs, polling/websocket updates, resumable results, and queued/cancel states. +5. **Improve error recovery UX** + - Map backend error classes to actionable UI advice. +6. **Replace static pricing snippets with backend-driven dynamic cost cards** + - Display estimate confidence and update timestamps. + +### P2 (delight & retention) +7. **Add guided “Campaign Asset Pipeline”** + - Single wizard chaining Create/Edit/Upscale/Social export with saved presets per brand/persona. +8. **Add quality scorecards per output** + - Platform compliance score, file-weight score, readability-safe-zone score. +9. **Add version compare + rollback in Asset Library** + - Better creative iteration experience. + +## End-user verdict +Image Studio is **feature-rich and architecturally promising**, especially with its modular backend and multi-tool surface. However, there are **critical product-polish gaps** (route parity, claim-vs-availability mismatches, ambiguous success semantics) that can weaken user trust. Fixing those quickly would materially improve perceived robustness and adoption. diff --git a/ToBeMigrated/legacy_backlinker/App.css b/ToBeMigrated/legacy_backlinker/App.css new file mode 100644 index 00000000..b9d355df --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/App.css @@ -0,0 +1,42 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} diff --git a/ToBeMigrated/legacy_backlinker/App.tsx b/ToBeMigrated/legacy_backlinker/App.tsx new file mode 100644 index 00000000..0c7cf78a --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/App.tsx @@ -0,0 +1,31 @@ +import { Toaster } from "@/components/ui/toaster"; +import { Toaster as Sonner } from "@/components/ui/sonner"; +import { TooltipProvider } from "@/components/ui/tooltip"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { BrowserRouter, Routes, Route } from "react-router-dom"; +import Index from "./pages/Index"; +import NotFound from "./pages/NotFound"; +import Dashboard from "./pages/Dashboard"; +import NewCampaign from "./pages/NewCampaign"; + +const queryClient = new QueryClient(); + +const App = () => ( + + + + + + + } /> + } /> + } /> + {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */} + } /> + + + + +); + +export default App; diff --git a/ToBeMigrated/legacy_backlinker/assets/ai-brain-icon.png b/ToBeMigrated/legacy_backlinker/assets/ai-brain-icon.png new file mode 100644 index 00000000..fa2eb2a8 Binary files /dev/null and b/ToBeMigrated/legacy_backlinker/assets/ai-brain-icon.png differ diff --git a/ToBeMigrated/legacy_backlinker/assets/neural-network-hero.jpg b/ToBeMigrated/legacy_backlinker/assets/neural-network-hero.jpg new file mode 100644 index 00000000..86d602ab Binary files /dev/null and b/ToBeMigrated/legacy_backlinker/assets/neural-network-hero.jpg differ diff --git a/ToBeMigrated/legacy_backlinker/components/comparison-section.tsx b/ToBeMigrated/legacy_backlinker/components/comparison-section.tsx new file mode 100644 index 00000000..79a97fb0 --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/comparison-section.tsx @@ -0,0 +1,103 @@ +import { motion } from "framer-motion"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { CheckCircle2, XCircle, Brain, Mail, Globe, Network, BarChart3, UserCheck } from "lucide-react"; + +export const ComparisonSection = () => { + const manual = [ + "Manual Google searches, endless tabs", + "Copy-paste emails scraped by hand", + "Generic outreach with low replies", + "No domain authority prioritization", + "Spreadsheet chaos, hard to track", + "Slow follow-ups and missed windows" + ]; + + const ai = [ + "AI web research finds and refines prospects", + "Auto-scrapes verified contacts and roles", + "Personalized AI emails for each prospect", + "DA ranking + semantic relevance scoring", + "Integrated sending + response intelligence", + "Human-in-the-loop reviews where it matters" + ]; + + return ( +
+
+ +

+ From Manual Grind to AI-First Backlinking +

+

+ ALwrity Backlinker revolutionizes traditional backlinking by automating research, outreach, and analysis with powerful AI. +

+
+ +
+ {/* Manual */} + + + + + + Traditional Manual Backlinking + + + +
    + {manual.map((item, i) => ( +
  • + + {item} +
  • + ))} +
+
+
+
+ + {/* AI */} + + + + + + ALwrity AI-First Backlinker + + + +
    + {ai.map((item, i) => ( +
  • + + {item} +
  • + ))} +
+
+ {[ + { icon: Network, label: "Prospects refined by AI" }, + { icon: Mail, label: "Personalized outreach at scale" }, + { icon: BarChart3, label: "Replies analyzed for collabs" } + ].map((k, i) => ( +
+ + {k.label} +
+ ))} +
+
Includes human-in-the-loop reviews for final send and approvals.
+
+
+
+
+
+
+ ); +}; diff --git a/ToBeMigrated/legacy_backlinker/components/dashboard-preview.tsx b/ToBeMigrated/legacy_backlinker/components/dashboard-preview.tsx new file mode 100644 index 00000000..9d0e91bb --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/dashboard-preview.tsx @@ -0,0 +1,201 @@ +import { motion } from "framer-motion"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Badge } from "@/components/ui/badge"; +import { + Search, + Mail, + TrendingUp, + Users, + Globe, + Zap, + Eye, + Send, + CheckCircle, + Clock +} from "lucide-react"; + +export const DashboardPreview = () => { + const containerVariants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.1 + } + } + }; + + const itemVariants = { + hidden: { opacity: 0, y: 20 }, + visible: { opacity: 1, y: 0 } + }; + + return ( +
+
+ +

+ AI-Driven{" "} + + Workflow + +

+

+ Experience the power of automated backlinking with our intelligent dashboard +

+
+ + + {/* Keyword Research Card */} + + + + + + Keyword Discovery + + + +
+ + +
+
+ {["AI tools", "content marketing", "SEO strategies"].map((keyword, index) => ( +
+ {keyword} + + {Math.floor(Math.random() * 500) + 100} ops + +
+ ))} +
+
+
+
+ + {/* Opportunities Card */} + + + + + + Found Opportunities + + + + {[ + { site: "TechBlog.com", da: 85, status: "pending" }, + { site: "AIInsights.org", da: 72, status: "contacted" }, + { site: "MarketingPro.net", da: 68, status: "replied" } + ].map((opp, index) => ( +
+
+ {opp.site} + + DA {opp.da} + +
+
+ {opp.status === "pending" && } + {opp.status === "contacted" && } + {opp.status === "replied" && } + {opp.status} +
+
+ ))} +
+
+
+ + {/* Email Campaign Card */} + + + + + + AI Outreach + + + +
+
AI Generated Subject
+
Guest Post Collaboration Opportunity
+
+
+
Personalized Content
+
+ "Hi Sarah, I noticed your recent article on AI automation was excellent. + I'd love to contribute a piece on..." +
+
+
+ + +
+
+
+
+ + {/* Analytics Card - Full Width */} + + + + + + Campaign Analytics + + + +
+ {[ + { label: "Emails Sent", value: "247", icon: Send, color: "text-blue-500" }, + { label: "Responses", value: "89", icon: Mail, color: "text-green-500" }, + { label: "Backlinks", value: "34", icon: CheckCircle, color: "text-purple-500" }, + { label: "Success Rate", value: "36%", icon: TrendingUp, color: "text-accent" } + ].map((stat, index) => ( + + +
{stat.value}
+
{stat.label}
+
+ ))} +
+
+
+
+
+
+
+ ); +}; \ No newline at end of file diff --git a/ToBeMigrated/legacy_backlinker/components/dashboard/analytics-summary.tsx b/ToBeMigrated/legacy_backlinker/components/dashboard/analytics-summary.tsx new file mode 100644 index 00000000..63dceba2 --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/dashboard/analytics-summary.tsx @@ -0,0 +1,109 @@ + +import { motion } from "framer-motion"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { + TrendingUp, + Mail, + Users, + CheckCircle, + Globe, + Eye, + MessageSquare, + Target +} from "lucide-react"; + +export const AnalyticsSummary = () => { + const stats = [ + { + title: "Total Prospects", + value: "1,247", + change: "+12.5%", + icon: Users, + color: "text-primary" + }, + { + title: "Emails Sent", + value: "856", + change: "+8.3%", + icon: Mail, + color: "text-secondary" + }, + { + title: "Response Rate", + value: "24.8%", + change: "+3.2%", + icon: MessageSquare, + color: "text-accent" + }, + { + title: "Backlinks Secured", + value: "187", + change: "+15.7%", + icon: CheckCircle, + color: "text-primary" + }, + { + title: "Domain Authority Avg", + value: "68.5", + change: "+2.1%", + icon: Globe, + color: "text-secondary" + }, + { + title: "Open Rate", + value: "42.3%", + change: "+5.4%", + icon: Eye, + color: "text-accent" + }, + { + title: "Active Campaigns", + value: "12", + change: "+2", + icon: Target, + color: "text-primary" + }, + { + title: "Conversion Rate", + value: "18.6%", + change: "+4.1%", + icon: TrendingUp, + color: "text-secondary" + } + ]; + + return ( + + + + + + Campaign Analytics Overview + + + +
+ {stats.map((stat, index) => ( + +
+ +
{stat.value}
+
{stat.title}
+
{stat.change}
+
+
+ ))} +
+
+
+
+ ); +}; diff --git a/ToBeMigrated/legacy_backlinker/components/dashboard/collaboration-tracker.tsx b/ToBeMigrated/legacy_backlinker/components/dashboard/collaboration-tracker.tsx new file mode 100644 index 00000000..fa4ddae8 --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/dashboard/collaboration-tracker.tsx @@ -0,0 +1,271 @@ + +import { motion } from "framer-motion"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"; +import { + Handshake, + CheckCircle, + Clock, + AlertTriangle, + Eye, + MessageSquare, + Link, + Calendar, + Hash, + Reply, + Lightbulb, + Target, + Brain, + Users +} from "lucide-react"; + +export const CollaborationTracker = () => { + const collaborations = [ + { + domain: "techcrunch.com", + contact: "Sarah Johnson", + status: "in_progress", + type: "Guest Post", + deadline: "2024-01-15", + lastUpdate: "Received draft outline", + priority: "high", + campaign: "AI Tools Guest Posts", + keywords: ["AI content marketing", "automation tools"], + lastReply: "Thanks for the detailed outline. We'd like to proceed with the guest post. Can you provide the full draft by next week?", + aiInsight: "High engagement potential. Editor responded positively. Website analysis shows strong editorial standards and high-quality guest content." + }, + { + domain: "contentmarketing.org", + contact: "Mike Chen", + status: "review_needed", + type: "Resource Link", + deadline: "2024-01-20", + lastUpdate: "Human review required", + priority: "medium", + campaign: "Content Marketing Outreach", + keywords: ["content optimization", "SEO automation"], + lastReply: "We're interested but need to review your content quality first. Please send some sample articles for our editorial team.", + aiInsight: "Cautious but interested response. They have strict content guidelines. Previous successful placements suggest good conversion potential." + }, + { + domain: "aitrends.net", + contact: "Lisa Rodriguez", + status: "completed", + type: "Case Study", + deadline: "2024-01-10", + lastUpdate: "Published successfully", + priority: "low", + campaign: "AI Tools Case Studies", + keywords: ["machine learning", "digital marketing AI"], + lastReply: "Case study is now live! Here's the link: aitrends.net/case-studies/alwrity-ai-success. Great collaboration!", + aiInsight: "Successful completion. High-quality backlink secured from DA 65 domain. Strong referral traffic potential. Consider for future partnerships." + }, + { + domain: "marketingland.com", + contact: "David Park", + status: "negotiating", + type: "Expert Quote", + deadline: "2024-01-25", + lastUpdate: "Discussing terms", + priority: "high", + campaign: "Expert Authority Building", + keywords: ["marketing automation", "AI tools"], + lastReply: "We can feature you as an expert, but we'll need you to provide insights on 3 different topics. Are you available for a 30-min interview?", + aiInsight: "Opportunity for thought leadership positioning. High-authority domain (DA 88). Interview format suggests potential for multiple quote placements." + } + ]; + + const getStatusIcon = (status: string) => { + switch (status) { + case "completed": return ; + case "in_progress": return ; + case "review_needed": return ; + case "negotiating": return ; + default: return ; + } + }; + + const getPriorityColor = (priority: string) => { + switch (priority) { + case "high": return "bg-red-500"; + case "medium": return "bg-yellow-500"; + case "low": return "bg-green-500"; + default: return "bg-gray-500"; + } + }; + + return ( + + + +
+ + + Collaboration Tracker + +
+ + + 4 Active + + + + AI Reviews + +
+
+
+ + + + +
+
+ + Active Collaborations +
+ + Human-in-Loop + +
+
+ +
+ {collaborations.map((collab, index) => ( + +
+
+
+ {getStatusIcon(collab.status)} +
+
+ {collab.domain} +
{collab.contact}
+
+
+
+
+ + {collab.type} + +
+
+ +
+
Campaign:
+ + {collab.campaign} + +
+ +
+
Target Keywords:
+
+ {collab.keywords.map((keyword, idx) => ( + + + {keyword} + + ))} +
+
+ +
+
+ +
Last Reply:
+
+
"{collab.lastReply}"
+
+ +
+
+ +
AI Insight:
+
+
{collab.aiInsight}
+
+ +
+
+ Deadline: + + + {collab.deadline} + +
+
+ +
+ + {collab.status === "review_needed" && ( + + )} + {collab.status === "completed" && ( + + )} + {collab.status === "negotiating" && ( + + )} + {collab.status === "in_progress" && ( + + )} +
+ + ))} +
+ +
+
+
+

AI Analysis Summary

+

+ 2 collaborations need human review • 1 high-priority deadline approaching +

+
+ ✓ 1 Completed + ⏳ 1 In Progress + ⚠ 1 Review Needed + 💬 1 Negotiating +
+
+ +
+
+ + + + + +
+ ); +}; diff --git a/ToBeMigrated/legacy_backlinker/components/dashboard/dashboard-header.tsx b/ToBeMigrated/legacy_backlinker/components/dashboard/dashboard-header.tsx new file mode 100644 index 00000000..305b81e3 --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/dashboard/dashboard-header.tsx @@ -0,0 +1,42 @@ + +import { motion } from "framer-motion"; +import { Button } from "@/components/ui/button"; +import { Brain, Zap, Plus, Settings } from "lucide-react"; + +export const DashboardHeader = () => { + return ( + +
+
+
+
+ +
+
+

AI Backlinking Dashboard

+

Automated lead generation & outreach campaigns

+
+
+
+ + + +
+
+
+
+ ); +}; diff --git a/ToBeMigrated/legacy_backlinker/components/dashboard/email-campaigns.tsx b/ToBeMigrated/legacy_backlinker/components/dashboard/email-campaigns.tsx new file mode 100644 index 00000000..08bf8293 --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/dashboard/email-campaigns.tsx @@ -0,0 +1,177 @@ + +import { motion } from "framer-motion"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"; +import { Mail, Send, Eye, Edit, Brain, Users, TrendingUp, Zap, Activity } from "lucide-react"; +import { useNavigate } from "react-router-dom"; + +export const EmailCampaigns = () => { + const navigate = useNavigate(); + + const campaigns = [ + { + name: "AI Tools Guest Posts", + status: "active", + sent: 45, + opened: 28, + replied: 12, + prospects: 67, + lastActivity: "2 hours ago" + }, + { + name: "Content Marketing Outreach", + status: "paused", + sent: 32, + opened: 18, + replied: 8, + prospects: 89, + lastActivity: "1 day ago" + }, + { + name: "SEO Expert Quotes", + status: "draft", + sent: 0, + opened: 0, + replied: 0, + prospects: 23, + lastActivity: "3 hours ago" + } + ]; + + const getStatusColor = (status: string) => { + switch (status) { + case "active": return "bg-green-500"; + case "paused": return "bg-yellow-500"; + case "draft": return "bg-blue-500"; + default: return "bg-gray-500"; + } + }; + + return ( + + + +
+ + + AI Email Campaigns + +
+ + + 3 Campaigns + + + + 28% Reply Rate + +
+
+
+ + + + +
+
+ + Active Email Campaigns +
+ + AI Powered + +
+
+ +
+ {campaigns.map((campaign, index) => ( + +
+
+
+ {campaign.name} +
+ + {campaign.status} + +
+ +
+
+
{campaign.sent}
+
Sent
+
+
+
{campaign.replied}
+
Replies
+
+
+ +
+ + + {campaign.prospects} prospects + + + + {campaign.opened > 0 ? Math.round((campaign.opened / campaign.sent) * 100) : 0}% open + +
+ +
+ + {campaign.status === "draft" ? ( + + ) : ( + + )} +
+ + ))} +
+ +
+ + +
+ + + + + +
+ ); +}; diff --git a/ToBeMigrated/legacy_backlinker/components/dashboard/keyword-research.tsx b/ToBeMigrated/legacy_backlinker/components/dashboard/keyword-research.tsx new file mode 100644 index 00000000..18a4ce5b --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/dashboard/keyword-research.tsx @@ -0,0 +1,126 @@ + +import { motion } from "framer-motion"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Badge } from "@/components/ui/badge"; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"; +import { Search, Zap, TrendingUp, Plus, Brain, Target, Sparkles } from "lucide-react"; +import { useNavigate } from "react-router-dom"; + +export const KeywordResearch = () => { + const navigate = useNavigate(); + + const keywords = [ + { term: "AI content marketing", volume: 12500, difficulty: "Medium", opportunities: 45 }, + { term: "SEO automation tools", volume: 8900, difficulty: "High", opportunities: 23 }, + { term: "Content optimization", volume: 15600, difficulty: "Low", opportunities: 67 }, + { term: "Digital marketing AI", volume: 9800, difficulty: "Medium", opportunities: 34 } + ]; + + return ( + + + +
+ + + AI Keyword Research + +
+ + + 4 Active + + + + 169 Opportunities + +
+
+
+ + + + +
+
+ + AI Research & Suggestions +
+ + Live + +
+
+ +
+ + +
+ +
+
+

Active Keywords

+ +
+ + {keywords.map((keyword, index) => ( + +
+ {keyword.term} + + {keyword.difficulty} + +
+
+ Vol: {keyword.volume.toLocaleString()} + + + {keyword.opportunities} ops + +
+
+ ))} +
+ + +
+
+
+
+
+
+ ); +}; diff --git a/ToBeMigrated/legacy_backlinker/components/dashboard/prospect-analysis.tsx b/ToBeMigrated/legacy_backlinker/components/dashboard/prospect-analysis.tsx new file mode 100644 index 00000000..2010b0f2 --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/dashboard/prospect-analysis.tsx @@ -0,0 +1,145 @@ + +import { motion } from "framer-motion"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"; +import { Globe, Brain, CheckCircle, Clock, AlertCircle, Eye, Users, BarChart3 } from "lucide-react"; + +export const ProspectAnalysis = () => { + const prospects = [ + { + domain: "techcrunch.com", + da: 94, + status: "analyzed", + opportunity: "Guest Post", + confidence: 92, + contact: "editor@techcrunch.com" + }, + { + domain: "contentmarketing.org", + da: 78, + status: "pending", + opportunity: "Resource Link", + confidence: 85, + contact: "info@contentmarketing.org" + }, + { + domain: "aitrends.net", + da: 65, + status: "reviewing", + opportunity: "Case Study", + confidence: 78, + contact: "submissions@aitrends.net" + }, + { + domain: "marketingland.com", + da: 88, + status: "analyzed", + opportunity: "Expert Quote", + confidence: 88, + contact: "news@marketingland.com" + } + ]; + + const getStatusIcon = (status: string) => { + switch (status) { + case "analyzed": return ; + case "pending": return ; + case "reviewing": return ; + default: return ; + } + }; + + return ( + + + +
+ + + AI Prospect Analysis + +
+ + + 4 Analyzed + + + + 86% Avg Score + +
+
+
+ + + + +
+
+ + Refined Prospects +
+ + AI Scored + +
+
+ +
+ {prospects.map((prospect, index) => ( + +
+
+ {getStatusIcon(prospect.status)} + {prospect.domain} +
+ + DA {prospect.da} + +
+ +
+
+ Opportunity: +
{prospect.opportunity}
+
+
+ AI Score: +
{prospect.confidence}%
+
+
+ +
+ + {prospect.contact} + + +
+
+ ))} +
+ + +
+
+
+
+
+
+ ); +}; diff --git a/ToBeMigrated/legacy_backlinker/components/features-section.tsx b/ToBeMigrated/legacy_backlinker/components/features-section.tsx new file mode 100644 index 00000000..951e6082 --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/features-section.tsx @@ -0,0 +1,195 @@ +import { motion } from "framer-motion"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { + Brain, + Search, + Mail, + BarChart, + Users, + Zap, + Globe, + Target, + Shield +} from "lucide-react"; + +export const FeaturesSection = () => { + const features = [ + { + icon: Search, + title: "Intelligent Discovery", + description: "AI-powered web scraping finds high-quality guest posting opportunities across the web", + gradient: "from-blue-500 to-cyan-500" + }, + { + icon: Brain, + title: "Neural Personalization", + description: "Advanced AI crafts personalized outreach emails tailored to each target website", + gradient: "from-purple-500 to-pink-500" + }, + { + icon: Mail, + title: "Automated Outreach", + description: "Streamlined email campaigns with follow-up automation and response tracking", + gradient: "from-green-500 to-emerald-500" + }, + { + icon: BarChart, + title: "Advanced Analytics", + description: "Real-time performance metrics, open rates, and backlink success tracking", + gradient: "from-orange-500 to-red-500" + }, + { + icon: Users, + title: "Lead Management", + description: "Comprehensive contact database with status tracking and relationship management", + gradient: "from-indigo-500 to-blue-500" + }, + { + icon: Zap, + title: "Batch Processing", + description: "Handle multiple keywords and campaigns simultaneously for maximum efficiency", + gradient: "from-yellow-500 to-orange-500" + }, + { + icon: Globe, + title: "Global Reach", + description: "Find opportunities across multiple languages and geographic regions", + gradient: "from-teal-500 to-cyan-500" + }, + { + icon: Target, + title: "Smart Targeting", + description: "AI algorithms identify the most promising prospects based on domain authority and relevance", + gradient: "from-rose-500 to-pink-500" + }, + { + icon: Shield, + title: "Safe & Compliant", + description: "Built-in safeguards ensure ethical outreach practices and compliance with email regulations", + gradient: "from-slate-500 to-gray-500" + } + ]; + + const containerVariants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.1 + } + } + }; + + const itemVariants = { + hidden: { opacity: 0, y: 20 }, + visible: { + opacity: 1, + y: 0, + transition: { + duration: 0.5 + } + } + }; + + return ( +
+ {/* Background pattern */} +
+
+
+ +
+ +

+ Powered by{" "} + + Advanced AI + +

+

+ Every feature is enhanced with machine learning algorithms to maximize your backlinking success +

+
+ + + {features.map((feature, index) => ( + + + +
+
+ +
+
+ + {feature.title} + +
+ +

+ {feature.description} +

+
+
+
+ ))} +
+ + {/* Bottom CTA */} + +
+

+ Ready to Transform Your Link Building? +

+

+ Join thousands of marketers using AI to build high-quality backlinks at scale +

+
+ + Start Free Trial + + + Book Demo + +
+
+
+
+
+ ); +}; \ No newline at end of file diff --git a/ToBeMigrated/legacy_backlinker/components/hero-section.tsx b/ToBeMigrated/legacy_backlinker/components/hero-section.tsx new file mode 100644 index 00000000..c6bae8d4 --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/hero-section.tsx @@ -0,0 +1,143 @@ +import { motion } from "framer-motion"; +import { Button } from "@/components/ui/button"; +import { ArrowRight, Zap, Brain, Network } from "lucide-react"; +import heroImage from "@/assets/neural-network-hero.jpg"; + +export const HeroSection = () => { + return ( +
+ {/* Background with neural network */} +
+ Neural Network Background +
+
+ + {/* Floating particles */} +
+ {Array.from({ length: 20 }).map((_, i) => ( + + ))} +
+ + {/* Main content */} +
+ + {/* Logo/Brand */} + +
+ +
+

+ ALwrity +

+
+ + + AI-Powered{" "} + + Backlinking + + + + + Automate your link building strategy with neural network intelligence. + Find opportunities, craft personalized outreach, and secure high-quality backlinks. + + + {/* Feature highlights */} + + {[ + { icon: Zap, text: "Automated Discovery" }, + { icon: Brain, text: "AI Personalization" }, + { icon: Network, text: "Smart Outreach" } + ].map((feature, index) => ( +
+ + {feature.text} +
+ ))} +
+ + {/* CTA Buttons */} + + + + + + {/* Stats */} + + {[ + { number: "10,000+", label: "Opportunities Found" }, + { number: "85%", label: "Response Rate" }, + { number: "3x", label: "Faster Outreach" } + ].map((stat, index) => ( +
+
{stat.number}
+
{stat.label}
+
+ ))} +
+
+
+
+ ); +}; \ No newline at end of file diff --git a/ToBeMigrated/legacy_backlinker/components/navigation.tsx b/ToBeMigrated/legacy_backlinker/components/navigation.tsx new file mode 100644 index 00000000..88f45b68 --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/navigation.tsx @@ -0,0 +1,80 @@ +import { useState } from "react"; +import { motion } from "framer-motion"; +import { Brain } from "lucide-react"; +import { Button } from "@/components/ui/button"; + +export const Navigation = () => { + const [isOpen, setIsOpen] = useState(false); + + return ( + +
+
+ +
+ +
+ + ALwrity Backlinker + +
+ + + +
+ +
+
+
+ + {isOpen && ( + + + + )} +
+ ); +}; diff --git a/ToBeMigrated/legacy_backlinker/components/pricing-section.tsx b/ToBeMigrated/legacy_backlinker/components/pricing-section.tsx new file mode 100644 index 00000000..5645fbbc --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/pricing-section.tsx @@ -0,0 +1,108 @@ +import { motion } from "framer-motion"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Button } from "@/components/ui/button"; +import { CheckCircle2, Sparkles, Shield, Zap } from "lucide-react"; + +export const PricingSection = () => { + const plans = [ + { + name: "Starter", + price: "$0", + period: "/mo", + highlight: "Get started with AI backlinking", + features: [ + "50 opportunity scans/mo", + "AI email drafts (basic)", + "Manual send", + "Basic analytics" + ], + cta: "Start Free", + variant: "neural" + }, + { + name: "Pro", + price: "$49", + period: "/mo", + highlight: "Scale campaigns with automation", + features: [ + "5k scans + batch processing", + "AI personalization + follow-ups", + "SMTP/Gmail integration", + "Response analysis" + ], + cta: "Upgrade", + variant: "ai" + }, + { + name: "Enterprise", + price: "Custom", + period: "", + highlight: "Advanced controls & SLAs", + features: [ + "Unlimited scans", + "Domain authority scoring", + "Human-in-the-loop workflow", + "SSO, Audit logs, SLAs" + ], + cta: "Contact Sales", + variant: "outline" + } + ]; + + return ( +
+
+ +

+ Pricing for Every Stage +

+

+ Start free. Scale with AI automation and enterprise controls when you need them. +

+
+ +
+ {plans.map((plan, i) => ( + + + +
+ {plan.name} + {i === 1 ? : null} +
+
+ {plan.price} + {plan.period} +
+
{plan.highlight}
+
+ +
    + {plan.features.map((f, idx) => ( +
  • + + {f} +
  • + ))} +
+
+ + {i === 2 ? : } +
+
+
+
+ ))} +
+
+
+ ); +}; diff --git a/ToBeMigrated/legacy_backlinker/components/ui/accordion.tsx b/ToBeMigrated/legacy_backlinker/components/ui/accordion.tsx new file mode 100644 index 00000000..e6a723d0 --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/ui/accordion.tsx @@ -0,0 +1,56 @@ +import * as React from "react" +import * as AccordionPrimitive from "@radix-ui/react-accordion" +import { ChevronDown } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Accordion = AccordionPrimitive.Root + +const AccordionItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AccordionItem.displayName = "AccordionItem" + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + svg]:rotate-180", + className + )} + {...props} + > + {children} + + + +)) +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName + +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +
{children}
+
+)) + +AccordionContent.displayName = AccordionPrimitive.Content.displayName + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/ToBeMigrated/legacy_backlinker/components/ui/alert-dialog.tsx b/ToBeMigrated/legacy_backlinker/components/ui/alert-dialog.tsx new file mode 100644 index 00000000..8722561c --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/ui/alert-dialog.tsx @@ -0,0 +1,139 @@ +import * as React from "react" +import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" + +import { cn } from "@/lib/utils" +import { buttonVariants } from "@/components/ui/button" + +const AlertDialog = AlertDialogPrimitive.Root + +const AlertDialogTrigger = AlertDialogPrimitive.Trigger + +const AlertDialogPortal = AlertDialogPrimitive.Portal + +const AlertDialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName + +const AlertDialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + +)) +AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName + +const AlertDialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +AlertDialogHeader.displayName = "AlertDialogHeader" + +const AlertDialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +AlertDialogFooter.displayName = "AlertDialogFooter" + +const AlertDialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName + +const AlertDialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogDescription.displayName = + AlertDialogPrimitive.Description.displayName + +const AlertDialogAction = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName + +const AlertDialogCancel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName + +export { + AlertDialog, + AlertDialogPortal, + AlertDialogOverlay, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel, +} diff --git a/ToBeMigrated/legacy_backlinker/components/ui/alert.tsx b/ToBeMigrated/legacy_backlinker/components/ui/alert.tsx new file mode 100644 index 00000000..41fa7e05 --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/ui/alert.tsx @@ -0,0 +1,59 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const alertVariants = cva( + "relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground", + { + variants: { + variant: { + default: "bg-background text-foreground", + destructive: + "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +const Alert = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & VariantProps +>(({ className, variant, ...props }, ref) => ( +
+)) +Alert.displayName = "Alert" + +const AlertTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +AlertTitle.displayName = "AlertTitle" + +const AlertDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +AlertDescription.displayName = "AlertDescription" + +export { Alert, AlertTitle, AlertDescription } diff --git a/ToBeMigrated/legacy_backlinker/components/ui/aspect-ratio.tsx b/ToBeMigrated/legacy_backlinker/components/ui/aspect-ratio.tsx new file mode 100644 index 00000000..c4abbf37 --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/ui/aspect-ratio.tsx @@ -0,0 +1,5 @@ +import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" + +const AspectRatio = AspectRatioPrimitive.Root + +export { AspectRatio } diff --git a/ToBeMigrated/legacy_backlinker/components/ui/avatar.tsx b/ToBeMigrated/legacy_backlinker/components/ui/avatar.tsx new file mode 100644 index 00000000..991f56ec --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/ui/avatar.tsx @@ -0,0 +1,48 @@ +import * as React from "react" +import * as AvatarPrimitive from "@radix-ui/react-avatar" + +import { cn } from "@/lib/utils" + +const Avatar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +Avatar.displayName = AvatarPrimitive.Root.displayName + +const AvatarImage = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AvatarImage.displayName = AvatarPrimitive.Image.displayName + +const AvatarFallback = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName + +export { Avatar, AvatarImage, AvatarFallback } diff --git a/ToBeMigrated/legacy_backlinker/components/ui/badge.tsx b/ToBeMigrated/legacy_backlinker/components/ui/badge.tsx new file mode 100644 index 00000000..f000e3ef --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/ui/badge.tsx @@ -0,0 +1,36 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const badgeVariants = cva( + "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", + secondary: + "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +
+ ) +} + +export { Badge, badgeVariants } diff --git a/ToBeMigrated/legacy_backlinker/components/ui/breadcrumb.tsx b/ToBeMigrated/legacy_backlinker/components/ui/breadcrumb.tsx new file mode 100644 index 00000000..71a5c325 --- /dev/null +++ b/ToBeMigrated/legacy_backlinker/components/ui/breadcrumb.tsx @@ -0,0 +1,115 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { ChevronRight, MoreHorizontal } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Breadcrumb = React.forwardRef< + HTMLElement, + React.ComponentPropsWithoutRef<"nav"> & { + separator?: React.ReactNode + } +>(({ ...props }, ref) =>