diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 8150a1a..fd50ef8 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,9 +1,4 @@ # These are supported funding model platforms - -github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: leifermendez open_collective: bot-whatsapp -ko_fi: # Replace with a single Ko-fi username -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +patreon: leifermendez custom: https://www.buymeacoffee.com/leifermendez diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 176cfc7..39adff0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,25 @@ # CONTRIBUTING +### 📄 Bienvenido/a +Si deseas colaborar con el proyecto existen varias maneras, la primera de ellas es aportando conocimiento y mejorando el repositorio (actualizando documentación, mejorando código, revisando __[issues](https://github.com/codigoencasa/bot-whatsapp/issues)__, etc). + + También es bien recibido los aportes económicos que se utilizaran para diferentes fines __[ver más](https://opencollective.com/bot-whatsapp)__ + +El lenguaje principal que se utilizó para desarrollar este proyecto fue __JavaScript__ con el fin de qué personas que están iniciando en el mundo de la programación puedan entender fácilmente. + + +### 🤔 Preguntas frecuentes +- ¿Como puedo hacer aportaciones de código en el proyecto?: [Ver Video](https://youtu.be/Lxt8Acob6aU) +- ¿Como ejecutar el entorno de pruebas?: [Ver Video](https://youtu.be/Mf9V-dloBfk) +- ¿Como crear un nuevo proveedor?: [Ver Video](https://youtu.be/cahK9zH3SI8) +- ¿Que son los GithubActions?: [Ver Video](https://youtu.be/nYBEBFKLiqw) +- ¿Canales de comunicación?: [Discord](https://link.codigoencasa.com/DISCORD) + +----- + ![](https://i.giphy.com/media/ntMt6TvalpstTIx7Ak/giphy.webp) + __Requerimientos:__ - Node v16 o superior __[descargar node](https://nodejs.org/es/download/)__ - __[Yarn](https://classic.yarnpkg.com/lang/en/docs/install/#windows-stable)__ como gestor de paquetes. En el link conseguirás las intrucciones para instalar yarn. @@ -75,14 +93,8 @@ En la consola encontraras los pasos a seguir --> ![](https://i.imgur.com/dC6lEwy.png) -### 🤔 Preguntas frecuentes -- ¿Como puedo hacer aportaciones de código en el proyecto?: [Ver Video](https://youtu.be/Lxt8Acob6aU) -- ¿Como ejecutar el entorno de pruebas?: [Ver Video](https://youtu.be/Mf9V-dloBfk) -- ¿Como crear un nuevo proveedor?: [Ver Video](https://youtu.be/cahK9zH3SI8) -- ¿Que son los GithubActions?: [Ver Video](https://youtu.be/nYBEBFKLiqw) - - -> __NOTA:__ Documento en constante actualización.... +> __NOTA:__ [Eres libre de aportar informacion a este documento o arreglar ortografia 🤣]( +https://github.com/codigoencasa/bot-whatsapp/edit/dev/CONTRIBUTING.md) ------ - [Discord](https://link.codigoencasa.com/DISCORD) diff --git a/MIGRATION.md b/MIGRATION.md index 5b5086e..8e4d1b4 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1,8 +1,13 @@ -## MIGRANDO DE LA VERSIÓN 1 A LAS VERSIÓN 2 +# Migración -Pasar los flujos del bot de la versión 1 a la 2 es muy fácil, supongamos que en tu initial.json y response.json tienes un flujo como el siguiente: +#### Versión (legacy) -```js +En la ***versión (legacy)*** se implementas los flujos de esta manera, en dos archivos independientes. + +> __`initial.json`__ para establecer las palabras claves y el flujo a responder, por otro lado tambien se necesitaba implementar. +> __`response.json`__ donde se escriben los mensajes a responder. + +```json //initial.json [ { @@ -13,15 +18,21 @@ Pasar los flujos del bot de la versión 1 a la 2 es muy fácil, supongamos que e ], "key": "hola" }, + { + "keywords": ["productos", "info"], + "key": "productos" + }, { "keywords": ["adios", "bye"], "key": "adios" + }, + { + "keywords": ["imagen", "foto"], + "key": "catalogo" } ] ``` -y - -```js +```json //response.json { "hola":{ @@ -35,34 +46,77 @@ y "replyMessage":[ "Que te vaya bien!!" ], - "media":null - } + }, + "productos":{ + "replyMessage":[ + "Más productos aquí" + ], + "trigger":null, + "actions":{ + "title":"¿Que te interesa ver?", + "message":"Abajo unos botons", + "footer":"", + "buttons":[ + {"body":"Telefonos"}, + {"body":"Computadoras"}, + {"body":"Otros"} + ] + } + }, + "catalogo":{ + "replyMessage":[ + "Te envio una imagen" + ], + "media":"https://media2.giphy.com/media/VQJu0IeULuAmCwf5SL/giphy.gif", + "trigger":null, + }, + } + ``` -En la versión 2, no es necesario tener esos 2 archivos, los flujos se ponen directamente en app.js de la siguiente manera: + +#### Versión 2 (0.2.X) + +En esta versión es mucho más sencillo abajo encontraras un ejemplo del mismo flujo anteriormente mostrado. ```js //app.js +const { + createBot, + createProvider, + createFlow, + addKeyword, + addChild, +} = require('@bot-whatsapp/bot') + +const BaileysProvider = require('@bot-whatsapp/provider/baileys') +const MockAdapter = require('@bot-whatsapp/database/mock') /** * Declarando flujos principales. */ -const flowHola = addKeyword(['hola', 'ola', 'alo']) //Aqui van los "keywords" de initial.json - .addAnswer('Gracias a ti!') // Aquí va la respuesta del response.json, no es necesario especificar nuevamente los "keywords" - .addAnswer('Siempre un placer!!!') // Y se pueden agregar varias respuestas encadenadas ... TANTAS com sean necesarias. +const flowHola = addKeyword(['hola', 'ola', 'alo']) + .addAnswer('Bienvenido a tu tienda online!') -const flowAdios = addKeyword(['adios', 'bye']) //Aqui van los "keywords" de initial.json - .addAnswer('Que te vaya bien!!') // Aquí va la respuesta del response.json, no es necesario especificar nuevamente los "keywords" - .addAnswer('Hasta luego!', // Y se pueden agregar varias respuestas encadenadas ... TANTAS com sean necesarias. - null, null,[...addChild(flowHijo1)] // Y se pueden agregar flujos HIJOS (Sub Menus). Los flujos hijos se tienen que definir ANTES que los principales. - ) +const flowAdios = addKeyword(['adios', 'bye']) + .addAnswer('Que te vaya bien!!') + .addAnswer('Hasta luego!') +const flowProductos = addKeyword(['productos', 'info']) + .addAnswer('Te envio una imagen', { + buttons:[ + {body:"Telefonos"}, + {body:"Computadoras"}, + {body:"Otros"} + ] + }) -##FALTAN EJEMPLOS DE ENVIOS DE IMAGENES! +const flowCatalogo = addKeyword(['imagen', 'foto']) + .addAnswer('Te envio una imagen', {media:'https://media2.giphy.com/media/VQJu0IeULuAmCwf5SL/giphy.gif'}) const main = async () => { const adapterDB = new MockAdapter() - const adapterFlow = createFlow([flowHola, flowAdios]) // Aqui se crean los flujos. + const adapterFlow = createFlow([flowHola, flowAdios, flowProductos, flowCatalogo]) const adapterProvider = createProvider(BaileysProvider) createBot({ flow: adapterFlow, @@ -70,4 +124,11 @@ const flowAdios = addKeyword(['adios', 'bye']) //Aqui van los "keywords" de init database: adapterDB, }) } - ``` \ No newline at end of file +``` + +> Forma parte de este proyecto. + +- [Discord](https://link.codigoencasa.com/DISCORD) +- [Twitter](https://twitter.com/leifermendez) +- [Youtube](https://www.youtube.com/watch?v=5lEMCeWEJ8o&list=PL_WGMLcL4jzWPhdhcUyhbFU6bC0oJd2BR) +- [Telegram](https://t.me/leifermendez) diff --git a/README.md b/README.md index 441cc16..9054e8d 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,15 @@ Video como hacer PR: https://youtu.be/Lxt8Acob6aU
Yonathan Suarez - + + + + jlferrete +
+ José Luis Ferrete +
+ + diff --git a/packages/bot/package.json b/packages/bot/package.json index 4079f55..b30e4b2 100644 --- a/packages/bot/package.json +++ b/packages/bot/package.json @@ -1,6 +1,6 @@ { "name": "@bot-whatsapp/bot", - "version": "0.0.24-alpha.0", + "version": "0.0.25-alpha.0", "description": "", "main": "./lib/bundle.bot.cjs", "scripts": { diff --git a/packages/cli/package.json b/packages/cli/package.json index 6e76ff6..dbefef2 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@bot-whatsapp/cli", - "version": "0.0.31-alpha.0", + "version": "0.0.32-alpha.0", "description": "", "main": "index.js", "devDependencies": { diff --git a/packages/create-bot-whatsapp/package.json b/packages/create-bot-whatsapp/package.json index 7cfa3ea..3e1f16a 100644 --- a/packages/create-bot-whatsapp/package.json +++ b/packages/create-bot-whatsapp/package.json @@ -1,6 +1,6 @@ { "name": "create-bot-whatsapp", - "version": "0.0.42-alpha.0", + "version": "0.0.43-alpha.0", "description": "", "main": "./lib/bundle.create-bot-whatsapp.cjs", "files": [ diff --git a/packages/database/package.json b/packages/database/package.json index cfe467d..bf869cb 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -1,6 +1,6 @@ { "name": "@bot-whatsapp/database", - "version": "0.0.23-alpha.0", + "version": "0.0.24-alpha.0", "description": "Esto es el conector a mysql, pg, mongo", "main": "./lib/mock/index.cjs", "keywords": [], @@ -12,8 +12,7 @@ "dependencies": { "dotenv": "^16.0.3", "mongodb": "^4.11.0", - "mysql2": "^2.3.3", - "stormdb": "^0.6.0" + "mysql2": "^2.3.3" }, "exports": { "./mock": "./lib/mock/index.cjs", diff --git a/packages/database/src/json/index.js b/packages/database/src/json/index.js index 7aa8029..cf09681 100644 --- a/packages/database/src/json/index.js +++ b/packages/database/src/json/index.js @@ -1,27 +1,42 @@ -const StormDB = require('stormdb') const { join } = require('path') - -const engine = new StormDB.localFileEngine(join(process.cwd(), './db.stormdb')) +const { existsSync, writeFileSync, readFileSync } = require('fs') class JsonFileAdapter { db + pathFile listHistory = [] constructor() { + this.pathFile = join(process.cwd(), 'db.json') this.init().then() } - init() { - return new Promise((resolve) => { - this.db = new StormDB(engine) - this.db.default({ history: [] }) - resolve(this.db) - }) + databaseExists() { + return existsSync(this.pathFile) + } + + async init() { + const dbExists = await this.databaseExists() + + if (!dbExists) { + const data = { + history: [], + } + await this.saveData(data) + } + } + + readDatabase() { + const db = readFileSync(this.pathFile) + return JSON.parse(db) + } + + saveData(data) { + writeFileSync(this.pathFile, JSON.stringify(data)) } getPrevByNumber = async (from) => { - const response = await this.db.get('history') - const { history } = response.state + const { history } = await this.readDatabase() if (!history.length) { return null @@ -35,12 +50,14 @@ class JsonFileAdapter { } save = async (ctx) => { - await this.db - .get('history') - .push({ ...ctx }) - .save() - console.log('Guardado en DB...', ctx) + this.db = await this.readDatabase() + + this.db.history.push(ctx) + + await this.saveData(this.db) + this.listHistory.push(ctx) + console.log('Guardado en DB...', ctx) } } diff --git a/packages/docs/.eslintrc.cjs b/packages/docs/.eslintrc.cjs index c31c7a9..32abdc8 100644 --- a/packages/docs/.eslintrc.cjs +++ b/packages/docs/.eslintrc.cjs @@ -6,35 +6,35 @@ module.exports = { node: true, }, extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:qwik/recommended', + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:qwik/recommended", ], - parser: '@typescript-eslint/parser', + parser: "@typescript-eslint/parser", parserOptions: { tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], + project: ["./tsconfig.json"], ecmaVersion: 2021, - sourceType: 'module', + sourceType: "module", ecmaFeatures: { jsx: true, }, }, - plugins: ['@typescript-eslint'], + plugins: ["@typescript-eslint"], rules: { - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-inferrable-types': 'off', - '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-empty-interface': 'off', - '@typescript-eslint/no-namespace': 'off', - '@typescript-eslint/no-empty-function': 'off', - '@typescript-eslint/no-this-alias': 'off', - '@typescript-eslint/ban-types': 'off', - '@typescript-eslint/ban-ts-comment': 'off', - 'prefer-spread': 'off', - 'no-case-declarations': 'off', - 'no-console': 'off', - '@typescript-eslint/no-unused-vars': ['error'], + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-empty-interface": "off", + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-this-alias": "off", + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/ban-ts-comment": "off", + "prefer-spread": "off", + "no-case-declarations": "off", + "no-console": "off", + "@typescript-eslint/no-unused-vars": ["error"], }, }; diff --git a/packages/docs/.gitignore b/packages/docs/.gitignore index b29623f..a88d7a8 100644 --- a/packages/docs/.gitignore +++ b/packages/docs/.gitignore @@ -5,7 +5,7 @@ /server # Development -node_modules +node_modules/ # Cache .cache @@ -37,5 +37,7 @@ lerna-debug.log* .yarn/* !.yarn/releases +package-lock.json + # Cloudflare functions/**/*.js diff --git a/packages/docs/.stackblitzrc b/packages/docs/.stackblitzrc new file mode 100644 index 0000000..43798ec --- /dev/null +++ b/packages/docs/.stackblitzrc @@ -0,0 +1,6 @@ +{ + "startCommand": "npm start", + "env": { + "ENABLE_CJS_IMPORTS": true + } +} \ No newline at end of file diff --git a/packages/docs/LICENSE.md b/packages/docs/LICENSE.md new file mode 100644 index 0000000..81566ba --- /dev/null +++ b/packages/docs/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 onWidget + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/docs/README.md b/packages/docs/README.md index 9948f9c..4c8a753 100644 --- a/packages/docs/README.md +++ b/packages/docs/README.md @@ -1,11 +1,287 @@ -### 😎 Documentación Bot-Whatsapp +# 💠 Qwind -👉 [https://bot-whatsapp.pages.dev/](https://bot-whatsapp.pages.dev/) +**Qwind** is a free and open-source template to make your website using **[Qwik](https://qwik.builder.io/) + [Tailwind CSS](https://tailwindcss.com/)**. Ready to start a new project and designed taking into account best practices. -Se esta iniciando una documentación oficial sobre como usar e implementar los diferentes funcionalidades del bot-wahtsapp +## Features +- ✅ Integration with **Tailwind CSS** supporting **Dark mode**. +- ✅ **Production-ready** scores in [Lighthouse](https://web.dev/measure/) and [PageSpeed Insights](https://pagespeed.web.dev/) reports. +- ✅ **Image optimization** and **Font optimization**. -La idea es cada usuario pueda ir aportando a la documentacion y formar parte de este proyecto. +
+Qwind Theme Screenshot -##### ¿Como agregar documentación? [Video] \ No newline at end of file +[![onWidget](https://custom-icon-badges.demolab.com/badge/made%20by%20-onWidget-556bf2?style=flat-square&logo=onwidget&logoColor=white&labelColor=101827)](https://onwidget.com) +[![License](https://img.shields.io/github/license/onwidget/qwind?style=flat-square&color=dddddd&labelColor=000000)](https://github.com/onwidget/qwind/blob/main/LICENSE.md) +[![Maintained](https://img.shields.io/badge/maintained%3F-yes-brightgreen.svg?style=flat-square)](https://github.com/onwidget) +[![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat-square)](https://github.com/onwidget/qwind#contributing) +[![Known Vulnerabilities](https://snyk.io/test/github/onwidget/qwind/badge.svg?style=flat-square)](https://snyk.io/test/github/onwidget/qwind) + +
+ +
+Table of Contents + +- [Demo](#demo) +- [Getting started](#getting-started) + - [Project structure](#project-structure) + - [Commands](#commands) + - [Configuration](#configuration) + - [Deploy](#deploy) +- [Roadmap](#roadmap) +- [Contributing](#contributing) +- [Acknowledgements](#acknowledgements) +- [License](#license) + +
+ +
+ +## Demo + +📌 [https://qwind.pages.dev/](https://qwind.pages.dev/) + +
+ +## Getting started + +This project is using Qwik with [QwikCity](https://qwik.builder.io/qwikcity/overview/). QwikCity is just a extra set of tools on top of Qwik to make it easier to build a full site, including directory-based routing, layouts, and more. + +### Project structure + +Inside **Qwind** template, you'll see the following folders and files: + +``` +/ +├── adaptors/ +| └── static/ +| └── vite.config.ts +├── public/ +│ ├── favicon.svg +│ ├── manifest.json +│ └── robots.txt +├── src/ +│ ├── assets/ +│ │ ├── images/ +| | └── styles/ +| | └── global.css +│ ├── components/ +│ │ ├── atoms/ +│ │ ├── core/ +│ │ ├── icons/ +| | └── widgets/ +| | ├── Header.astro +| | ├── Footer.astro +| | └── ... +│ ├── routes/ +│ | ├── blog/ +│ | ├── index.astro +| | ├── layout.tsx +| | └-- service-worker.ts +│ ├── config.mjs +│ ├── entry.dev.tsx +│ ├── entry.preview.tsx +│ ├── entry.ssr.tsx +│ └── root.tsx +├── package.json +└── ... +``` + +- `src/routes`: Provides the directory based routing, which can include a hierarchy of `layout.tsx` layout files, and an `index.tsx` file as the page. Additionally, `index.ts` files are endpoints. Please see the [routing docs](https://qwik.builder.io/qwikcity/routing/overview/) for more info. + +- `src/components`: Recommended directory for components. + +- `public`: Any static assets, like images, can be placed in the public directory. Please see the [Vite public directory](https://vitejs.dev/guide/assets.html#the-public-directory) for more info. + +[![Edit Qwind on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://githubbox.com/onwidget/qwind/tree/main) + +> **Seasoned qwik expert?** Delete this file. Update `config.mjs` and contents. Have fun! + +
+ +### Commands + +All commands are run from the root of the project, from a terminal: + +| Command | Action | +| :-------------------- | :------------------------------------------------- | +| `npm install` | Installs dependencies | +| `npm run dev` | Starts local dev server at `127.0.0.1:5173/` | +| `npm run build` | Build your production site to `./dist/` | +| `npm run preview` | Preview your build locally, before deploying | +| `npm run fmt` | Format codes with Prettier | +| `npm run lint` | Run Eslint | +| `npm run qwik ...` | Run CLI commands like `qwik add`, `qwik build` | + +
+ +### Configuration + +Basic configuration file: `./src/config.mjs` + +```javascript +export const SITE = { + name: 'Example', + + origin: 'https://example.com', + basePathname: '/', // Change this if you need to deploy to Github Pages, for example + trailingSlash: true, // Generate permalinks with or without "/" at the end +}; +``` + +
+ +### Deploy + +#### Deploy to production (manual) + +You can create an optimized production build with: + +```shell +npm run build +``` + +Now, your website is ready to be deployed. All generated files are located at +`dist` folder, which you can deploy the folder to any hosting service you +prefer. + +#### Deploy to Netlify + +Clone this repository on own GitHub account and deploy to Netlify: + +[![Netlify Deploy button](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/onwidget/qwind) + +#### Deploy to Vercel + +Clone this repository on own GitHub account and deploy to Vercel: + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fonwidget%2Fqwind) + +
+ +## Roadmap + +### Base +- [ ] Create utilities to generate permalinks tailored to the domain and base pathname. +- [ ] Simplify the way to optimize images. +- [ ] Create component to make SEO simpler and more intuitive. +- [ ] Create configurable blog with categories, tags and authors using MDX. +- [ ] Add more frequently used pages (Portfolio, Services, Contact, Docs ...). +- [ ] Find or create a library to have more icon sources available. +- [ ] Refactor some code that doesn't follow Qwik conventions yet. + +### Advanced + +- [ ] Achieve perfect 100% Google Page Speed score. +- [ ] Insert complex javascript example widget on home page to demonstrate Qwik features. +- [ ] Create small illustrative admin backend. + +
+ +## Contributing + +If you have any idea, suggestions or find any bugs, feel free to open a discussion, an issue or create a pull request. +That would be very useful for all of us and we would be happy to listen and take action. + +## Acknowledgements + +Initially created by [onWidget](https://onwidget.com) and maintained by a community of [contributors](https://github.com/onwidget/qwind/graphs/contributors). + +## License + +**Qwind** is licensed under the MIT license — see the [LICENSE](https://github.com/onwidget/qwind/blob/main/LICENSE.md) file for details. + +## Cloudflare Pages + +Cloudflare's [wrangler](https://github.com/cloudflare/wrangler) CLI can be used to preview a production build locally. To start a local server, run: + +``` +npm run serve +``` + +Then visit [http://localhost:8787/](http://localhost:8787/) + +### Deployments + +[Cloudflare Pages](https://pages.cloudflare.com/) are deployable through their [Git provider integrations](https://developers.cloudflare.com/pages/platform/git-integration/). + +If you don't already have an account, then [create a Cloudflare account here](https://dash.cloudflare.com/sign-up/pages). Next go to your dashboard and follow the [Cloudflare Pages deployment guide](https://developers.cloudflare.com/pages/framework-guides/deploy-anything/). + +Within the projects "Settings" for "Build and deployments", the "Build command" should be `npm run build`, and the "Build output directory" should be set to `dist`. + +### Function Invocation Routes + +Cloudflare Page's [function-invocation-routes config](https://developers.cloudflare.com/pages/platform/functions/function-invocation-routes/) can be used to include, or exclude, certain paths to be used by the worker functions. Having a `_routes.json` file gives developers more granular control over when your Function is invoked. +This is useful to determine if a page response should be Server-Side Rendered (SSR) or if the response should use a static-site generated (SSG) `index.html` file. + +By default, the Cloudflare pages adaptor _does not_ include a `public/_routes.json` config, but rather it is auto-generated from the build by the Cloudflare adaptor. An example of an auto-generate `dist/_routes.json` would be: + +``` +{ + "include": [ + "/*" + ], + "exclude": [ + "/_headers", + "/_redirects", + "/build/*", + "/favicon.ico", + "/manifest.json", + "/service-worker.js", + "/about" + ], + "version": 1 +} +``` + +In the above example, it's saying _all_ pages should be SSR'd. However, the root static files such as `/favicon.ico` and any static assets in `/build/*` should be excluded from the Functions, and instead treated as a static file. + +In most cases the generated `dist/_routes.json` file is ideal. However, if you need more granular control over each path, you can instead provide you're own `public/_routes.json` file. When the project provides its own `public/_routes.json` file, then the Cloudflare adaptor will not auto-generate the routes config and instead use the committed one within the `public` directory. + +## Cloudflare Pages + +Cloudflare's [wrangler](https://github.com/cloudflare/wrangler) CLI can be used to preview a production build locally. To start a local server, run: + +``` +npm run serve +``` + +Then visit [http://localhost:8787/](http://localhost:8787/) + +### Deployments + +[Cloudflare Pages](https://pages.cloudflare.com/) are deployable through their [Git provider integrations](https://developers.cloudflare.com/pages/platform/git-integration/). + +If you don't already have an account, then [create a Cloudflare account here](https://dash.cloudflare.com/sign-up/pages). Next go to your dashboard and follow the [Cloudflare Pages deployment guide](https://developers.cloudflare.com/pages/framework-guides/deploy-anything/). + +Within the projects "Settings" for "Build and deployments", the "Build command" should be `npm run build`, and the "Build output directory" should be set to `dist`. + +### Function Invocation Routes + +Cloudflare Page's [function-invocation-routes config](https://developers.cloudflare.com/pages/platform/functions/function-invocation-routes/) can be used to include, or exclude, certain paths to be used by the worker functions. Having a `_routes.json` file gives developers more granular control over when your Function is invoked. +This is useful to determine if a page response should be Server-Side Rendered (SSR) or if the response should use a static-site generated (SSG) `index.html` file. + +By default, the Cloudflare pages adaptor _does not_ include a `public/_routes.json` config, but rather it is auto-generated from the build by the Cloudflare adaptor. An example of an auto-generate `dist/_routes.json` would be: + +``` +{ + "include": [ + "/*" + ], + "exclude": [ + "/_headers", + "/_redirects", + "/build/*", + "/favicon.ico", + "/manifest.json", + "/service-worker.js", + "/about" + ], + "version": 1 +} +``` + +In the above example, it's saying _all_ pages should be SSR'd. However, the root static files such as `/favicon.ico` and any static assets in `/build/*` should be excluded from the Functions, and instead treated as a static file. + +In most cases the generated `dist/_routes.json` file is ideal. However, if you need more granular control over each path, you can instead provide you're own `public/_routes.json` file. When the project provides its own `public/_routes.json` file, then the Cloudflare adaptor will not auto-generate the routes config and instead use the committed one within the `public` directory. diff --git a/packages/docs/adaptors/static/vite.config.ts b/packages/docs/adaptors/static/vite.config.ts new file mode 100644 index 0000000..eeefc30 --- /dev/null +++ b/packages/docs/adaptors/static/vite.config.ts @@ -0,0 +1,21 @@ +import { staticAdaptor } from '@builder.io/qwik-city/adaptors/static/vite' +import { extendConfig } from '@builder.io/qwik-city/vite' +import baseConfig from '../../vite.config' + +import { SITE } from '../../src/config.mjs' + +export default extendConfig(baseConfig, () => { + return { + build: { + ssr: true, + rollupOptions: { + input: ['@qwik-city-plan'], + }, + }, + plugins: [ + staticAdaptor({ + origin: SITE.origin, + }), + ], + } +}) diff --git a/packages/docs/netlify.toml b/packages/docs/netlify.toml new file mode 100644 index 0000000..9324f51 --- /dev/null +++ b/packages/docs/netlify.toml @@ -0,0 +1,7 @@ +[build] + publish = "dist" + command = "npm run build" +[[headers]] + for = "/build/*" + [headers.values] + Cache-Control = "public, max-age=31536000, immutable" \ No newline at end of file diff --git a/packages/docs/package.json b/packages/docs/package.json index c5955ac..3b6c476 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -1,44 +1,50 @@ { - "name": "bot-whatsapp-docs", - "version": "0.0.1", - "description": "Basic start point to build a docs site with Qwik", - "engines": { - "node": ">=15.0.0" - }, - "private": true, - "scripts": { - "build": "qwik build", - "build.client": "vite build", - "build.preview": "vite build --ssr src/entry.preview.tsx", - "build.server": "vite build -c adaptors/cloudflare-pages/vite.config.ts", - "build.types": "tsc --incremental --noEmit", - "deploy": "wrangler pages dev ./dist", - "dev": "vite --mode ssr", - "dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force", - "fmt": "prettier --write .", - "fmt.check": "prettier --check .", - "lint": "eslint \"src/**/*.ts*\"", - "preview": "qwik build preview && vite preview --open", - "start": "vite --open --mode ssr", - "qwik": "qwik" - }, - "devDependencies": { - "@builder.io/qwik": "0.14.1", - "@builder.io/qwik-city": "0.0.127", - "@types/eslint": "8.4.10", - "@types/node": "latest", - "@typescript-eslint/eslint-plugin": "5.43.0", - "@typescript-eslint/parser": "5.43.0", - "autoprefixer": "10.4.11", - "eslint": "8.28.0", - "eslint-plugin-qwik": "0.14.1", - "node-fetch": "3.3.0", - "postcss": "^8.4.16", - "prettier": "2.7.1", - "tailwindcss": "^3.1.8", - "typescript": "4.9.3", - "vite": "3.2.4", - "vite-tsconfig-paths": "3.5.0", - "wrangler": "latest" - } + "name": "qwind", + "description": "A template to make your website using Qwik + Tailwind CSS.", + "version": "0.1.1", + "scripts": { + "build": "qwik build && npm run subfont", + "build.client": "vite build", + "build.preview": "vite build --ssr src/entry.preview.tsx", + "build.server": "vite build -c adaptors/cloudflare-pages/vite.config.ts", + "build.types": "tsc --incremental --noEmit", + "deploy": "wrangler pages dev ./dist", + "dev": "vite --mode ssr", + "dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force", + "fmt": "prettier --write .", + "fmt.check": "prettier --check .", + "lint": "eslint \"src/**/*.ts*\"", + "preview": "qwik build preview && vite preview --open", + "start": "vite --open --mode ssr", + "subfont": "subfont -i --inline-css --no-fallbacks --silent --root dist", + "qwik": "qwik" + }, + "devDependencies": { + "@builder.io/qwik": "0.15.0", + "@builder.io/qwik-city": "0.0.128", + "@fontsource/inter": "^4.5.14", + "@iconify-json/tabler": "^1.1.49", + "@types/eslint": "8.4.10", + "@types/node": "latest", + "@typescript-eslint/eslint-plugin": "5.45.0", + "@typescript-eslint/parser": "5.45.0", + "autoprefixer": "10.4.13", + "eslint": "8.29.0", + "eslint-plugin-qwik": "0.15.0", + "imagetools-core": "^3.2.3", + "node-fetch": "3.3.0", + "postcss": "^8.4.19", + "prettier": "2.8.0", + "rehype-autolink-headings": "^6.1.1", + "subfont": "^6.12.2", + "tailwindcss": "^3.1.8", + "typescript": "4.8.4", + "vite": "3.2.4", + "vite-imagetools": "^4.0.11", + "vite-tsconfig-paths": "3.6.0", + "wrangler": "latest" + }, + "engines": { + "node": ">=15.0.0" + } } diff --git a/packages/docs/sandbox.config.json b/packages/docs/sandbox.config.json new file mode 100644 index 0000000..a8b5f3e --- /dev/null +++ b/packages/docs/sandbox.config.json @@ -0,0 +1,11 @@ +{ + "infiniteLoopProtection": true, + "hardReloadOnChange": false, + "view": "browser", + "template": "node", + "container": { + "port": 5173, + "startScript": "start", + "node": "16" + } +} diff --git a/packages/docs/screenshot.jpg b/packages/docs/screenshot.jpg new file mode 100644 index 0000000..66b228f Binary files /dev/null and b/packages/docs/screenshot.jpg differ diff --git a/packages/docs/src/assets/images/hero.jpg b/packages/docs/src/assets/images/hero.jpg new file mode 100644 index 0000000..9f88a5e Binary files /dev/null and b/packages/docs/src/assets/images/hero.jpg differ diff --git a/packages/docs/src/assets/images/logo.png b/packages/docs/src/assets/images/logo.png new file mode 100644 index 0000000..6137145 Binary files /dev/null and b/packages/docs/src/assets/images/logo.png differ diff --git a/packages/docs/src/assets/styles/global.css b/packages/docs/src/assets/styles/global.css new file mode 100644 index 0000000..8d4a039 --- /dev/null +++ b/packages/docs/src/assets/styles/global.css @@ -0,0 +1,73 @@ +/** + * WHAT IS THIS FILE? + * + * Globally applied styles. No matter which components are in the page or matching route, + * the styles in here will be applied to the Document, without any sort of CSS scoping. + * + */ + +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer components { + .btn { + @apply inline-flex items-center justify-center rounded-md shadow-md border-gray-400 border bg-transparent font-medium text-center text-base text-gray-700 leading-snug transition py-3 px-6 md:px-8 ease-in duration-200 focus:ring-blue-500 focus:ring-offset-blue-200 focus:ring-2 focus:ring-offset-2 hover:bg-gray-100 hover:border-gray-600 dark:text-slate-300 dark:border-slate-500 dark:hover:bg-slate-800 dark:hover:border-slate-800; + } + + .btn-ghost { + @apply border-none shadow-none text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white; + } + + .btn-primary { + @apply font-semibold bg-primary-600 text-white border-primary-600 hover:bg-primary-800 hover:border-primary-800 hover:text-white dark:text-white dark:bg-primary-700 dark:border-primary-700 dark:hover:border-primary-900 dark:hover:bg-primary-900; + } + + .slot h1 { + @apply mb-2 font-semibold text-2xl; + } + + .slot h2 { + @apply mb-2 font-semibold text-lg; + } + + .slot h3 { + @apply mb-2 font-semibold text-base; + } + + .slot code { + @apply bg-slate-100 dark:bg-slate-800 p-1 px-2 rounded w-full; + } + + .slot pre { + @apply w-full flex my-2; + } + + .slot a { + @apply text-sky-900 font-medium dark:text-sky-400; + } + + .slot hr { + @apply my-5; + } + + [data-aw-toggle-menu] path { + @apply transition; + } + [data-aw-toggle-menu].expanded g > path:first-child { + @apply -rotate-45 translate-y-[15px] translate-x-[-3px]; + } + + p, + li { + @apply mt-2 text-sm text-slate-700 dark:text-slate-400; + } + + [data-aw-toggle-menu].expanded g > path:last-child { + @apply rotate-45 translate-y-[-8px] translate-x-[14px]; + } +} + +.dropdown:hover .dropdown-menu { + display: block; +} diff --git a/packages/docs/src/components/atoms/Logo.tsx b/packages/docs/src/components/atoms/Logo.tsx new file mode 100644 index 0000000..bd310f5 --- /dev/null +++ b/packages/docs/src/components/atoms/Logo.tsx @@ -0,0 +1,18 @@ +import { component$ } from '@builder.io/qwik' + +// @ts-ignore +import logoSrc from '~/assets/images/logo.png?width=64&height=64&png' + +export default component$(() => ( + + Qwind Logo + Qwind + +)) diff --git a/packages/docs/src/components/breadcrumbs/breadcrumbs.css b/packages/docs/src/components/breadcrumbs/breadcrumbs.css deleted file mode 100644 index 4626391..0000000 --- a/packages/docs/src/components/breadcrumbs/breadcrumbs.css +++ /dev/null @@ -1,25 +0,0 @@ -nav.breadcrumbs { - padding: 5px; - border-bottom: 1px solid #ddd; -} - -nav.breadcrumbs > span { - display: inline-block; - padding: 5px 0; - font-size: 12px; -} - -nav.breadcrumbs > span a { - text-decoration: none; - color: inherit; -} - -nav.breadcrumbs > span::after { - content: '>'; - padding: 0 5px; - opacity: 0.4; -} - -nav.breadcrumbs > span:last-child::after { - display: none; -} diff --git a/packages/docs/src/components/breadcrumbs/breadcrumbs.tsx b/packages/docs/src/components/breadcrumbs/breadcrumbs.tsx deleted file mode 100644 index 03954f0..0000000 --- a/packages/docs/src/components/breadcrumbs/breadcrumbs.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { component$, useStyles$ } from '@builder.io/qwik' -import { useContent, useLocation, ContentMenu } from '@builder.io/qwik-city' -import styles from './breadcrumbs.css?inline' - -export const Breadcrumbs = component$(() => { - useStyles$(styles) - - const { menu } = useContent() - const loc = useLocation() - - const breadcrumbs = createBreadcrumbs(menu, loc.pathname) - if (breadcrumbs.length === 0) { - return null - } - - return ( - - ) -}) - -export function createBreadcrumbs( - menu: ContentMenu | undefined, - pathname: string -) { - if (menu?.items) { - for (const indexA of menu.items) { - const breadcrumbA: ContentBreadcrumb = { - text: indexA.text, - } - if (typeof indexA.href === 'string') { - breadcrumbA.href = indexA.href - } - if (indexA.href === pathname) { - return [breadcrumbA] - } - - if (indexA.items) { - for (const indexB of indexA.items) { - const breadcrumbB: ContentBreadcrumb = { - text: indexB.text, - } - if (typeof indexB.href === 'string') { - breadcrumbB.href = indexB.href - } - if (indexB.href === pathname) { - return [breadcrumbA, breadcrumbB] - } - - if (indexB.items) { - for (const indexC of indexB.items) { - const breadcrumbC: ContentBreadcrumb = { - text: indexC.text, - } - if (typeof indexC.href === 'string') { - breadcrumbC.href = indexC.href - } - if (indexC.href === pathname) { - return [breadcrumbA, breadcrumbB, breadcrumbC] - } - } - } - } - } - } - } - - return [] -} - -interface ContentBreadcrumb { - text: string - href?: string -} diff --git a/packages/docs/src/components/core/DarkThemeLauncher.tsx b/packages/docs/src/components/core/DarkThemeLauncher.tsx new file mode 100644 index 0000000..5bc512f --- /dev/null +++ b/packages/docs/src/components/core/DarkThemeLauncher.tsx @@ -0,0 +1,3 @@ +export const DarkThemeLauncher = () => ( + +) diff --git a/packages/docs/src/components/router-head/router-head.tsx b/packages/docs/src/components/core/RouterHead.tsx similarity index 100% rename from packages/docs/src/components/router-head/router-head.tsx rename to packages/docs/src/components/core/RouterHead.tsx diff --git a/packages/docs/src/components/core/ToggleMenu.tsx b/packages/docs/src/components/core/ToggleMenu.tsx new file mode 100644 index 0000000..51779fc --- /dev/null +++ b/packages/docs/src/components/core/ToggleMenu.tsx @@ -0,0 +1,38 @@ +import { component$, useStore } from '@builder.io/qwik' + +import { IconMenu } from '~/components/icons/IconMenu' + +interface ItemProps { + iconClass?: string +} + +export default component$((props: ItemProps) => { + const { iconClass } = props + + const store = useStore({ + isExpanded: false, + }) + + return ( + + ) +}) diff --git a/packages/docs/src/components/core/ToggleTheme.tsx b/packages/docs/src/components/core/ToggleTheme.tsx new file mode 100644 index 0000000..00de98e --- /dev/null +++ b/packages/docs/src/components/core/ToggleTheme.tsx @@ -0,0 +1,52 @@ +import { component$, useStore, useClientEffect$ } from '@builder.io/qwik' + +import { IconSun } from '~/components/icons/IconSun' +import { IconMoon } from '../icons/IconMoon' + +interface ItemProps { + iconClass?: string +} + +export default component$((props: ItemProps) => { + const { iconClass } = props + const store = useStore({ + theme: + (typeof window !== 'undefined' && window?.localStorage?.theme) || + undefined, + }) + + useClientEffect$(() => { + store.theme = + window.localStorage.theme === 'dark' || + (!('theme' in window.localStorage) && + window.matchMedia('(prefers-color-scheme: dark)').matches) + ? 'dark' + : 'light' + }) + + return ( + + ) +}) diff --git a/packages/docs/src/components/footer/footer.css b/packages/docs/src/components/footer/footer.css deleted file mode 100644 index 662fc22..0000000 --- a/packages/docs/src/components/footer/footer.css +++ /dev/null @@ -1,22 +0,0 @@ -footer { - border-top: 0.5px solid #ddd; - margin-top: 40px; - padding: 20px; - text-align: center; -} - -footer a { - color: #9e9e9e; - font-size: 12px; -} - -footer ul { - list-style: none; - margin: 0; - padding: 0; -} - -footer li { - display: inline-block; - padding: 6px 12px; -} diff --git a/packages/docs/src/components/footer/footer.tsx b/packages/docs/src/components/footer/footer.tsx deleted file mode 100644 index c4634f7..0000000 --- a/packages/docs/src/components/footer/footer.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { component$, useStyles$ } from '@builder.io/qwik' -import styles from './footer.css?inline' - -export default component$(() => { - useStyles$(styles) - - return ( - - ) -}) diff --git a/packages/docs/src/components/header/header.css b/packages/docs/src/components/header/header.css deleted file mode 100644 index d2fd582..0000000 --- a/packages/docs/src/components/header/header.css +++ /dev/null @@ -1,34 +0,0 @@ -header { - position: sticky; - top: 0; - z-index: 11; - display: grid; - grid-template-columns: minmax(130px, auto) 1fr; - gap: 30px; - height: 80px; - width: 100%; - padding: 10px; - background-color: white; - overflow: hidden; -} - -header a.logo { - display: block; -} - -header a { - text-decoration: none; -} - -header nav { - text-align: right; -} - -header nav a { - display: inline-block; - padding: 5px 15px; -} - -header nav a:hover { - text-decoration: underline; -} diff --git a/packages/docs/src/components/header/header.tsx b/packages/docs/src/components/header/header.tsx deleted file mode 100644 index f151fe3..0000000 --- a/packages/docs/src/components/header/header.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { component$, useStyles$ } from '@builder.io/qwik' -import { useLocation } from '@builder.io/qwik-city' -import { QwikLogo } from '../icons/qwik' -import styles from './header.css?inline' - -export default component$(() => { - useStyles$(styles) - - const { pathname } = useLocation() - - return ( -
- - -
- ) -}) diff --git a/packages/docs/src/components/icons/IconArrowDownRight.tsx b/packages/docs/src/components/icons/IconArrowDownRight.tsx new file mode 100644 index 0000000..8adfab2 --- /dev/null +++ b/packages/docs/src/components/icons/IconArrowDownRight.tsx @@ -0,0 +1,27 @@ +interface ItemProps { + class?: string +} + +export const IconArrowDownRight = (props: ItemProps) => { + const { class: className } = props + return ( + + + + + + ) +} diff --git a/packages/docs/src/components/icons/IconFacebook.tsx b/packages/docs/src/components/icons/IconFacebook.tsx new file mode 100644 index 0000000..efa8754 --- /dev/null +++ b/packages/docs/src/components/icons/IconFacebook.tsx @@ -0,0 +1,17 @@ +export const IconFacebook = () => ( + + + + +) diff --git a/packages/docs/src/components/icons/IconGithub.tsx b/packages/docs/src/components/icons/IconGithub.tsx new file mode 100644 index 0000000..ced827c --- /dev/null +++ b/packages/docs/src/components/icons/IconGithub.tsx @@ -0,0 +1,17 @@ +export const IconGithub = () => ( + + + + +) diff --git a/packages/docs/src/components/icons/IconInstagram.tsx b/packages/docs/src/components/icons/IconInstagram.tsx new file mode 100644 index 0000000..508fa0e --- /dev/null +++ b/packages/docs/src/components/icons/IconInstagram.tsx @@ -0,0 +1,19 @@ +export const IconInstagram = () => ( + + + + + + +) diff --git a/packages/docs/src/components/icons/IconMenu.tsx b/packages/docs/src/components/icons/IconMenu.tsx new file mode 100644 index 0000000..2d02bac --- /dev/null +++ b/packages/docs/src/components/icons/IconMenu.tsx @@ -0,0 +1,30 @@ +interface ItemProps { + class?: string +} + +export const IconMenu = (props: ItemProps) => { + const { class: className } = props + return ( + + + + + + + ) +} diff --git a/packages/docs/src/components/icons/IconMoon.tsx b/packages/docs/src/components/icons/IconMoon.tsx new file mode 100644 index 0000000..fa65ec0 --- /dev/null +++ b/packages/docs/src/components/icons/IconMoon.tsx @@ -0,0 +1,26 @@ +interface ItemProps { + class?: string +} + +export const IconMoon = (props: ItemProps) => { + const { class: className } = props + return ( + + + + + ) +} diff --git a/packages/docs/src/components/icons/IconStar.tsx b/packages/docs/src/components/icons/IconStar.tsx new file mode 100644 index 0000000..3b60a48 --- /dev/null +++ b/packages/docs/src/components/icons/IconStar.tsx @@ -0,0 +1,17 @@ +export const IconStar = () => ( + + + + +) diff --git a/packages/docs/src/components/icons/IconSun.tsx b/packages/docs/src/components/icons/IconSun.tsx new file mode 100644 index 0000000..660f507 --- /dev/null +++ b/packages/docs/src/components/icons/IconSun.tsx @@ -0,0 +1,25 @@ +interface ItemProps { + class?: string +} + +export const IconSun = (props: ItemProps) => { + const { class: className } = props + return ( + + + + + + ) +} diff --git a/packages/docs/src/components/icons/IconTwitter.tsx b/packages/docs/src/components/icons/IconTwitter.tsx new file mode 100644 index 0000000..3b9bcb6 --- /dev/null +++ b/packages/docs/src/components/icons/IconTwitter.tsx @@ -0,0 +1,17 @@ +export const IconTwitter = () => ( + + + + +) diff --git a/packages/docs/src/components/icons/qwik.tsx b/packages/docs/src/components/icons/qwik.tsx deleted file mode 100644 index 7641610..0000000 --- a/packages/docs/src/components/icons/qwik.tsx +++ /dev/null @@ -1,20 +0,0 @@ -export const QwikLogo = () => ( - - - - - - -) diff --git a/packages/docs/src/components/menu/menu.css b/packages/docs/src/components/menu/menu.css deleted file mode 100644 index ffb745c..0000000 --- a/packages/docs/src/components/menu/menu.css +++ /dev/null @@ -1,13 +0,0 @@ -.menu { - background: #eee; - padding: 20px 10px; -} - -.menu h5 { - margin: 0; -} - -.menu ul { - padding-left: 20px; - margin: 5px 0 25px 0; -} diff --git a/packages/docs/src/components/menu/menu.tsx b/packages/docs/src/components/menu/menu.tsx deleted file mode 100644 index 3ccd57e..0000000 --- a/packages/docs/src/components/menu/menu.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { component$, useStyles$ } from '@builder.io/qwik' -import { useContent, Link, useLocation } from '@builder.io/qwik-city' -import styles from './menu.css?inline' - -export default component$(() => { - useStyles$(styles) - - const { menu } = useContent() - const loc = useLocation() - - return ( - - ) -}) diff --git a/packages/docs/src/components/on-this-page/on-this-page.css b/packages/docs/src/components/on-this-page/on-this-page.css deleted file mode 100644 index 4d1f610..0000000 --- a/packages/docs/src/components/on-this-page/on-this-page.css +++ /dev/null @@ -1,33 +0,0 @@ -.on-this-page { - padding-bottom: 20px; - font-size: 0.9em; -} - -.on-this-page h6 { - margin: 10px 0; - font-weight: bold; - text-transform: uppercase; -} - -.on-this-page ul { - margin: 0; - padding: 0 0 20px 0; - list-style: none; -} - -.on-this-page a { - position: relative; - display: block; - border: 0 solid #ddd; - border-left-width: 2px; - padding: 4px 2px 4px 8px; - text-decoration: none; -} - -.on-this-page a.indent { - padding-left: 30px; -} - -.on-this-page a:hover { - border-color: var(--theme-accent); -} diff --git a/packages/docs/src/components/on-this-page/on-this-page.tsx b/packages/docs/src/components/on-this-page/on-this-page.tsx deleted file mode 100644 index 520017c..0000000 --- a/packages/docs/src/components/on-this-page/on-this-page.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { useContent, useLocation } from '@builder.io/qwik-city' -import { component$, useStyles$ } from '@builder.io/qwik' -import styles from './on-this-page.css?inline' - -export default component$(() => { - useStyles$(styles) - - const { headings } = useContent() - const contentHeadings = - headings?.filter((h) => h.level === 2 || h.level === 3) || [] - - const { pathname } = useLocation() - const editUrl = `#update-your-edit-url-for-${pathname}` - - return ( - - ) -}) diff --git a/packages/docs/src/components/widgets/CallToAction.tsx b/packages/docs/src/components/widgets/CallToAction.tsx new file mode 100644 index 0000000..bbee471 --- /dev/null +++ b/packages/docs/src/components/widgets/CallToAction.tsx @@ -0,0 +1,37 @@ +import { component$ } from '@builder.io/qwik' + +export default component$(() => { + return ( +
+
+
+
+

+ Qwik +{' '} +
+ + Tailwind CSS + +

+

+ Be very surprised by these huge fake numbers you are + seeing on this page. + Don't waste more time! +

+ + +
+
+
+
+ ) +}) diff --git a/packages/docs/src/components/widgets/ExtraBar.tsx b/packages/docs/src/components/widgets/ExtraBar.tsx new file mode 100644 index 0000000..030951f --- /dev/null +++ b/packages/docs/src/components/widgets/ExtraBar.tsx @@ -0,0 +1,27 @@ +import { component$ } from '@builder.io/qwik' +import { useLocation } from '@builder.io/qwik-city' + +/** + * options = [] array con la lista de opciones de la documentacion + */ +export default component$( + ({ + options = [], + }: { + options: { link: string; name: string; class?: string }[] + }) => { + const { pathname } = useLocation() + const editUrl = ` https://github.com/codigoencasa/bot-whatsapp/edit/dev/packages/docs/src/routes${pathname}index.mdx` + return ( +
+ +
+ ) + } +) diff --git a/packages/docs/src/components/widgets/FAQs.tsx b/packages/docs/src/components/widgets/FAQs.tsx new file mode 100644 index 0000000..6377cb1 --- /dev/null +++ b/packages/docs/src/components/widgets/FAQs.tsx @@ -0,0 +1,84 @@ +import { component$ } from '@builder.io/qwik' +import { IconArrowDownRight } from '../icons/IconArrowDownRight' + +export default component$(() => { + const items = [ + [ + { + question: 'What do I need to start?', + answer: `Space, the final frontier. These are the voyages of the Starship Enterprise. Its five-year mission: to explore strange new worlds. + + Many say exploration is part of our destiny, but it’s actually our duty to future generations.`, + }, + { + question: 'How to install the Qwik + Tailwind CSS template?', + answer: `Well, the way they make shows is, they make one show. That show's called a pilot. + + Then they show that show to the people who make shows, and on the strength of that one show they decide if they're going to make more shows. Some pilots get picked and become television programs. Some don't, become nothing. She starred in one of the ones that became nothing.`, + }, + { + question: + "What's something that you completely don't understand?", + answer: `A flower in my garden, a mystery in my panties. Heart attack never stopped old Big Bear. I didn't even know we were calling him Big Bear.`, + }, + ], + [ + { + question: "What's an example of when you changed your mind?", + answer: `Michael Knight a young loner on a crusade to champion the cause of the innocent. The helpless. The powerless in a world of criminals who operate above the law. Here he comes Here comes Speed Racer. He's a demon on wheels.`, + }, + { + question: + 'What is something that you would really like to try again?', + answer: `A business big enough that it could be listed on the NASDAQ goes belly up. Disappears! + + It ceases to exist without me. No, you clearly don't know who you're talking to, so let me clue you in.`, + }, + { + question: + 'If you could only ask one question to each person you meet, what would that question be?', + answer: `This is not about revenge. This is about justice. A lot of things can change in twelve years, Admiral. Well, that's certainly good to know. About four years. I got tired of hearing how young I looked.`, + }, + ], + ] + + return ( +
+
+
+
+

+ FAQs +

+

+ Frequently Asked Questions +

+
+
+
+
+ {items.map((subitems) => ( +
+ {subitems.map(({ question, answer }) => ( +
+

+ + {question} +

+ {answer + .split('\n\n') + .map((paragraph) => ( +

+ {paragraph} +

+ ))} +
+ ))} +
+ ))} +
+
+
+
+ ) +}) diff --git a/packages/docs/src/components/widgets/Features.tsx b/packages/docs/src/components/widgets/Features.tsx new file mode 100644 index 0000000..5f870e5 --- /dev/null +++ b/packages/docs/src/components/widgets/Features.tsx @@ -0,0 +1,91 @@ +import { component$ } from '@builder.io/qwik' +import { IconStar } from '~/components/icons/IconStar' + +export default component$(() => { + const items = [ + [ + { + title: 'Qwik + Tailwind CSS Integration', + description: + 'A seamless integration between two great frameworks that offer high productivity, performance and versatility.', + icon: 'tabler:brand-tailwind', + }, + { + title: 'Ready-to-use Components', + description: + 'Widgets made with Tailwind CSS ready to be used in Marketing Websites, SaaS, Blogs, Personal Profiles, Small Business...', + icon: 'tabler:components', + }, + { + title: 'Best Practices', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis lobortis, mi risus tempus nulla.', + icon: 'tabler:list-check', + }, + ], + [ + { + title: 'Excellent Page Speed', + description: + 'Having a good page speed impacts organic search ranking, improves user experience (UI/UX) and increase conversion rates.', + icon: 'tabler:rocket', + }, + { + title: 'Search Engine Optimization (SEO)', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis lobortis, mi risus tempus nulla.', + icon: 'tabler:arrows-right-left', + }, + { + title: 'Open to new ideas and contributions', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, quam nec venenatis lobortis, mi risus tempus nulla.', + icon: 'tabler:bulb', + }, + ], + ] + + return ( +
+
+
+

+ Features +

+

+ What you get with{' '} + Qwind +

+

+ Sed ut perspiciatis unde omnis iste natus error sit + voluptatem accusantium doloremque rem aperiam, eaque + ipsa quae. +

+
+
+ {items.map((subitems) => ( +
+ {subitems.map(({ title, description }) => ( +
+
+
+ +
+
+
+

+ {title} +

+

+ {description} +

+
+
+ ))} +
+ ))} +
+
+
+ ) +}) diff --git a/packages/docs/src/components/widgets/Footer.tsx b/packages/docs/src/components/widgets/Footer.tsx new file mode 100644 index 0000000..d7c3b8b --- /dev/null +++ b/packages/docs/src/components/widgets/Footer.tsx @@ -0,0 +1,128 @@ +import { component$ } from '@builder.io/qwik' +import { Link } from '@builder.io/qwik-city' + +import { IconTwitter } from '~/components/icons/IconTwitter' +import { IconInstagram } from '~/components/icons/IconInstagram' +import { IconFacebook } from '~/components/icons/IconFacebook' +import { IconGithub } from '~/components/icons/IconGithub' + +export default component$(() => { + const links = [ + { + title: 'Product', + items: [ + { title: 'Features', href: '#' }, + { title: 'Security', href: '#' }, + ], + }, + { + title: 'Platform', + items: [ + { title: 'Developer API', href: '#' }, + { title: 'Partners', href: '#' }, + ], + }, + { + title: 'Support', + items: [ + { title: 'Docs', href: '#' }, + { title: 'Community Forum', href: '#' }, + ], + }, + { + title: 'Company', + items: [ + { title: 'About', href: '#' }, + { title: 'Blog', href: '#' }, + ], + }, + ] + + const social = [ + { label: 'Twitter', icon: IconTwitter, href: '#' }, + { label: 'Instagram', icon: IconInstagram, href: '#' }, + { label: 'Facebook', icon: IconFacebook, href: '#' }, + { + label: 'Github', + icon: IconGithub, + href: 'https://github.com/onwidget/qwind', + }, + ] + + return ( + + ) +}) diff --git a/packages/docs/src/components/widgets/Header.tsx b/packages/docs/src/components/widgets/Header.tsx new file mode 100644 index 0000000..73c2714 --- /dev/null +++ b/packages/docs/src/components/widgets/Header.tsx @@ -0,0 +1,119 @@ +import { component$, useStore } from '@builder.io/qwik' +import Logo from '~/components/atoms/Logo' +import { IconGithub } from '~/components/icons/IconGithub' +import ToggleTheme from '~/components/core/ToggleTheme' +import ToggleMenu from '~/components/core/ToggleMenu' + +export default component$(() => { + const store = useStore({ + isScrolling: false, + }) + + return ( + + ) +}) diff --git a/packages/docs/src/components/widgets/Hero.tsx b/packages/docs/src/components/widgets/Hero.tsx new file mode 100644 index 0000000..f8aacbb --- /dev/null +++ b/packages/docs/src/components/widgets/Hero.tsx @@ -0,0 +1,87 @@ +import { component$ } from '@builder.io/qwik' + +// @ts-ignore +import srcsetAvif from '~/assets/images/hero.jpg?w=400;900&avif&srcset' +// @ts-ignore +import srcsetWebp from '~/assets/images/hero.jpg?w=400;900&webp&srcset' +// @ts-ignore +import { src as placeholder } from '~/assets/images/hero.jpg?width=400&metadata' + +export default component$(() => { + return ( +
+
+
+
+
+

+ Free template for {' '} + {' '} + Qwik +{' '} + + Tailwind CSS + +

+
+

+ + Qwind + {' '} + is a production ready template to start your + new website using Qwik +{' '} + Tailwind CSS. It has been designed + following Best Practices, SEO, + Accessibility,{' '} + ... + +

+
+ +
+ +
+
+
+
+
+
+
+ + + + Qwind Hero Image (Cool dog) + +
+
+
+
+
+ ) +}) diff --git a/packages/docs/src/components/widgets/NavBar.tsx b/packages/docs/src/components/widgets/NavBar.tsx new file mode 100644 index 0000000..42127ee --- /dev/null +++ b/packages/docs/src/components/widgets/NavBar.tsx @@ -0,0 +1,32 @@ +import { component$ } from '@builder.io/qwik' +import { useLocation } from '@builder.io/qwik-city' + +/** + * options = [] array con la lista de opciones de la documentacion + */ +export default component$( + ({ options = [] }: { options: { link: string; name: string }[] }) => { + const location = useLocation() + const currentPage = location.pathname + return ( +
+ +
+ ) + } +) diff --git a/packages/docs/src/components/widgets/Stats.tsx b/packages/docs/src/components/widgets/Stats.tsx new file mode 100644 index 0000000..c4dc31a --- /dev/null +++ b/packages/docs/src/components/widgets/Stats.tsx @@ -0,0 +1,42 @@ +import { component$ } from '@builder.io/qwik' + +export default component$(() => { + return ( +
+
+
+
+ 132K +
+

+ Downloads +

+
+
+
+ 24.8K +
+

+ Stars +

+
+
+
+ 10.3K +
+

+ Forks +

+
+
+
+ 48.4K +
+

+ Users +

+
+
+
+ ) +}) diff --git a/packages/docs/src/config.mjs b/packages/docs/src/config.mjs new file mode 100644 index 0000000..4342570 --- /dev/null +++ b/packages/docs/src/config.mjs @@ -0,0 +1,7 @@ +export const SITE = { + name: "Qwind", + + origin: "https://qwind.pages.dev", + basePathname: "/", + trailingSlash: true +}; diff --git a/packages/docs/src/entry.ssr.tsx b/packages/docs/src/entry.ssr.tsx index 6d6808c..3eac0ab 100644 --- a/packages/docs/src/entry.ssr.tsx +++ b/packages/docs/src/entry.ssr.tsx @@ -20,7 +20,9 @@ export default function (opts: RenderToStreamOptions) { ...opts, // Use container attributes to set attributes on the html tag. containerAttributes: { - lang: 'en-us', + lang: 'en', + dir: 'ltr', + class: 'motion-safe:scroll-smooth 2xl:text-[20px]', ...opts.containerAttributes, }, }) diff --git a/packages/docs/src/global.css b/packages/docs/src/global.css deleted file mode 100644 index 45a24b8..0000000 --- a/packages/docs/src/global.css +++ /dev/null @@ -1,67 +0,0 @@ -* { - box-sizing: border-box; -} - -:root { - --user-font-scale: 1rem - 16px; - --max-width: calc(100% - 1rem); - - --font-body: system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, - Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji; - --font-mono: 'IBM Plex Mono', Consolas, 'Andale Mono WT', 'Andale Mono', - 'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono', - 'Bitstream Vera Sans Mono', 'Liberation Mono', 'Nimbus Mono L', Monaco, - 'Courier New', Courier, monospace; - - color-scheme: light; - --theme-accent: #006ce9; - --theme-text: #181818; -} - -@media (min-width: 50em) { - :root { - --max-width: 46em; - } -} - -body { - display: flex; - flex-direction: column; - min-height: 100vh; - font-family: var(--font-body); - font-size: 1rem; - font-size: clamp(0.9rem, 0.75rem + 0.375vw + var(--user-font-scale), 1rem); - line-height: 1.5; - max-width: 100vw; - background: var(--theme-bg); - color: var(--theme-text); -} - -main { - padding: 10px 20px; - max-width: 960px; - margin: 0 auto; -} - -a { - color: var(--theme-accent); -} - -a:hover { - text-decoration: none; -} - -code, -kbd, -samp, -pre { - font-family: var(--font-mono); -} - -code { - background-color: rgb(224, 224, 224); - padding: 2px 4px; - border-radius: 3px; - font-size: 0.9em; - border-bottom: 2px solid #bfbfbf; -} diff --git a/packages/docs/src/root.tsx b/packages/docs/src/root.tsx index 7dc392f..bbaf423 100644 --- a/packages/docs/src/root.tsx +++ b/packages/docs/src/root.tsx @@ -1,27 +1,42 @@ -import { component$ } from '@builder.io/qwik' +import { component$, useStyles$ } from '@builder.io/qwik' import { QwikCityProvider, RouterOutlet, ServiceWorkerRegister, } from '@builder.io/qwik-city' -import { RouterHead } from './components/router-head/router-head' -import './global.css' +import { RouterHead } from '~/components/core/RouterHead' +import { DarkThemeLauncher } from '~/components/core/DarkThemeLauncher' + +import globalStyles from '~/assets/styles/global.css?inline' export default component$(() => { - /* + /** * The root of a QwikCity site always start with the component, * immediately followed by the document's and . * * Dont remove the `` and `` elements. */ + + useStyles$(globalStyles) + return ( + + + + - + diff --git a/packages/docs/src/routes/about-us/index.md b/packages/docs/src/routes/about-us/index.md deleted file mode 100644 index 2d08bf4..0000000 --- a/packages/docs/src/routes/about-us/index.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: About Bot-Whatsapp . ---- - -# About Qwik - -Hola soy una prueba - -## More info: - -- [Layouts](https://qwik.builder.io/qwikcity/layout/overview/) -- [Routing](https://qwik.builder.io/qwikcity/routing/overview/) -- [Authoring Content](https://qwik.builder.io/qwikcity/content/component/) -- [Deployment](https://qwik.builder.io/qwikcity/adaptors/overview/) -- [Static Site Generation (SSG)](https://qwik.builder.io/qwikcity/static-site-generation/overview/) diff --git a/packages/docs/src/routes/blog/index.tsx b/packages/docs/src/routes/blog/index.tsx new file mode 100644 index 0000000..c912e31 --- /dev/null +++ b/packages/docs/src/routes/blog/index.tsx @@ -0,0 +1,27 @@ +import { component$ } from '@builder.io/qwik' +import type { DocumentHead } from '@builder.io/qwik-city' + +export default component$(() => { + return ( + <> +
+
+

+ Blog +

+

Coming soon ...

+
+
+ + ) +}) + +export const head: DocumentHead = { + title: 'Blog — Qwind', + meta: [ + { + name: 'description', + content: 'Lorem ipsum lorem ...', + }, + ], +} diff --git a/packages/docs/src/routes/docs/advanced/index.md b/packages/docs/src/routes/docs/advanced/index.md deleted file mode 100644 index 6b8cf43..0000000 --- a/packages/docs/src/routes/docs/advanced/index.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Advanced ---- - -# Advanced - -Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - -## Ferrari - -[Ferrari](https://en.wikipedia.org/wiki/Ferrari) (/fəˈrɑːri/; Italian: [ferˈraːri]) is an Italian luxury sports car manufacturer based in Maranello, Italy. Founded by Enzo Ferrari (1898–1988) in 1939 from the Alfa Romeo racing division as Auto Avio Costruzioni, the company built its first car in 1940, and produced its first Ferrari-badged car in 1947. diff --git a/packages/docs/src/routes/docs/docs.css b/packages/docs/src/routes/docs/docs.css deleted file mode 100644 index 1edc550..0000000 --- a/packages/docs/src/routes/docs/docs.css +++ /dev/null @@ -1,22 +0,0 @@ -.docs { - display: grid; - grid-template-columns: 210px auto 190px; - grid-template-areas: 'menu article on-this-page'; - gap: 40px; -} - -.docs h1 { - margin-top: 0; -} - -.docs .menu { - grid-area: menu; -} - -.docs article { - grid-area: article; -} - -.docs .on-this-page { - grid-area: on-this-page; -} diff --git a/packages/docs/src/routes/docs/getting-started/index.md b/packages/docs/src/routes/docs/getting-started/index.md deleted file mode 100644 index 0a081c6..0000000 --- a/packages/docs/src/routes/docs/getting-started/index.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Getting Started ---- - -# Getting Started - -``` -npm create qwik@latest -``` - -## Ford GT40 - -The [Ford GT40](https://en.wikipedia.org/wiki/Ford_GT40) is a high-performance endurance racing car commissioned by the Ford Motor Company. It grew out of the "Ford GT" (for Grand Touring) project, an effort to compete in European long-distance sports car races, against Ferrari, which won the prestigious 24 Hours of Le Mans race from 1960 to 1965. Ford succeeded with the GT40, winning the 1966 through 1969 races. diff --git a/packages/docs/src/routes/docs/index.md b/packages/docs/src/routes/docs/index.md deleted file mode 100644 index b76532d..0000000 --- a/packages/docs/src/routes/docs/index.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Overview ---- - -# Docs Site Overview - -This page is wrapped by two layouts because this source file `src/routes/docs/index.md` is nested. The applied layouts are: - -- `src/routes/docs/layout.tsx` -- `src/routes/layout.tsx` - -## Left Menu - -The left menu ordering is created with the `src/routes/docs/menu.md` markdown file. - -## More info: - -- [Layouts](https://qwik.builder.io/qwikcity/layout/overview/) -- [Routing](https://qwik.builder.io/qwikcity/routing/overview/) -- [Authoring Content](https://qwik.builder.io/qwikcity/content/component/) -- [Deployment](https://qwik.builder.io/qwikcity/adaptors/overview/) -- [Static Site Generation (SSG)](https://qwik.builder.io/qwikcity/static-site-generation/overview/) diff --git a/packages/docs/src/routes/docs/index.mdx b/packages/docs/src/routes/docs/index.mdx new file mode 100644 index 0000000..d5aa85f --- /dev/null +++ b/packages/docs/src/routes/docs/index.mdx @@ -0,0 +1,19 @@ +# Primeros Pasos + +Los chatbots son una herramienta poderosa para que las empresas y +organizaciones comuniquen de forma personalizada y automatizada con sus clientes. + +Está documentación te ayudará a instalar tu bot de whatsapp en simples pasos con el proposito de +que tengas un chatbot funcional en solo minutos. + +--- + +### Ejecutar + +Es muy sencillo solo deberas ejecutar el siguiente comando 🚀 + +```shell +npm create bot-whatsapp@latest +``` + +![](https://camo.githubusercontent.com/97cd563fb448c72cc50dd60d71e85d269e5b1c738473d56fee6e023e1e0723bb/68747470733a2f2f692e67697068792e636f6d2f6d656469612f6e744d74365476616c70737454497837416b2f67697068792e77656270) diff --git a/packages/docs/src/routes/docs/install/index.mdx b/packages/docs/src/routes/docs/install/index.mdx new file mode 100644 index 0000000..a8eeb88 --- /dev/null +++ b/packages/docs/src/routes/docs/install/index.mdx @@ -0,0 +1,10 @@ +--- +title: Overview +contributors: + - adamdbradley + - steve8708 + - manucorporat + - gabrielgrant +--- + +# Instalación diff --git a/packages/docs/src/routes/docs/layout!.tsx b/packages/docs/src/routes/docs/layout!.tsx new file mode 100644 index 0000000..3ff05ae --- /dev/null +++ b/packages/docs/src/routes/docs/layout!.tsx @@ -0,0 +1,55 @@ +import { component$, Slot, useStore } from '@builder.io/qwik' +import type { DocumentHead } from '@builder.io/qwik-city' +import Footer from '~/components/widgets/Footer' +import Header from '~/components/widgets/Header' +import NavBar from '~/components/widgets/NavBar' +import ExtraBar from '~/components/widgets/ExtraBar' + +export default component$(() => { + const store = useStore({ + options: [ + { name: 'Primeros pasos', link: '/docs' }, + { name: 'Instalación', link: '/docs/install' }, + { name: 'Configuración', link: '/docs/settings' }, + { name: 'Migración', link: '/docs/migration' }, + ], + extraOptions: [ + { name: 'Primeros pasos', link: '/docs', class: 'font-semibold' }, + { name: 'Instalación', link: '/docs' }, + { name: 'Configuración', link: '/docs' }, + { name: 'Forma de pensar', link: '/docs' }, + ], + }) + + return ( + <> +
+
+
+
+ +
+
+ +
+
+ +
+
+
+ +