Merge branch 'gek/webv2-merge' into develop

This commit is contained in:
Gabe Kangas 2023-01-30 14:06:10 -08:00
commit a51f831aa8
No known key found for this signature in database
GPG key ID: 4345B2060657F330
17 changed files with 90 additions and 178 deletions

View file

@ -2,13 +2,9 @@ name: Lint
on: on:
push: push:
branches:
- webv2
paths: paths:
- '.github/workflows/*' - '.github/workflows/*'
pull_request: pull_request:
branches:
- webv2
paths: paths:
- '.github/workflows/*' - '.github/workflows/*'

View file

@ -15,28 +15,28 @@ jobs:
with: with:
issue-number: ${{ github.event.issue.number }} issue-number: ${{ github.event.issue.number }}
body: | body: |
## Good First Issue ## Good First Issue
This item was marked as a good first issue because of the following: This item was marked as a good first issue because of the following:
- It's self contained as a single feature or change. - It's self contained as a single feature or change.
- Is clear when it's complete. - Is clear when it's complete.
- You do not need deep knowledge of Owncast to accomplish it. - You do not need deep knowledge of Owncast to accomplish it.
### Next Steps ### Next Steps
1. Comment on this issue before starting work so it can be assigned to you. Also, this issue may have been filed with limited detail or changes may have occurred that are worth sharing with you before you start work. 1. Comment on this issue before starting work so it can be assigned to you. Also, this issue may have been filed with limited detail or changes may have occurred that are worth sharing with you before you start work.
2. Drop by our [community chat](https://owncast.rocket.chat/) if you'd like to be involved in more real-time discussion around Owncast to talk about this change. 2. Drop by our [community chat](https://owncast.rocket.chat/) if you'd like to be involved in more real-time discussion around Owncast to talk about this change.
3. Follow the project's getting started tips to make sure you can [build and run the project from source](https://owncast.online/development). 3. Follow the project's getting started tips to make sure you can [build and run the project from source](https://owncast.online/development).
### Notes ### Notes
- Current web work is taking place in the [`webv2` branch](https://github.com/owncast/owncast/tree/webv2) and it is very much work in progress. Read the [README](https://github.com/owncast/owncast/blob/webv2/web/README.md) for this branch to get the web project running. But it's mostly just a `npm install` and `npm run dev`. - Development takes place on the `develop` branch.
- We use Storybook for testing and developing React components. `npm run storybook`. - We use Storybook for testing and developing React components. `npm run storybook`. A hosted version [is available for viewing](https://owncast.online/components).
- If you need to install the Go programming language to run the Owncast backend it's simple from [here](https://go.dev/dl/). - If you need to install the Go programming language to run the Owncast backend it's simple from [here](https://go.dev/dl/).
- Active contributors get an Owncast t-shirt! Ask about it if you feel like you've been contributing and haven't yet been given one. - Active contributors get an Owncast t-shirt! Ask about it if you feel like you've been contributing and haven't yet been given one.
### New to Git? ### New to Git?
If you're brand new to Git you may want a short primer about the Fork -> Commit -> Pull Request workflow that enables changes to get made collaboratively using git. Visit the [First Contributions](https://github.com/firstcontributions/first-contributions) project to learn step-by-step how to commit a change to a Git repository such as this one. If you're brand new to Git you may want a short primer about the Fork -> Commit -> Pull Request workflow that enables changes to get made collaboratively using git. Visit the [First Contributions](https://github.com/firstcontributions/first-contributions) project to learn step-by-step how to commit a change to a Git repository such as this one.

View file

@ -2,7 +2,7 @@ name: Build and Deploy Components+Style Guide
on: on:
push: push:
branches: branches:
- webv2 - develop
paths: ['web/stories/**', 'web/components/**', 'web/.storybook/**'] # Trigger the action only when files change in the folders defined here paths: ['web/stories/**', 'web/components/**', 'web/.storybook/**'] # Trigger the action only when files change in the folders defined here
jobs: jobs:
@ -13,8 +13,6 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
with:
ref: webv2 # Remove when webv2 gets merged into develop
- name: Install and Build - name: Install and Build
run: | # Install npm packages and build the Storybook files run: | # Install npm packages and build the Storybook files

View file

@ -2,7 +2,6 @@ name: Build and bundle web app into Owncast
on: on:
push: push:
branches: branches:
- webv2
- develop - develop
paths: paths:
- 'web/**' - 'web/**'

View file

@ -47,6 +47,5 @@ jobs:
# Chromatic GitHub Action options # Chromatic GitHub Action options
with: with:
workingDir: web workingDir: web
autoAcceptChanges: webv2
projectToken: f47410569b62 projectToken: f47410569b62
onlyChanged: true onlyChanged: true

View file

@ -3,12 +3,12 @@ name: Lint
on: on:
push: push:
branches: branches:
- webv2 - develop
paths: paths:
- 'Dockerfile' - 'Dockerfile'
pull_request: pull_request:
branches: branches:
- webv2 - develop
paths: paths:
- 'Dockerfile' - 'Dockerfile'

View file

@ -8,10 +8,10 @@ on:
- cron: '0 2 * * *' - cron: '0 2 * * *'
push: push:
branches: branches:
- webv2 - develop
pull_request: pull_request:
branches: branches:
- webv2 - develop
jobs: jobs:
Earthly: Earthly:
@ -42,15 +42,6 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Build and push
if: ${{ github.event_name == 'schedule' && env.GH_CR_PAT != null }}
env:
GH_CR_PAT: ${{ secrets.GH_CR_PAT }}
EARTHLY_BUILD_TAG: 'webv2'
EARTHLY_BUILD_BRANCH: 'webv2'
EARTHLY_PUSH: true
run: ./build/develop/container.sh
- name: Build and push - name: Build and push
if: ${{ github.event_name == 'schedule' && env.GH_CR_PAT != null }} if: ${{ github.event_name == 'schedule' && env.GH_CR_PAT != null }}
uses: nick-fields/retry@v2 uses: nick-fields/retry@v2

View file

@ -3,12 +3,12 @@ name: Lint
on: on:
push: push:
branches: branches:
- webv2 - develop
paths: paths:
- '**.sh' - '**.sh'
pull_request: pull_request:
branches: branches:
- webv2 - develop
paths: paths:
- '**.sh' - '**.sh'

View file

@ -9,7 +9,7 @@ set -e
# $EARTHLY_BUILD_TAG: tag for container image # $EARTHLY_BUILD_TAG: tag for container image
EARTHLY_IMAGE_NAME="owncast" EARTHLY_IMAGE_NAME="owncast"
BUILD_TAG=${EARTHLY_BUILD_TAG:-webv2} BUILD_TAG=${EARTHLY_BUILD_TAG:-develop}
DATE=$(date +"%Y%m%d") DATE=$(date +"%Y%m%d")
VERSION="${DATE}-${BUILD_TAG}" VERSION="${DATE}-${BUILD_TAG}"

View file

@ -25,7 +25,7 @@ Specify the human readable version number in the `version` flag such as `v0.1.0`
Create and push the image to Docker Hub with a list of tags. You'll want to tag the image with both the new version number and `latest`. Create and push the image to Docker Hub with a list of tags. You'll want to tag the image with both the new version number and `latest`.
**Run**: `earthly --push +docker-all --images="owncast/owncast:0.1.0 owncast/owncast:latest gabekangas/owncast:0.1.0 gabekangas/owncast:latest" --version="webv2"` **Run**: `earthly --push +docker-all --images="owncast/owncast:0.1.0 owncast/owncast:latest gabekangas/owncast:0.1.0 gabekangas/owncast:latest" --version="v0.1.0"`
Omit `--push` if you don't want to push the image to Docker Hub and want to just build and test the image locally first. Omit `--push` if you don't want to push the image to Docker Hub and want to just build and test the image locally first.

View file

@ -3,8 +3,7 @@
"config:base" "config:base"
], ],
"baseBranches": [ "baseBranches": [
"develop", "develop"
"webv2"
], ],
"timezone": "America/Los_Angeles", "timezone": "America/Los_Angeles",
"lockFileMaintenance": { "lockFileMaintenance": {

View file

@ -5,7 +5,7 @@ import { ColorRow } from './Color';
# Default theme colors # Default theme colors
These colors are assigned in our [color token](https://github.com/owncast/owncast/tree/webv2/web/style-definitions/tokens/color) files These colors are assigned in our [color token](https://github.com/owncast/owncast/tree/develop/web/style-definitions/tokens/color) files
and get reflected here as they change. run `npm run build-styles` to regenerate. and get reflected here as they change. run `npm run build-styles` to regenerate.
<Story <Story

View file

@ -6,11 +6,11 @@ import { Image, ImageRow } from './ImageAsset';
# Images # Images
<ImageRow images={[ <ImageRow images={[
{src: "img/fediverse-black.png", name: "fediverse-black.png"}, {src: "/img/fediverse-black.png", name: "fediverse-black.png"},
{src: "img/fediverse-color.png", name: "fediverse-color.png"}, {src: "/img/fediverse-color.png", name: "fediverse-color.png"},
{src: "img/follow.svg", name: "follow.svg"}, {src: "/img/follow.svg", name: "follow.svg"},
{src: "img/indieauth.png", name: "indieauth.png"}, {src: "/img/indieauth.png", name: "indieauth.png"},
{src: "img/like.svg", name: "like.svg"}, {src: "/img/like.svg", name: "like.svg"},
{src: "img/repost.svg", name: "repost.svg"}, {src: "/img/repost.svg", name: "repost.svg"},
]}/> ]}/>

View file

@ -1,69 +0,0 @@
import { Meta } from '@storybook/addon-docs';
import { Typography } from 'antd';
<Meta title="Owncast/Documentation/Readme" />
<Typography.Title style={{ color: 'var(--primary-color)' }}>Owncast Web UI v2</Typography.Title>
Owncast is going through a complete rewrite of the web app frontend.
Visit the [UIv2 milestone](https://github.com/owncast/owncast/milestone/18) on GitHub to see the individual tasks for this project.
## Quick Links
- [Redesign project](https://github.com/owncast/owncast/milestone/18)
- [Currently defined colors](/story/owncast-style-guide-colors--page)
- [Owncast Frontend Chat](https://owncast.rocket.chat/group/frontend-dev)
## Why?
- Moving to a full React Component workflow allows the project to be more productive and build features faster.
- Share code between the web frontend UI and the existing admin.
- Address feedback from users.
- Better accessibility.
- Better mobile experience.
- Standardize styling across the project by using a single design language and style guide.
- Allows more people to contribute to the project if we use popular frameworks.
## What
- [Next.js](https://nextjs.org/)
- [React](https://reactjs.org/)
- [Ant Design](https://ant.design/)
## Contributing
1. Find a component that hasn't yet been worked on by looking through the [UIv2 milestone](https://github.com/owncast/owncast/milestone/18)
and the sidebar of components to the left.
1. See if you can have an example of this functionality in action via the [Owncast Demo Server](https://watch.owncast.online) or [Owncast Nightly Build](https://nightly.owncast.online) so you know how it's supposed to work if it's interactive.
1. Visit the `Docs` tab to read any specific documentation that may have been written about how this component works.
1. Go to the `Canvas` tab of the component you selected and see if there's a Design attached to it.
1. If there is a design, then that's a starting point you can use to start building out the component.
1. If there isn't, then visit the [Owncast Demo Server](https://watch.owncast.online), the [Owncast Nightly Build](https://nightly.owncast.online), or the proposed [v2 design](https://www.figma.com/proto/B6ICOn1J3dyYeoZM5kPM2A/Owncast---Review?node-id=643%3A646&scaling=min-zoom&page-id=643%3A17&starting-point-node-id=643%3A44) for some ways to start.
1. If no design exists, then you can ask around the Owncast chat for help, for come up with your own ideas!
1. No designs are stuck in stone, and we're using this as an opportunity to level up the UI of Owncast, so all ideas are welcome.
## How?
This rewrite is a large project, but like anything else, breaking it into pieces and working on one thing at a time will eventually get us to the finish line.
And that's what this interface lets us do. On this page we see all the different components still needing to be worked on, and have a place to document the functionality of these pieces.
## What about the Admin?
The admin has always been a Next+React+Ant project, so the goal is to touch that as little as possible except where needed to share code and styles.
## What is this page?
This is called [_Storybook_](https://storybook.js.org/docs/react/get-started/introduction).
Storybook is a tool for UI development. It makes development faster and easier by isolating components.
This allows you to work on one component at a time. You can develop entire UIs without needing to start
up a complex dev stack, force certain data into your database, or navigate around your application.
For example a button may have a disabled state that requires a specific scenario to take place in real-world use,
but here we you can just toggle the state to verify things are working as expected.
This means [new components should have a corresponding story added](https://storybook.js.org/docs/react/get-started/whats-a-story) to make it easier to maintain the project.
For more details about building React components read [this document](https://github.com/owncast/owncast/blob/webv2/web/components/_COMPONENT_HOW_TO.md) with specifics.
<img src="https://user-images.githubusercontent.com/9563255/187112334-e6c73bad-72df-42fc-9ee2-8d36ba615275.png"/>

View file

@ -6,15 +6,14 @@ import { Image, ImageRow } from './ImageAsset';
# Logos &amp; Graphics # Logos &amp; Graphics
<ImageRow images={[ <ImageRow images={[
{src: "project/header.png", name: "header.png"}, {src: "/project/header.png", name: "header.png"},
{src: "project/kiss-cut-stickers-5.5x5.5-default-60874a6c11849.png", name: "kiss-cut-stickers-5.5x5.5-default-60874a6c11849.png"}, {src: "/project/kiss-cut-stickers-5.5x5.5-default-60874a6c11849.png", name: "kiss-cut-stickers-5.5x5.5-default-60874a6c11849.png"},
{src: "project/logo-glare-outlined.png", name: "logo-glare-outlined.png"}, {src: "/project/logo-glare-outlined.png", name: "logo-glare-outlined.png"},
{src: "project/logo-glare-vector.svg", name: "logo-glare-vector.svg"}, {src: "/project/logo-glare-vector.svg", name: "logo-glare-vector.svg"},
{src: "project/logo-noglare-vector.svg", name: "logo-noglare-vector.svg"}, {src: "/project/logo-noglare-vector.svg", name: "logo-noglare-vector.svg"},
{src: "project/logo-translucent-grey.svg", name: "logo-translucent-grey.svg"}, {src: "/project/logo-translucent-grey.svg", name: "logo-translucent-grey.svg"},
{src: "project/logo-white.svg", name: "logo-white.svg"}, {src: "/project/logo-white.svg", name: "logo-white.svg"},
{src: "project/owncast-background.png", name: "owncast-background.png"}, {src: "/project/owncast-background.png", name: "owncast-background.png"},
{src: "project/owncast-browser-mobile.png", name: "owncast-browser-mobile.png"}, {src: "/project/owncast-browser-mobile.png", name: "owncast-browser-mobile.png"},
{src: "project/sticker-bigtech-alt.png", name: "sticker-bigtech-alt.png"},
]}/> ]}/>

View file

@ -6,36 +6,36 @@ import { Image, ImageRow } from './ImageAsset';
# Social Platform Images # Social Platform Images
<ImageRow images={[ <ImageRow images={[
{src: "img/platformlogos/bandcamp.svg", name: "bandcamp.svg"}, {src: "/img/platformlogos/bandcamp.svg", name: "bandcamp.svg"},
{src: "img/platformlogos/default.svg", name: "default.svg"}, {src: "/img/platformlogos/default.svg", name: "default.svg"},
{src: "img/platformlogos/discord.svg", name: "discord.svg"}, {src: "/img/platformlogos/discord.svg", name: "discord.svg"},
{src: "img/platformlogos/donate.svg", name: "donate.svg"}, {src: "/img/platformlogos/donate.svg", name: "donate.svg"},
{src: "img/platformlogos/facebook.svg", name: "facebook.svg"}, {src: "/img/platformlogos/facebook.svg", name: "facebook.svg"},
{src: "img/platformlogos/fediverse.svg", name: "fediverse.svg"}, {src: "/img/platformlogos/fediverse.svg", name: "fediverse.svg"},
{src: "img/platformlogos/follow.svg", name: "follow.svg"}, {src: "/img/platformlogos/follow.svg", name: "follow.svg"},
{src: "img/platformlogos/github.svg", name: "github.svg"}, {src: "/img/platformlogos/github.svg", name: "github.svg"},
{src: "img/platformlogos/gitlab.svg", name: "gitlab.svg"}, {src: "/img/platformlogos/gitlab.svg", name: "gitlab.svg"},
{src: "img/platformlogos/google.svg", name: "google.svg"}, {src: "/img/platformlogos/google.svg", name: "google.svg"},
{src: "img/platformlogos/instagram.svg", name: "instagram.svg"}, {src: "/img/platformlogos/instagram.svg", name: "instagram.svg"},
{src: "img/platformlogos/keyoxide.png", name: "keyoxide.png"}, {src: "/img/platformlogos/keyoxide.png", name: "keyoxide.png"},
{src: "img/platformlogos/ko-fi.svg", name: "ko-fi.svg"}, {src: "/img/platformlogos/ko-fi.svg", name: "ko-fi.svg"},
{src: "img/platformlogos/lbry.svg", name: "lbry.svg"}, {src: "/img/platformlogos/lbry.svg", name: "lbry.svg"},
{src: "img/platformlogos/liberapay.svg", name: "liberapay.svg"}, {src: "/img/platformlogos/liberapay.svg", name: "liberapay.svg"},
{src: "img/platformlogos/link.svg", name: "link.svg"}, {src: "/img/platformlogos/link.svg", name: "link.svg"},
{src: "img/platformlogos/linkedin.svg", name: "linkedin.svg"}, {src: "/img/platformlogos/linkedin.svg", name: "linkedin.svg"},
{src: "img/platformlogos/mastodon.svg", name: "mastodon.svg"}, {src: "/img/platformlogos/mastodon.svg", name: "mastodon.svg"},
{src: "img/platformlogos/matrix.svg", name: "matrix.svg"}, {src: "/img/platformlogos/matrix.svg", name: "matrix.svg"},
{src: "img/platformlogos/odysee.svg", name: "odysee.svg"}, {src: "/img/platformlogos/odysee.svg", name: "odysee.svg"},
{src: "img/platformlogos/patreon.svg", name: "patreon.svg"}, {src: "/img/platformlogos/patreon.svg", name: "patreon.svg"},
{src: "img/platformlogos/paypal.svg", name: "paypal.svg"}, {src: "/img/platformlogos/paypal.svg", name: "paypal.svg"},
{src: "img/platformlogos/snapchat.svg", name: "snapchat.svg"}, {src: "/img/platformlogos/snapchat.svg", name: "snapchat.svg"},
{src: "img/platformlogos/soundcloud.svg", name: "soundcloud.svg"}, {src: "/img/platformlogos/soundcloud.svg", name: "soundcloud.svg"},
{src: "img/platformlogos/spotify.svg", name: "spotify.svg"}, {src: "/img/platformlogos/spotify.svg", name: "spotify.svg"},
{src: "img/platformlogos/steam.svg", name: "steam.svg"}, {src: "/img/platformlogos/steam.svg", name: "steam.svg"},
{src: "img/platformlogos/tiktok.svg", name: "tiktok.svg"}, {src: "/img/platformlogos/tiktok.svg", name: "tiktok.svg"},
{src: "img/platformlogos/twitch.svg", name: "twitch.svg"}, {src: "/img/platformlogos/twitch.svg", name: "twitch.svg"},
{src: "img/platformlogos/twitter.svg", name: "twitter.svg"}, {src: "/img/platformlogos/twitter.svg", name: "twitter.svg"},
{src: "img/platformlogos/xmpp.svg", name: "xmpp.svg"}, {src: "/img/platformlogos/xmpp.svg", name: "xmpp.svg"},
{src: "img/platformlogos/youtube.svg", name: "youtube.svg"}, {src: "/img/platformlogos/youtube.svg", name: "youtube.svg"},
]}/> ]}/>

View file

@ -6,18 +6,18 @@ import { Image, ImageRow } from './ImageAsset';
# T-shirt # T-shirt
<ImageRow images={[ <ImageRow images={[
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-back-60873dde52297.png", name: "all-over-print-mens-crew-neck-t-shirt-white-back-60873dde52297.png"}, {src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-back-60873dde52297.png", name: "all-over-print-mens-crew-neck-t-shirt-white-back-60873dde52297.png"},
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-back-60873dde523ae.png", name: "all-over-print-mens-crew-neck-t-shirt-white-back-60873dde523ae.png"}, {src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-back-60873dde523ae.png", name: "all-over-print-mens-crew-neck-t-shirt-white-back-60873dde523ae.png"},
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-back-60873dde524ca.png", name: "all-over-print-mens-crew-neck-t-shirt-white-back-60873dde524ca.png"}, {src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-back-60873dde524ca.png", name: "all-over-print-mens-crew-neck-t-shirt-white-back-60873dde524ca.png"},
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-front-60873dde51eb3.png", name: "all-over-print-mens-crew-neck-t-shirt-white-front-60873dde51eb3.png"}, {src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-front-60873dde51eb3.png", name: "all-over-print-mens-crew-neck-t-shirt-white-front-60873dde51eb3.png"},
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-front-60873dde52064.png", name: "all-over-print-mens-crew-neck-t-shirt-white-front-60873dde52064.png"}, {src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-front-60873dde52064.png", name: "all-over-print-mens-crew-neck-t-shirt-white-front-60873dde52064.png"},
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-left-60873dde525e2.png", name: "all-over-print-mens-crew-neck-t-shirt-white-left-60873dde525e2.png"}, {src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-left-60873dde525e2.png", name: "all-over-print-mens-crew-neck-t-shirt-white-left-60873dde525e2.png"},
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-right-60873dde52184.png", name: "all-over-print-mens-crew-neck-t-shirt-white-right-60873dde52184.png"}, {src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-right-60873dde52184.png", name: "all-over-print-mens-crew-neck-t-shirt-white-right-60873dde52184.png"},
{src: "tshirt/all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62999.png", name: "all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62999.png"}, {src: "/tshirt/all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62999.png", name: "all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62999.png"},
{src: "tshirt/all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62aa4.png", name: "all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62aa4.png"}, {src: "/tshirt/all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62aa4.png", name: "all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62aa4.png"},
{src: "tshirt/all-over-print-womens-crew-neck-t-shirt-white-front-6087418b626d5.png", name: "all-over-print-womens-crew-neck-t-shirt-white-front-6087418b626d5.png"}, {src: "/tshirt/all-over-print-womens-crew-neck-t-shirt-white-front-6087418b626d5.png", name: "all-over-print-womens-crew-neck-t-shirt-white-front-6087418b626d5.png"},
{src: "tshirt/all-over-print-womens-crew-neck-t-shirt-white-front-6087418b62878.png", name: "all-over-print-womens-crew-neck-t-shirt-white-front-6087418b62878.png"}, {src: "/tshirt/all-over-print-womens-crew-neck-t-shirt-white-front-6087418b62878.png", name: "all-over-print-womens-crew-neck-t-shirt-white-front-6087418b62878.png"},
{src: "tshirt/all-over-print-womens-crew-neck-t-shirt-white-left-6087418b62b91.png", name: "all-over-print-womens-crew-neck-t-shirt-white-left-6087418b62b91.png"}, {src: "/tshirt/all-over-print-womens-crew-neck-t-shirt-white-left-6087418b62b91.png", name: "all-over-print-womens-crew-neck-t-shirt-white-left-6087418b62b91.png"},
{src: "tshirt/all-over-print-womens-crew-neck-t-shirt-white-right-6087418b62c88.png", name: "all-over-print-womens-crew-neck-t-shirt-white-right-6087418b62c88.png"}, {src: "/tshirt/all-over-print-womens-crew-neck-t-shirt-white-right-6087418b62c88.png", name: "all-over-print-womens-crew-neck-t-shirt-white-right-6087418b62c88.png"},
]}/> ]}/>