В этом руководстве вы узнаете, как создать приложение для опроса с помощью Strapi и react.js, а также как использовать интернационализацию для приложения.

Автор: Попула Темитопе

Приложения для опросов — это программное обеспечение, которое компании используют для получения отзывов от клиентов или сотрудников о том, насколько хорошо работают их продукты или услуги. Поскольку организации могут получать отзывы клиентов или сотрудников о своих услугах, приложения для проведения опросов играют важную роль в анализе услуг организации. Затем компания будет работать с собранными отзывами, чтобы предоставлять лучшие услуги, соответствующие ожиданиям клиентов.

Многие компании используют опросы, потому что это один из самых простых способов сбора информации из внешнего мира. Независимо от того, хочет ли ваша компания собрать мнения или хочет, чтобы вы заполнили форму обратной связи, веб-опрос — это хороший способ.

Опросы могут показать вам проблемы, которые решает ваш сервис (и те, которые он не решает), и дать вам представление о том, что вам нужно делать, чтобы удовлетворить своих клиентов. Они расскажут вам больше о ваших схемах ценообразования и расскажут, как вы можете улучшить их, основываясь на том, что говорят ваши клиенты. Короче говоря, опросы должны быть встроены в стратегию каждой организации, чтобы получать отзывы от клиентов и потенциальных клиентов, а также как способ завоевать с ними доверие.

В этом руководстве я покажу вам, как создать приложение для опроса с помощью React.js, используя Strapi в качестве внутреннего инструмента. Вот как это будет выглядеть:

Предпосылки

Чтобы следовать этому руководству, у вас должно быть:

  • Node.js v14 или v12 установлен на вашем компьютере. Чтобы проверить версию вашего узла, используйте команду node -v.
  • На вашем компьютере установлены NPM или Yarn.
  • Базовые знания React.js.

Что такое Страпи?

Strapi — это Content API Framework с открытым исходным кодом, который используется для создания контент-ориентированных приложений. Его можно использовать для создания простого блога или для создания сложных платформ электронной коммерции, таких как Shopify.

Strapi написан на Node.js и использует MongoDB в качестве своей базы данных. Он предоставляет богатый набор функций, включая аутентификацию и авторизацию, управление контентом, импорт/экспорт данных, мониторинг производительности и т. д.

Что такое React.js?

React.js — это библиотека для создания пользовательских интерфейсов. Это декларативная библиотека пользовательского интерфейса на основе компонентов. Это позволяет вам создавать повторно используемые компоненты пользовательского интерфейса, которые визуализируются с использованием моделей данных, чтобы описать, как компонент должен быть визуализирован.

React направлен на решение одной проблемы: создание больших приложений с данными, которые со временем меняются. Мы хотим, чтобы наши приложения были быстрыми и отзывчивыми, независимо от того, сколько данных они отображают или сколько вещей происходит на странице одновременно, поэтому нам нужен эффективный способ обновления представления при изменении данных.

Почему приложение для опроса важно?

Есть много причин, по которым разработчикам необходимо использовать опросы. 1. Они могут получать отзывы от своих клиентов о своих продуктах. 2. Они могут знать, какие функции нужны людям и как они хотят их реализовать. 3. Это помогает им улучшить качество своего продукта и внести соответствующие изменения. 4. Это также дает им представление о доле рынка их продукта, что поможет им решить, стоит ли тратить больше времени на процесс разработки или нет.

Возможности нашего приложения для опросов

Приложение для опроса, которое мы создадим, будет иметь следующие функции:

  • Случайные вопросы
  • Вопросы «да или нет»
  • Локализованные вопросы
  • Форма вопросов

Установка страпи

Давайте начнем с нашей установки. Откройте командную строку и введите одну из следующих команд:

  • Команда пряжи:
yarn create strapi-app survey-app --quickstart

Or

  • команда нпкс:
npx create-strapi-app survey-app --quickstart

Приведенная выше команда установит все необходимые пакеты для проекта. После установки приложение Strapi автоматически запустится в браузере. Зарегистрируйтесь, указав свои данные, и вы попадете на страницу панели инструментов, как показано ниже:

Установка React.js

Создать приложение React легко. Первый шаг — запустить в терминале следующие команды:

npx create-react-app my-app
    cd my-app
    npm start

Приведенная выше команда создаст каталог для вашего нового проекта и инициализирует его как пакет. Приложение React должно быть установлено в папке my-project.

Создание приложения для опроса

Теперь, когда мы выполнили всю подготовку, давайте сразу приступим к созданию нашего приложения для опросов.

Создание наших коллекций приложений на Strapi

В этом простом приложении для проведения опросов мы создадим два типа контента: опрос и ответ.

  • Тип сбора опросов:

Этот тип коллекции будет содержать все вопросы опроса с их вариантами, чтобы пользователи могли выбрать этот ответ. Мы также будем использовать плагин интернационализации для перевода вопросов опроса на разные языки.

Прежде чем мы создадим коллекцию опросов, давайте добавим в наше приложение новый язык локали. Сделать это просто. В меню панели инструментов нажмите «Настройки». Затем в подменю глобальных настроек нажмите на интернационализацию.

Чтобы добавить новый язык, нажмите кнопку «Добавить новый язык», а затем выберите язык и сохраните его. Но для нашего приложения для опроса мы добавим только французский (Канада) fr-CA, как показано ниже:

Теперь давайте создадим тип коллекции опросов. В меню панели инструментов нажмите «Конструктор типов контента», затем нажмите «Создать новый тип коллекции». Введите отображаемое имя для типа коллекции, а затем нажмите «Дополнительные настройки». В дополнительных настройках убедитесь, что вы включили международный режим, и нажмите «Продолжить».

После этого мы добавим необходимые поля для типа контента опроса. Тип содержимого опроса заполняет следующие поля:

я. вопрос: (Текст — Длинный текст)

II. a: (Текст — Короткий текст)

III. b: (Текст — Короткий текст)

IV. c: (Текст — Короткий текст)

  • Тип сбора ответов:

В этом типе коллекции будут храниться все ответы на опросы. Тип набора ответов будет содержать следующие поля: Электронная почта, SurveyQuestion, SurveyResponse. Чтобы создать тип набора ответов, выполните те же шаги, что и для типа сбора опроса выше.

Добавление вопросов в коллекцию опросов

Давайте добавим некоторые вопросы опроса в тип набора опросов. Сделать это просто. В меню контент-менеджера щелкните опрос, а затем нажмите кнопку «Создать новую запись». Заполните вопросы опроса и варианты ответов на них, затем сохраните его и нажмите «Опубликовать». Вы можете добавить столько вопросов для опроса, сколько хотите.

Добавление вопросов интернационализации

Чтобы добавить содержимое локали для типа набора опросов, на странице набора опросов щелкните значок редактирования для каждого вопроса. С левой стороны нажмите на языковой стандарт и выберите предпочитаемый язык. Заполните вопрос опроса на выбранном языке, сохраните и опубликуйте его.

Завершение бэкенда

Прежде чем мы перейдем к дизайну внешнего интерфейса, нам нужно убедиться, что типы контента опроса и ответа доступны через вызов API. Перейдите в «Настройки», нажмите «Роли» и отредактируйте «Общие». Выберите все и нажмите «Сохранить» как для опроса, так и для ответа соответственно.

Теперь мы можем делать запросы к типам сбора опросов и ответов, используя конечные точки http://localhost:1337/api/surveys/ и http://localhost:1337/api/responses/ restful из внешнего интерфейса.

Создание внешнего интерфейса

В этом уроке мы не будем сосредотачиваться на стилях, но в вашем проекте React откройте app.css и замените стиль следующим кодом:

// src/App.css
    .App {
        text-align: center;
    }
     
    .main {
        width: 99%;
        height: 500px;
        background-color: #e7e7e7;
        border-radius: 10px;
        margin-top: 70px;
        border: 4px solid #f3f3f3
    }
     
    .bar1 {
        width: 100%;
        height: 70px;
        border-top-right-radius: 10px;
        border-top-left-radius: 10px;
    }
     
    .bar2 {
        width: 70%;
        height: 27px;
        background-color: white;
        border-radius: 10px;
    }
     
    .bar3 {
        width: 100%;
        height: 27px;
        background-color: #f68e56;
        float: left;
        border-radius: 10px;
        color: white;
    }
     
    #surv {
     
        width: 90%;
        height: 380px;
        background-color: #f3f3f3;
        border-top-right-radius: 10px;
        border-top-left-radius: 10px;
        margin-left: 70px;
    }
     
    .divid1 {
        height: 200px;
        width: 440px;
        float: left;
        margin-left: 200px;
    }
     
    .divid2 {
        height: 200px;
        width: 440px;
        float: right;
    }
     
    .input {
        border: 2px solid #d5d5d5;
        font-size: 17px;
        background: #fbfbfb;
        height: 20px;
        padding: 8px;
        width: 400px;
    }
     
    .radio_option {
        width: 1100px;
        height: 430px;
        margin-left: 100px;
    }
     
    .radio {
        border: 2px solid #d5d5d5;
        font-size: 17px;
        background: #fbfbfb;
        height: 24px;
        padding: 8px;
        width: 24px;
    }
    .checkbox {
        border: 2px solid #d5d5d5;
        font-size: 17px;
        background: #fbfbfb;
        height: 24px;
        padding: 8px;
        width: 24px;
    }
     
    .container {
        width: 1100px;
        height: 430px;
    }
     
    .hid {
        display: none;
        width: 90%;
        height: 380px;
        background-color: #f3f3f3;
        border-top-right-radius: 10px;
        border-top-left-radius: 10px;
        margin-left: 70px
    }
     
    .view {
        display: inherit;
        width: 90%;
        height: 380px;
        background-color: #f3f3f3;
        border-top-right-radius: 10px;
        border-top-left-radius: 10px;
        margin-left: 70px
    }
     
    .btn {
        width: 100px;
        height: 32px;
        background-color: #f68e56;
        border-radius: 100px;
    }

Что такое Аксиос?

Axios — это инструмент для отправки HTTP-запросов и обработки ответов. Он написан поверх Promise API и может использоваться как в браузере, так и на сервере. Это быстро, просто и поддерживает такие функции, как кэширование, тайм-аут и аутентификация.

Мы будем использовать Axios для отправки запросов к конечной точке нашего проекта Strapi из-за его возможностей и функций. Давайте запустим Axios в нашем приложении React.

Установка Аксиос

Чтобы установить Axios, перейдите в папку проекта React в терминале и выполните приведенную ниже команду.

npm install Axios

Построение функциональности приложения

Чтобы добавить функциональность в наш проект, откройте app.js в редакторе кода и вставьте следующий код, а затем сохраните его.

// src/App.js
    import React, { useState, useEffect } from 'react';
    import axios from 'axios';
    import './App.css';
     
    function App() {
        const [email, setemail] = useState('2');
        const [gender, setgender] = useState('3');
        const [question1, setQuestion1] = useState("");
        const [question2, setQuestion2] = useState("");
        const [question3, setQuestion3] = useState("");
        const [response1, setResponse1] = useState("");
        const [response2, setResponse2] = useState("");
        const [response3, setResponse3] = useState("");
        const [lang, setLang] = useState("en");
        const [QuestionNum1, setQuestionNum1] = useState(1);
        const [QuestionNum2, setQuestionNum2] = useState(2);
        const [button, setButton] = useState("Start Survey");
        const  getsurvey = async (value) => {
     
            let Tasks = await axios.get('http://localhost:1337/api/surveys?locale=' + value);
            setQuestion1(Tasks.data.data\[0\]["attributes"]);
            setQuestion2(Tasks.data.data\[QuestionNum1\]["attributes"]);
            setQuestion3(Tasks.data.data\[QuestionNum2\]["attributes"]);
            setQuestionNum1(prev => QuestionNum1 + 2);
            setQuestionNum2(prev => QuestionNum2 + 2);
        }
     
     
     
        const load = (value) => {
             getsurvey(value);
        }
     
        const [checkbox, setCheckbox] = useState({ box1: "", box2: "",box3: ""});
     
     
        const updateBox = (box, value) => {
            if (box === "1") {
                if (checkbox.box1 === value) {
                    value = ""
                }
                setCheckbox(previousState => {
     
                    return { ...previousState, box1: value }
     
                });
     
            }
     
            if (box === "2") {
                if (checkbox.box2 === value) {
                    value = ""
                }
                setCheckbox(previousState => {
                    return { ...previousState, box2: value }
                });
            }
            if (box === "3") {
                if (checkbox.box3 === value) {
                    value = ""
                }
                setCheckbox(previousState => {
                    return { ...previousState, box3: value }
                });
            }
        }
     
     
     
        const [page, setpage] = useState(0);
        const [page0, set0page] = useState('view');
        const [page1, set1page] = useState('hid');
        const [page2, set2page] = useState('hid');
        const [page3, set3page] = useState('hid');
        const [page4, set4page] = useState('hid');
     
        const addTask = async (quest, valu) => {
            let res = await axios
                .post("http://localhost:1337/api/responses/", {
     
                    "data": { "Email": email, "surveyQuestion": quest, "surveyResponse": valu}
                })
     
           .catch((err) => console.log(err));
     
        };
     
        useEffect(() => {
            setResponse3(prev => checkbox.box1 + "," + checkbox.box2 + "," + checkbox.box3);
        }, [checkbox])
     
     
        const next = () => {
            if (page === 0) {
                set0page(prev => "hid");
                set1page(prev => "view");
                setpage(prev => page + 1);
                setButton(prev => "Next Question");
            }
            if (page === 1) {
                set1page(prev => "hid");
                set2page(prev => "view");
                setpage(prev => page + 1);
                setButton(prev => "Next Question");
            }
            if (page === 2) {
                set2page(prev => "hid");
                set3page(prev => "view");
                setpage(prev => page + 1);
                setButton(prev => "Submit");
            }
            if (page === 3) {
                set3page(prev => "hid");
                set4page(prev => "view");
                setpage(prev => 4);
                setButton(prev => "New Survey");
                addTask(question1.question, response1);
                addTask(question2.question, response2);
                addTask(question3.question, response3);
                 getsurvey(lang);
            }
            if (page === 4) {
                set4page(prev => "hid");
                set2page(prev => "view");
                setpage(prev => 2);
                setButton(prev => "Next Question");
            }
        }
        return (
            <div className="App" >
                <div className="main">
                    <div className="bar1">
                        <center>
                            <span>Progress</span>
                            <div className="bar2">
                                <div className="bar3" >
                                    {page}/3
                                </div>
                            </div>
                        </center>
                    </div>
                    <div  id="surv" className={page0}>
     
                        <br />
                        <h2>welcome to my survey app</h2>
                        <div className="container">
                            <div className="divid1">
                                <br />
                                <input type="text" className="input" name="" placeholder="Email address" onChange={(event) => setemail(event.target.value)} />
                                <br /><br />
                                <label>Select Language</label>
                                <select className="input" onChange={(event) => load(event.target.value)} placeholder="Select Language">
                                    <option>Select Language</option>
                                    <option value="en">English </option>
                                    <option value="fr-CA">French</option>
                                </select>
                                <br />
                                <br />
                            </div>
                            <div className="divid2">
                                <br />
                                <input type="text" className="input" name="" placeholder="Gender" onChange={(event) => setgender(event.target.value)} />
                                <br /><br />
                            </div>
                        </div>
                    </div>
                    <div id="surv" className={page1}>
                        <br />
                        <h2>{question1.question}</h2>
                        <div className="container">
                            <div className="divid1">
                                <br />
                                <input type="text" className="input" name="" placeholder="Fullname" onChange={(event) => setResponse1(event.target.value)} />
                                <br />
                                <br />
                            </div>
                        </div>
                    </div>
                    <div id="surv" className={page2} hidden>
                        <br />
                        <h2>{question2.question}</h2>
                        <div className="radio_option">
                            <input type="radio" value="22" onClick={(event) => setResponse2(question2.a)} name="r" className="radio"  />
                            <label className="font1">{question2.a}</label>
                            <br /><br />
                            <input type="radio" value="22" name="r" className="radio" onClick={(event) => setResponse2(question2.b)}   />
                            <label className="font1">{question2.b}</label>
                            <br /> <br />
                            <input type="radio" value="ww" name="r" className="radio" onClick={(event) => setResponse2(question2.c)}   />
                            <label className="font1 magin1">{question2.c}</label>
                            <br /><br />
                        </div>
                    </div>
                    <div id="surv" className={page3} hidden>
                        <br />
                        <h2>{question3.question}</h2>
                        <div className="radio_option">
                            <input type="checkbox" name="e" className="checkbox" onClick={(event) => updateBox('1', question3.a)} />
                            <label className="font1">{question3.a}</label>
                            <br />
                            <br />
                            <input type="checkbox" onClick={(event) => updateBox('2', question3.b)} value="22" name="e" className="checkbox"   />
                            <label className="font1">{question3.b}</label>
                            <br />
                            <br />
                            <input type="checkbox" onClick={(event) => updateBox('3', question3.c)} value="." name="r" className="checkbox" />
                            <label className="font1">{question3.c}</label>
                            <br />
                            <br />
                        </div>
                    </div>
                    <div id="surv" className={page4}>
                        <br />
                        <h2>Survey completed</h2>
                        <div className="container">
                            <b> start another survey now</b>
                        </div>
                    </div>
                    <button className="btn" onClick={() => next()} > {button} </button>
                </div>
            </div>
        );
     
    }
    export default App;

Если вы выполнили все шаги с самого начала, ваше приложение для опроса должно быть запущено.

Как работает код?

Давайте объясним, как работает приведенный выше код, чтобы лучше понять приложение.

const  getsurvey = async (value) => {
     
            let Tasks = await axios.get('http://localhost:1337/api/surveys?locale=' + value);
            setQuestion1(Tasks.data.data\[0\]["attributes"]);
            setQuestion2(Tasks.data.data\[QuestionNum1\]["attributes"]);
            setQuestion3(Tasks.data.data\[QuestionNum2\]["attributes"]);
            setQuestionNum1(prev => QuestionNum1 + 2);
            setQuestionNum2(prev => QuestionNum2 + 2);
        }

Из приведенного выше кода следует, что метод getsurvey() использует Axios для выполнения запросов к серверной части. Язык интернационализации, который нужно получить из бэкенда Strapi, определяется параметром значения переменной.

Когда пользователь нажимает кнопку Начать опрос, вопросы опроса загружаются из страпи на основе языка, выбранного пользователем. Если язык, выбранный пользователем, является французским, то вопросы опроса будут на французском языке с использованием плагина интернационализации страпи.

const addTask = async (quest, valu) => {
            let res = await axios
                .post("http://localhost:1337/api/responses/", {
     
                    "data": { "Email": email, "surveyQuestion": quest, "surveyResponse": valu}
                })
     
           .catch((err) => console.log(err));
     
        };

Мы используем метод addTask() для хранения ответов пользователя на серверную часть. Всякий раз, когда пользователь заканчивает с набором вопросов опроса, и когда пользователь нажимает кнопку отправки, addTask() будет запускаться для отправки ответов в серверную часть.

useEffect(() => {
            setResponse3(prev => checkbox.box1 + "," + checkbox.box2 + "," + checkbox.box3);
        }, [checkbox])

Мы используем хук useEffect для обновления значений вопросов с несколькими вариантами ответа. Всякий раз, когда флажок установлен или снят, мы обновляем его соответствующим значением.

Заключение

Поздравляем! Вы успешно создали приложение для опроса с нуля.

В этом руководстве вы узнали, как настроить Strapi для приложения для проведения опросов, используя библиотеку React.js для внешнего интерфейса. Мы также узнали, как использовать интернационализацию в Strapi, чтобы предлагать контент на разных языках.

Вы можете просмотреть код этой статьи здесь.