合并请求分支下拉接口以及搜索

This commit is contained in:
caishi 2022-05-06 10:19:52 +08:00
parent 51d028336f
commit e4a95602cc
20 changed files with 436 additions and 155 deletions

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 2340181 */
src: url('iconfont.woff2?t=1649726899310') format('woff2'),
url('iconfont.woff?t=1649726899310') format('woff'),
url('iconfont.ttf?t=1649726899310') format('truetype');
src: url('iconfont.woff2?t=1651041108151') format('woff2'),
url('iconfont.woff?t=1651041108151') format('woff'),
url('iconfont.ttf?t=1651041108151') format('truetype');
}
.iconfont {
@ -13,6 +13,10 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-personal-center:before {
content: "\e927";
}
.icon-bangzhuzhongxinicon:before {
content: "\e926";
}

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,13 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "29206429",
"name": "personal-center",
"font_class": "personal-center",
"unicode": "e927",
"unicode_decimal": 59687
},
{
"icon_id": "28888753",
"name": "帮助中心icon",

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -25,7 +25,7 @@ if (isDev) {
}
debugType = window.location.search.indexOf('debug=t') !== -1 ? 'teacher' :
window.location.search.indexOf('debug=s') !== -1 ? 'student' :
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'admin'
window.location.search.indexOf('debug=a') !== -1 ? 'admin' : parsed.debug || 'student'
}
window._debugType = debugType;
export function initAxiosInterceptors(props) {

View File

@ -116,68 +116,45 @@ class CreateMerge extends Component {
this.setState({ isSpin: true });
const { pullOwner, pullBranch, mergeOwner, mergeBranch, projectId } = branchParams;
const url = `/${pullOwner}/${projectId}/pulls/new.json`;
axios
.get(url)
.then((result) => {
if (result) {
if(init){
//页面初始化时调用selectProjectName给is_original、fork_project_id、merge_user_login赋值
const initUser = result.data.projects_names && result.data.projects_names.filter((item)=>item.project_user_login === branchParams.mergeOwner);
initUser && initUser[0] && this.selectProjectName(initUser[0].id,false,{projects_names: result.data.projects_names,id: result.data.id});
}
this.setState({isSpin: false});
// 如果url上的分支不存在取默认值master
const noMergeBranch =
(result.data.branches || []).filter(
(branch) => branch.name === returnbar(mergeBranch)
).length === 0;
const noPullBranch =
(result.data.branches || []).filter(
(branch) => branch.name === returnbar(pullBranch)
).length === 0;
this.setState({
// isFork: result.data.is_fork,
projects_names: result.data.projects_names,
mergeProjects: result.data.merge_projects,
pullBranches: result.data.branches,
mergeBranches: result.data.branches,
project_id: result.data.project_id,
id: result.data.id,
merge: returnbar(mergeBranch),
pull: returnbar(pullBranch),
});
//判断源分支是否存在
if(noPullBranch){
this.setState({
showMessage: true,
defaultMessage:'源分支不存在',
isCompareSpin: false,
});
}else{
if(pullOwner === returnbar(mergeOwner)){
if (!noMergeBranch) {
this.compareProject(true, branchParams);
} else {
this.setState({
showMessage: true,
defaultMessage:'目标分支不存在',
isCompareSpin: false,
});
}
}else{
this.getBranchList(branchParams);
}
}
axios.get(url).then((result) => {
if (result) {
if(init){
//页面初始化时调用selectProjectName给is_original、fork_project_id、merge_user_login赋值
const initUser = result.data.projects_names && result.data.projects_names.filter((item)=>item.project_user_login === branchParams.mergeOwner);
initUser && initUser[0] && this.selectProjectName(initUser[0].id,false,{projects_names: result.data.projects_names,id: result.data.id});
}
this.setState({ isSpin: false });
})
.catch((error) => {
this.setState({ isSpin: false });
console.log(error);
});
this.setState({
// isFork: result.data.is_fork,
projects_names: result.data.projects_names,
mergeProjects: result.data.merge_projects,
// pullBranches: result.data.branches,
// mergeBranches: result.data.branches,
project_id: result.data.project_id,
id: result.data.id,
merge: returnbar(mergeBranch),
pull: returnbar(pullBranch),
});
this.checkBranch(branchParams);
this.setState({
isSpin: false,isCompareSpin: false
});
}
})
.catch((error) => {
this.setState({ isSpin: false });
console.log(error);
});
};
checkBranch=async(branchParams)=>{
const { mergeBranch , mergeOwner, projectId , pullBranch ,pullOwner} = branchParams;
let getbranch =await this.getBranchList(mergeOwner,projectId,pullBranch,mergeBranch);
// let checkpull =await this.getBranchList(pullOwner,projectId,pullBranch,"pull");
if(getbranch){
this.compareProject(mergeOwner === pullOwner, branchParams);
}
}
// compare接口获取分支对比信息
compareProject = (sameProject, branchParams) => {
const { pullOwner, pullBranch, mergeOwner, mergeBranch, projectId } = branchParams;
@ -187,8 +164,6 @@ class CreateMerge extends Component {
} else {
url += `/${Base64.encode(returnbar(mergeBranch))}...${pullOwner}/${projectId}:${Base64.encode(returnbar(pullBranch))}.json`;
}
console.log(url);
this.setState({ isSpin: false, isCompareSpin: true });
axios
.get(url)
.then((result) => {
@ -219,31 +194,40 @@ class CreateMerge extends Component {
};
// 根据所有者、仓库名,获取分支列表,目前仅涉及目标仓库分支查询
getBranchList = (branchParams) => {
const { mergeOwner, projectId, mergeBranch } = branchParams;
this.setState({ isSpin: true });
const url = `/${mergeOwner}/${projectId}/pulls/get_branches.json`;
axios
.get(url)
.then((result) => {
if (result) {
const noMergeBranch =
(result.data || []).filter((branch) => branch.name === mergeBranch)
.length === 0;
getBranchList =async(owner,identifier,branch,mergebranch) => {
const url = `/${owner}/${identifier}/branches.json`;
let check = await axios.get(url).then((result) => {
if(result.data){
let pfilter = (result.data || []).filter(i => i.name === branch).length === 0;
let mfilter = (result.data || []).filter(i => i.name === mergebranch).length === 0;
if(pfilter){
this.setState({
mergeBranches: result.data,
showMessage: noMergeBranch,
defaultMessage: '目标分支不存在',
isCompareSpin: false,
showMessage: branch,
defaultMessage: `源分支不存在`,
isCompareSpin: false
});
!noMergeBranch && this.compareProject(false, branchParams);
return false;
}
this.setState({ isSpin: false });
})
.catch((error) => {
this.setState({ isSpin: false });
console.log(error);
});
if(mfilter){
this.setState({
showMessage: mergebranch,
defaultMessage: `目标分支不存在`,
isCompareSpin: false
});
return false;
}
this.setState({
pullBranches:result.data,
mergeBranches:result.data
})
return true;
}
})
.catch((error) => {
this.setState({ isSpin: false });
check = false;
});
return check;
};
// 切换分支事件
@ -339,21 +323,25 @@ class CreateMerge extends Component {
};
// 源分支-分支搜索
changePullValue=(value,cate)=>{
changePullValue=async(value,cate)=>{
const branchParams = getBranchParams(this.props.location.pathname);
const { pullOwner , projectId } = branchParams;
const url = `/${pullOwner}/${projectId}/pulls/new.json`;
const { pullOwner, mergeOwner , projectId } = branchParams;
const url = `/${cate === "pull" ? pullOwner :mergeOwner}/${projectId}/pulls/get_branches.json`;
axios.get(url,{
params:{branch_name:value || undefined}
params:{
name:value || undefined,
}
}).then(result=>{
if(result){
if(cate === "pull"){
this.setState({
pullBranches:result.data.branches
pullBranches:result.data,
pullBranch:result.data
})
}else{
this.setState({
mergeBranches:result.data.branches
mergeBranches:result.data,
mergeBranch:result.data
})
}
}
@ -379,7 +367,6 @@ class CreateMerge extends Component {
} = this.state;
let { project } = this.props;
return (
<div>
<Spin spinning={isSpin || isCompareSpin}>
@ -402,8 +389,8 @@ class CreateMerge extends Component {
className="merge-flex1 flex1 matchwidth"
dropdownMatchSelectWidth={false}
dropdownClassName="overlihide"
onSearch={(e)=>this.changePullValue(e,"pull")}
filterOption={(input,option)=>option}
// onSearch={(e)=>this.changePullValue(e,"pull")}
// filterOption={(input,option)=>option}
>
{this.renderBrances(pullBranches)}
</Select>
@ -432,8 +419,8 @@ class CreateMerge extends Component {
className="merge-flex1 flex1 matchwidth"
dropdownMatchSelectWidth={false}
dropdownClassName="overlihide"
onSearch={(e)=>this.changePullValue(e,"merge")}
filterOption={(input,option)=>option}
// onSearch={(e)=>this.changePullValue(e,"merge")}
// filterOption={(input,option)=>option}
>
{this.renderBrances(mergeBranches)}
</Select>

View File

@ -11,7 +11,7 @@
}
.quillFlag {
position: absolute;
bottom: 0px;
bottom: 30px;
left: 6px;
height: 20px;
line-height: 18px;

View File

@ -210,17 +210,17 @@ class order_form extends Component {
if (result && result.data.id) {
this.props.showNotification("任务创建成功!");
this.props.history.push(`/${owner}/${projectsId}/issues/${result.data.id}`);
this.setState({
description: "",
isSpin: false,
});
const { getDetail } = this.props;
getDetail && getDetail();
}
this.setState({
description: "",
isSpin: false,
});
})
.catch((error) => {
this.setState({
isSpin: false,
isSpin: false
});
});
} else {
@ -240,10 +240,13 @@ class order_form extends Component {
const { getDetail } = this.props;
getDetail && getDetail();
}
this.setState({
isSpin: false
});
})
.catch((error) => {
this.setState({
isSpin: false,
isSpin: false
});
});
}

View File

@ -42,13 +42,14 @@ class comments extends Component {
//添加评论
addjournals = () => {
const { content, reply_content } = this.state;
const { content, reply_content , fileList } = this.state;
this.setState({
journal_spin: true,
});
if (!content && !reply_content) {
this.setState({
journal_spin: false,
quillFlag:true
});
return;
}
@ -58,15 +59,12 @@ class comments extends Component {
const {
page,
limit,
fileList,
orderId,
reply_id,
is_reply,
atWhoLoginList,
} = this.state;
const url = `/issues/${orderId}/journals.json`;
axios
.post(url, {
@ -343,7 +341,7 @@ class comments extends Component {
height="30"
/>
</Link>
<div>
<div style={{position:"relative"}}>
<MDEditor
placeholder={"添加评论..."}
height={300}
@ -362,7 +360,7 @@ class comments extends Component {
projectsId = {projectsId}
></MDEditor>
<p className="quillFlag">
{quillFlag && <span className="">请输入评论内容</span>}
{quillFlag && <span>请输入评论内容</span>}
</p>
<Upload
className="commentStyle"

View File

@ -15,6 +15,7 @@ import Activity from './Activity';
import moment from 'moment';
import Axios from 'axios';
import Nodata from '../../Nodata';
import Personal from '../Personal/Index';
const { Option } = Select;
const aLimit = 5;
@ -95,8 +96,8 @@ function Index(props) {
}
}).catch(error=>{})
}
return(
props && props.menuKey === "0" ?
<div>
<div>
<ConcentrateProject
@ -127,6 +128,8 @@ function Index(props) {
{ total > aLimit && <div style={{textAlign:'center',paddingBottom:"30px"}}><Pagination pageSize={aLimit} current={page} total={total} onChange={(p)=>setPage(p)}/></div> }
</div>
</div>
:
<Personal {...props}/>
)
}
export default Index;

View File

@ -216,7 +216,7 @@ ul.ant-menu.menuStyle li {
.infosRightMenu .ant-menu-item {
padding: 0px;
margin: 0px 20px !important;
margin: 0px 20px 0px 0px !important;
font-size: 17px;
height: 32px;
line-height: 0px;
@ -224,7 +224,7 @@ ul.ant-menu.menuStyle li {
position: relative;
}
.infosRightMenu .ant-menu-item a > i {
font-size: 15px !important;
font-size: 15px;
margin-right: 8px;
}
.infosRightMenu .ant-menu-item .menuNum {

View File

@ -24,7 +24,7 @@ export default withRouter(
secondRouter = props.location.pathname.split('/')[2];
}
let userRouterArr = ['statistics', 'projects', 'notice', 'devops', 'organizes', 'info', 'following', 'followers', 'password'];
let userRouterArr = ['statistics', 'projects', 'notice', 'devops', 'organizes', 'info', 'following', 'followers', 'password' , "general"];
return (
<Switch>

View File

@ -107,6 +107,46 @@ $flex:flex;
font-size: 16px;
text-align: center;
}
.usersDesc{
padding:20px 10px;
background-color: rgba(239, 247, 255, 1);
margin-top: 24px;
display: flex;
align-items: center;
flex-direction: column;
p{
text-align: left;
line-height: 20px;
font-size: 14px;
color: #666;
margin-bottom: 20px!important;
}
.emptyBtn{
width: 118px;
text-align: center;
height: 36px;
line-height: 34px;
border: 1px solid rgba(26, 71, 255, 1);
color: rgba(26, 71, 255, 1);
border-radius: 5px;
&:hover{
border-color:rgba(102, 132, 254, 1);
color: rgba(102, 132, 254, 1);
}
}
.fullBtn{
width: 118px;
text-align: center;
height: 36px;
line-height: 34px;
color: #fff!important;
border-radius: 5px;
background-color: rgba(70, 106, 255, 1);
&:hover{
background-color: rgba(102, 132, 254, 1);
}
}
}
.focusBox,.infoBox{
width: 100%!important;
display: inline-block;
@ -237,7 +277,7 @@ ul.ant-menu.menuStyle{
.infosRightMenu{
.ant-menu-item{
padding:0px;
margin:0px 20px!important;
margin:0px 30px 0px 0px !important;
font-size: 17px;
height: 32px;
line-height: 0px;
@ -245,9 +285,14 @@ ul.ant-menu.menuStyle{
position: relative;
a{
font-size: 16px;
display: flex;
align-items: center;
& >i{
font-size: 15px!important;
margin-right: 8px;
&.font-20{
font-size: 17px!important;
}
}
}
.menuNum{

View File

@ -58,6 +58,12 @@ const Notice = Loadable({
loader: () => import("../Notice/Index"),
loading: Loading,
})
const Personal = Loadable({
loader: () => import("./Personal/Index"),
loading: Loading,
})
class Infos extends Component {
constructor(props) {
super(props);
@ -67,15 +73,20 @@ class Infos extends Component {
project_type: undefined,
route_type: undefined,
undo_events:0,
menuKey:"0",
menuKey:"6",
avatarVisible:false
};
}
renderPath=(pathname)=>{
renderPath=(pathname,load)=>{
const { username } = this.props.match.params;
if(pathname === `/${username}`){
this.setState({menuKey:"0",route_type:undefined});
this.setState({route_type:undefined});
if(load){
this.setState({
menuKey:load.show_super_description ? "6" :"0"
})
}
}else if(pathname === `/${username}/statistics`){
this.setState({menuKey:"1",route_type:undefined});
}else if(pathname.indexOf(`/${username}/projects`)>-1){
@ -97,8 +108,6 @@ class Infos extends Component {
componentDidMount = () => {
this.fetchUser();
const { pathname } = this.props.location;
this.renderPath(pathname);
};
componentDidUpdate=(prevProps)=>{
@ -136,6 +145,8 @@ class Infos extends Component {
isSpin: false,
undo_events:e
});
const { pathname } = this.props.location;
this.renderPath(pathname,result.data);
})
.catch((error) => {
this.setState({
@ -211,10 +222,34 @@ class Infos extends Component {
}
}
chooseTab =(key)=>{
this.setState({
menuKey:key
})
}
aboutDescFunc =(flag)=>{
const { user } = this.state;
const url = `/users/${user && user.login}.json`;
const params={
user: {
user_extension_attributes: {
show_super_description:flag
}
}
}
axios.put(url,params).then(result=>{
if(result && result.data){
this.fetchUser();
}
})
}
render() {
const { current_user } = this.props;
const { username } = this.props.match.params;
const { user, isSpin, route_type , undo_events , menuKey , avatarVisible } = this.state;
return (
<div className="newMain clearfix">
{
@ -254,34 +289,42 @@ class Infos extends Component {
<div className="userDescription">
{user && user.description}
</div>
<div>
{/* {user && current_user && user.login === current_user.login && (
<div className="user-info-star-button ">
<Button
block
className="text-button-grey"
onClick={()=>this.props.history.push(`/${user.login}/info`)}
type="primary"
>
{" "}
<i className="iconfont icon-shezhi4 font-15 mr5"></i>
修改资料
</Button>
</div>
)} */}
{current_user && user && user.login !== current_user.login && (
<div className="user-info-star-button ">
<FocusButton
is_block={true}
is_watch={user.is_watch}
id={user.login}
fontClass={"font-14 ml5"}
starText={"关注TA"}
notReset={true}
/>
</div>
)}
</div>
{/* {user && current_user && user.login === current_user.login && (
<div className="user-info-star-button ">
<Button
block
className="text-button-grey"
onClick={()=>this.props.history.push(`/${user.login}/info`)}
type="primary"
>
{" "}
<i className="iconfont icon-shezhi4 font-15 mr5"></i>
修改资料
</Button>
</div>
)} */}
{current_user && user && user.login !== current_user.login && (
<div className="user-info-star-button ">
<FocusButton
is_block={true}
is_watch={user.is_watch}
id={user.login}
fontClass={"font-14 ml5"}
starText={"关注TA"}
notReset={true}
/>
</div>
)}
{
current_user && user && user.login === current_user.login &&
<div className="usersDesc">
<p>想全方位展示自己试试点击下方按钮定制化您的专属个人简介吧</p>
{
user.show_super_description ? <a className="emptyBtn" onClick={()=>this.aboutDescFunc(false)}>隐藏个人简介</a> : <a className="fullBtn" onClick={()=>this.aboutDescFunc(true)}></a>
}
</div>
}
<div className="focusBox">
<Link
to={`/${user && user.login}/following`}
@ -315,7 +358,11 @@ class Infos extends Component {
<div className="list-right">
{ !route_type && menuKey &&
<Menu selectedKeys={[menuKey]} mode={`horizontal`} className="infosRightMenu">
<Menu.Item key="0"><Link to={`/${user && user.login}`}><i className="iconfont icon-gailan"></i></Link></Menu.Item>
{
user && user.show_super_description &&
<Menu.Item key="6"><Link to={`/${user && user.login}`} onClick={()=>this.chooseTab("6")}><i className="iconfont icon-personal-center font-20"></i></Link></Menu.Item>
}
<Menu.Item key="0"><Link to={`/${user && user.login}`} onClick={()=>this.chooseTab("0")}><i className="iconfont icon-gailan"></i></Link></Menu.Item>
<Menu.Item key="1"><Link to={`/${user && user.login}/statistics`}><i className="iconfont icon-shujutongji"></i></Link></Menu.Item>
<Menu.Item key="2"><Link to={`/${user && user.login}/projects`}><i className="iconfont icon-xiangmu"></i></Link></Menu.Item>
{
@ -406,13 +453,19 @@ class Infos extends Component {
<Route
path="/:username"
render={(props) => {
return <GeneralView {...this.props} {...this.state} />;
return <GeneralView {...this.props} {...this.state} menuKey={menuKey} show_super_description={user && user.show_super_description}/>;
}}
></Route>
{/* <Route
path="/:username"
render={(props) => {
return <Personal {...this.props} {...this.state} />;
}}
></Route> */}
<Route
path="/"
render={(props) => {
return <GeneralView {...this.props} {...this.state} />;
return <GeneralView {...this.props} {...this.state} menuKey={menuKey}/>;
}}
></Route>
</Switch>

View File

@ -115,11 +115,11 @@ export default Form.create()(
<Checkbox>在个人主页展示</Checkbox>
)}
</Form.Item>
<Form.Item label="简介">
<Form.Item label="签名">
{getFieldDecorator("description",{
rules:[]
})(
<TextArea placeholder="请输入您的自我简介" rows={4} maxLength={140} style={{width:"600px"}}/>
<TextArea placeholder="请输入您的签名" rows={4} maxLength={140} style={{width:"600px"}}/>
)}
</Form.Item>
<AlignCenter>

View File

@ -0,0 +1,111 @@
import React, { useEffect, useState } from 'react';
import { Button } from 'antd';
import './Index.scss';
import MDEditor from "../../../modules/tpm/challengesnew/tpm-md-editor";
import RenderHtml from "../../../components/render-html";
import { Divider } from 'antd';
import axios from 'axios';
function Personal(props){
const { user ,current_user , resetUserInfo } = props;
const [ edit , setEdit ] = useState(false);
const [ showedit , setShowEdit ] = useState(false);
const [ description ,setDescription ] = useState("");
const [ copyDescription ,setCopyDescription ] = useState("");
useEffect(()=>{
if(user && user.super_description){
setDescription(user.super_description);
setCopyDescription(user.super_description);
setShowEdit(true);
}
},[user])
function onContentChange(value){
setDescription(value);
}
function emtptyEditFunc(){
setShowEdit(true);
setEdit(true);
}
function editCancelFunc(){
if(!copyDescription){
setShowEdit(false);
}
setDescription(copyDescription);
setEdit(false);
}
function editSaveFunc(){
const url = `/users/${user && user.login}.json`;
const params={
user: {
user_extension_attributes: {
super_description:description
}
}
}
axios.put(url,params).then(result=>{
if(result && result.data){
setCopyDescription(description);
setEdit(false);
setShowEdit(description ?true :false);
resetUserInfo && resetUserInfo();
}
})
}
return(
<div>
{
description || showedit?
user && current_user && user.login === current_user.login &&
<div className="editPanel">
{
edit ?
<div>
<Button ghost onClick={()=>editCancelFunc()}>取消</Button>
<Button type="primary" ghost onClick={editSaveFunc}>保存</Button>
</div>
:
<Button type="primary" ghost onClick={()=>setEdit(true)}>编辑</Button>
}
</div>
:
<div className="emptyDescBox">
<img src={require('./img/nullicon.png')} alt="" width="58px"/>
<p className="emptyMain">暂无数据</p>
{
current_user && user && (current_user.login === user.login) &&
<div className="emptyContent">
<p className="emptysub">您可以在此页面定制化您的个人简介信息包括开发者介绍宣传链接宣传图片等</p>
<Divider className="divider"/>
<a className="fullBtn" onClick={emtptyEditFunc}>编辑个人简介</a>
</div>
}
</div>
}
{
showedit ?
<div className="padding20">
{
edit ?
<MDEditor
placeholder={"请输入个人简介"}
height={500}
mdID={"personal-description"}
initValue={description || ""}
onChange={onContentChange}
isCanAtme = {false}
></MDEditor>
:
<RenderHtml className="break_word_comments imageLayerParent" value={description || ""} url={props.history.location} />
}
</div>
:
""
}
</div>
)
}
export default Personal;

View File

@ -0,0 +1,70 @@
.editPanel
{
display: flex;
justify-content: right;
padding:20px 20px 0px 0px;
.ant-btn.ant-btn-background-ghost{
color: #d0d0d0;
}
.ant-btn.ant-btn-primary.ant-btn-background-ghost {
border-color: #1890ff;
color: #1890ff;
margin-left: 20px;
&:hover{
background-color: #fff!important;
color: #1890ff;;
}
}
}
.emptyDescBox{
min-height:420px;
background-color:#fafcff;
border:1px solid;
border-color:rgba(42, 97, 255, 0.23);
border-radius:4px 4px 0px 0px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 20px;
.emptyMain{
height: 28px;
line-height: 28px;
margin-top: 22px;
color:#333333;
font-size:20px;
text-align: center;
}
.emptyContent{
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
.emptysub{
margin-top: 12px;
line-height:23px;
color:#333333;
font-size:14px;
text-align:center;
width: 325px;
}
.divider{
width: 400px;
min-width: 400px;
}
.fullBtn{
width: 118px;
text-align: center;
height: 36px;
line-height: 34px;
color: #fff!important;
border-radius: 5px;
background-color: rgba(70, 106, 255, 1);
&:hover{
background-color: rgba(102, 132, 254, 1);
}
margin:0px auto;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B