Как создать веб-сайт портфолио React на базе Cosmic JS

В этом уроке я собираюсь продемонстрировать, как создать веб-сайт портфолио фотографий, используя React, Styled-Components и Космический JS. Давайте начнем.

TL;DR

Посмотреть и установить демо
Посмотреть код на GitHub

вступление

Космический JS обеспечивает хороший бэкэнд для ваших веб-приложений. Это полнофункциональная система управления контентом (CMS) с многочисленными опциями, которая позволяет всем членам вашей команды совместно управлять контентом. Cosmic JS предоставляет множество возможностей для разработчиков: администраторы Bucket могут назначать разные роли членам своей команды, создавать одиночные или множественные отношения между объектами и многое другое.

В этом примере я использую:

  • метаполе отношения нескольких объектов
  • изображения / файлы
  • ввод объектов по умолчанию

РеактJS: простая и гибкая JS-библиотека для создания клиентского приложения. React CLI позволяет создавать одностраничные приложения без настройки.

Стилизованные компоненты: альтернатива Static CSS, позволяет создавать отдельные компоненты для улучшения вашего приложения и расширения его возможностей.

Начиная

1. На панели управления Cosmic JS нажмите » Добавить новое ведро«.

1.1** Установить приложение **- Кнопка «Установить приложение», назначить имя приложения и «Сохранить корзину». После этого выберите приложение из списка приложений и нажмите «Установить бесплатно». И вы создали все необходимые для приложения объекты. Последнее, что нужно сделать: Скопируйте ключ API с рабочего стола Cosmic JS> Основные настройки> Слаг ковша.

1.2 С нуля — кнопку начать с нуля, назначить имя приложения и «Сохранить ведро». Для этого приложения вам нужно создать три типа объектов. Изображения, категории и сайты.

Картинки : Входные данные по умолчанию плюс дополнительные метаполя, называемые: «img» в качестве типа объекта изображения/файла, проверены по мере необходимости.

Категории : ввод по умолчанию плюс дополнительные метаполя, называемые: «изображения» как отношения нескольких объектов (выберите ограничение «Поиск по изображениям») и объект изображения/файла, называемый: «img».

Места : Тип ввода по умолчанию плюс дополнительные метаполя под названием «изображение».

Я создал Bucket для своего приложения и теперь готов погрузиться в код. Ссылка для вашего Ведро Слизняк.

Код

Клонируйте репозиторий с Github или создайте его с нуля. Этот пакет показывает все зависимости, используемые для приложения:

{
  "name": "portfolio",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "cosmicjs": "^3.2.14",
    "react": "^16.6.3",
    "react-dom": "^16.6.3",
    "react-pose": "^4.0.4",
    "react-pose-text": "^3.1.0",
    "react-router-dom": "^4.3.1",
    "react-scripts": "2.1.1",
    "styled-components": "^4.1.3",
    "styled-loaders": "^0.3.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}

После того, как вы установили React и все зависимости, вы готовы писать код.

Все данные скачиваются отдельно, параметр отправляется в react-router. После перехода к одному сообщению один элемент извлекается и отображается в компоненте.

Краткое пояснение о файловой структуре.

  • Наша первая задача — создать файловую структуру для проекта.

App.js по умолчанию, компонент папки:

кнопки (все созданные кнопки),

заголовки (все заголовки),

страница (все страницы),

части (все компоненты без состояния только в стиле const),

раздел (класс и функциональные компоненты, которые управляют данными и импортируют другие компоненты из файла частей),

л нет (поставщик темы глобального стиля макета приложения).

утилиты (цвет и тема объекта).

  App.js
│   index.js
│   serviceWorker.js
│
├───components
│   ├───buttons
│   │       Button.js
│   │
│   ├───headers
│   │       H1.js
│   │       H2.js
│   │
│   ├───page
│   │       Contact.js
│   │
│   ├───parts
│   │       Anchor.js
│   │       Caption.js
│   │       Card.js
│   │       CategoryCard.js
│   │       Center.js
│   │       Contain.js
│   │       Figure.js
│   │       Paragraph.js
│   │       PositionContainer.js
│   │
│   └───section
│           Category.js
│           Footer.js
│           Nav.js
│           PartGrid.js
│           Single.js
│           Wrap.js
│
├───layout
│       Layout.js
│
└───utils
        colors.js
        theme.js

Что внутри

Файл App.js, в котором находится маршрутизация и импорт макета, состояние интерактивных элементов. Здесь мы передаем данные, которые мы можем получить в другом компоненте в качестве реквизита.

import React, { Component } from 'react';
import {BrowserRouter, Switch, Route} from 'react-router-dom';

//CSS COMPONENT IMPORTS
import './font-awesome-4.7.0/css/font-awesome.min.css';
import Layout from './layout/Layout';
import Wrap from './components/section/Wrap';
import Category from './components/section/Category';
import PartGrid from './components/section/PartGrid';
import Contact from './components/page/Contact';
import Single from './components/section/Single';
import Footer from './components/section/Footer';
import Center from './components/parts/Center';

class App extends Component {
  state = {
    category:null,
    hg:false
  }
  componentDidMount = async () => {
    const Cosmic = require('cosmicjs');
    const api = Cosmic();
    const bucket = api.bucket({
    slug: 'ec055990-f24c-11e8-9231-9b47e8f95b7e'
    })
    const data = await bucket.getObjects({
      type: 'categories'
    })
    this.setState({
      category: data.objects,
    })
    document.addEventListener('scroll', () => {
      if(window.pageYOffset > 50 ) {
        this.setState({
          hg: true
        })
        }
        else{
          this.setState({
            hg: false
          })
        }
    });  
}
  handleMenu = () => {
    this.setState((prevProps) => ({visable: !prevProps.visable }));
  }    
  render() {
    console.log(this.state.category);
    return (
    <div className="App">
    <Layout>
    <BrowserRouter>
    <>
      <Wrap hg={this.state.hg} />
      <Switch>
        <Route path="/" exact render={(props) => <Category category={this.state.category}/>}/>  
        <Route path="/contact" exact component={Contact}  />
        <Route path="/img/:slug" component={Single} exact  />
        <Route path="/:slug" component={PartGrid} exact  />
      </Switch>
      </>
     </BrowserRouter>
     <Center fs> " A portfolio is a set of pictures by someone, or photographs of examples of their work, which they use when entering competitions or applying for work. "</Center>
     <Footer/>
    </Layout>
     </div>
    );
  }
}

export default App;

Раздел

Категория.js отображается как домашняя страница. Это отображает данные, загруженные в качестве реквизита из компонента app.js. Он также импортирует стилизованные компоненты из папки «parts».

import React from 'react'
import CategoryCard from './../parts/CategoryCard';
import CaptionWrap from '../parts/Caption';
import Button from './../buttons/Button';
import H1 from '../headers/H1';
import ContainerCategory from './../parts/Contain';
import Position from './../parts/PositionContainer';
import { Link } from 'react-router-dom'
import Par from './../parts/Paragraph';

export default function Category(props) {
  console.log("Props category", props);
return (
<ContainerCategory>
{props.category && props.category.map((item, index) => {
  return(
    <CategoryCard key={index} index={index + 1}>
      <img src={item.metadata.img.url} alt="img" index={index + 1} />
        <CaptionWrap index={index + 1}>   
         <Position index={index + 1}>
            <H1 isBig>{item.title}</H1>
            <Par  dangerouslySetInnerHTML={{__html:item.content}}></Par>
            <Link to={'/' + item.slug}><Button >See more</Button> </Link>
         </Position>
        </CaptionWrap>
      </CategoryCard>
      )
    })}
    </ContainerCategory>
  )
}

PartGrid.js — компонент состояния собирает данные из Cosmic JS. Страница с фотографиями в выбранной категории содержит ссылку на одну фотографию.

import React, { Component } from 'react'
import styled from 'styled-components'

import Card from '../parts/Card';
import Img from '../parts/Figure';
import Anchor from './../parts/Anchor';
import { Link } from 'react-router-dom';


const GridContainer = styled.div`
    min-height:100%;
    display:grid;
    margin:150px auto;
    justify-items:center;
    grid-template-column:1fr;
    grid-template-rows:400px;
    grid-gap:10px;
${({theme}) => theme.media.mobile} {
   grid-template-columns:320px 320px;
   width:640px;
}
${({theme}) => theme.media.tablet} {
    grid-template-columns:320px 320px 320px;
    width:960px;
    
}
${({theme}) => theme.media.desktop} {
    grid-template-columns:320px 320px 320px 320px;
    width:1280px;
    margin:200px auto 450px auto;
}
`;
export default class PartGrid extends Component {
    state ={
        picture: []
    }
    componentDidMount = async() => {
        const slug = this.props.match.params.slug;

        const Cosmic = require('cosmicjs')
        const api = Cosmic()
        const bucket = api.bucket({
        slug: 'imageapp'
        })
        const data = await bucket.getObject({
        slug: `${slug}`
        })
        this.setState({
            picture:data.object
        })
    }
  render() {
    return (
        <GridContainer column={true}>
        { this.state.picture.metadata && this.state.picture.metadata.images.map((item, index) => {
        return(
          <Card key={index}>
            <Img src={item.metadata.img.url} alt="grid-img"/>
            <Anchor as={Link} to={'/img/' + item.slug}>
            <i className="fa fa-link" aria-hidden="true"></i>
            </Anchor>
          </Card>
        )
       })}    
        </GridContainer>
    )
  }
}

Сингл.js — Это также компонент, содержащий состояние. Получает данные для одной фотографии от Cosmic JS.

import React, { Component } from 'react'

import CategoryCard from './../parts/CategoryCard';
import CaptionWrap from '../parts/Caption';
import Button from './../buttons/Button';
import H1 from '../headers/H1';
import ContainerCategory from './../parts/Contain';
import Position from './../parts/PositionContainer';
import { Link } from 'react-router-dom';
import Par from './../parts/Paragraph';

export default class Single extends Component {
    state ={
        img: null
    }
    componentDidMount = async() => {
        const link = this.props.match.params.slug;

        const Cosmic = require('cosmicjs')
        const api = Cosmic()
        const bucket = api.bucket({
        slug: 'imageapp'
        })
        const data = await bucket.getObject({
        slug: `${link}`
        })
        this.setState({
            img:data.object
        })
    }
 
  render() {
    return (
    <ContainerCategory>
    <CategoryCard index={0}>
    {this.state.img && <img src={this.state.img.metadata.img.url} alt="img" index={0} /> }
        <CaptionWrap index={0}>   
         <Position index={0}>
         {this.state.img &&  <H1 isBig>{this.state.img.title}</H1>}
         {this.state.img &&  <Par  dangerouslySetInnerHTML={{__html:this.state.img.content}}></Par>}
         </Position>
        </CaptionWrap>
      </CategoryCard>
      <br/> <br/>
      <Link to={'/'}><Button >Go back</Button></Link>
    </ContainerCategory>
    )
  }
}

Макет.js — содержит провайдер темы и глобальный стиль. Поскольку мы использовали провайдер темы, мы можем подключить CSS к React и использовать переменные CSS в зависимости от реквизитов компонента.

import React from 'react'

import {createGlobalStyle, ThemeProvider} from 'styled-components';
import { theme } from './../utils/theme';

const GlobalStyle = createGlobalStyle`
 body {
   padding: 0;
   box-sizing:border-box;
   margin 0;
   background:${({theme}) => theme.colors.light}
   font-family: Montserrat,'Segoe UI', sans-serif ;
   color:${({theme}) => theme.colors.dark}
  }
`;
export default function Layout({children}) {
  return (
    <ThemeProvider theme={theme}>
        <>
        <GlobalStyle />
        {children}
        </>
    </ThemeProvider>
  
  )
}

Nav.js — отдельный компонент состояния с собственными стилизованными компонентами и состоянием.

Части

В этой папке находятся только отдельные теги HTML, стилизованные в CSS (styled-components) и экспортируемые как отдельные компоненты.

Кнопки и заголовки

Стилизация отдельных HTML-тегов в styled-components): h1, кнопка и т. д.

Страница

Contact.js — компонент состояния, который извлекает данные из Cosmic JS и отображает их в приложении.

Утилиты

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

export const colors = {

    dark: '#1B1B1E',
    darkOne: '#373F51',
    middle: '#373F51',
    // light: '#D8DBE2',
    lightOne: '#A9BCD0',
    light: 'white'
}
import {colors} from './colors';

export const theme = {
    colors,
    fontWg: {
        thin:300,
        reg:400,
        fat:800
    },
    media: {
        desktop: '@media(min-width: 1324px)',
        tablet: '@media(min-width: 1024px)',
        mobile: '@media(min-width: 665px)',
    }
}

Вывод

Мы только что создали простое приложение, используя стилизованные компоненты, React JS и Cosmic JS. В начале мы увидели, как создать Bucket для нашего приложения. Затем мы создали шаблон с помощью React CLI и установили зависимости. После создания структуры папок и компонентов стилей в CSS мы загрузили данные из Cosmic JS для отображения в приложении.

Cosmic JS имеет отличный API для каждого приложения в сочетании с множеством опций для разработчиков и редакторов контента, которые позволяют беспрепятственно управлять контентом. Стилизованные компоненты позволяют создавать независимые компоненты, поэтому приложение может быть создано многими людьми, не вызывая конфликтов, таких как (имя класса в css) и т. д. В одной команде React CLI позволяет нам создать шаблон для нашего приложения.

Я рекомендую вам установить приложение, добавить свои компоненты и расширить функциональность. Веселиться!

Если у вас есть какие-либо комментарии или вопросы о создании приложений с помощью Cosmic JS, свяжитесь с нами в Twitter а также присоединиться к беседе в Slack.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *