Notice
Recent Posts
Recent Comments
250x250
Creative Code
Aurora-(13)최종 프로젝트 2 -Myprofile,maps,video 본문
728x90
--> myProfile 화면에서 본인의 Nickname, 상태메시지 설정 가능, 본인이 작성한 story 내역 전체 확인 가능, 오른쪽에있는 <<버튼 클릭시 본인의 팔로잉유저 또는 팔로워 유저를 조회가능, 언팔로우 기능 제공
※ myprofile 화면(front-end)를 구성하는 코드 : pages/myprofile.py
# aurora.state.home 모듈에서 필요한 State 및 HomeState를 가져옵니다.
import reflex as rx
from aurora.state.base import State
from aurora.state.home import HomeState
# 컴포넌트를 가져옵니다.
from ..components import container
# 탭 버튼을 생성하는 함수
def tab_button(name, href):
"""A tab switcher button."""
return rx.link(
rx.icon(tag="star", mr=2), # 별 모양 아이콘
name, # 버튼 텍스트
display="inline-flex",
align_items="center",
py=3,
px=6,
href=href, # 버튼 클릭 시 이동할 경로
border="1px solid #eaeaea",
font_weight="semibold",
border_radius="full",
)
# 왼쪽에 표시되는 탭 스위처
def tabs():
"""The tab switcher displayed on the left."""
return rx.box(
rx.vstack(
rx.container(
rx.hstack(
rx.icon(tag="spinner", mr=2, color='green'), # 달 모양 아이콘
rx.text(
"Aurora",
style={
"fontSize": "25px",
"fontWeight": "bolder",
"fontFamily": "Open Sans,Sans-serif",
"background": "-webkit-linear-gradient(-45deg, #77e67d, #3c8552)",
"-webkit-background-clip": "text",
"color": "transparent",
},
center_content=True,
), # 앱 이름
),
),
tab_button("Home", "/"), # Home 탭 버튼
tab_button("My Profile","/myprofile"),
tab_button("Maps","/maps"),
tab_button("video","/video"),
tab_button("web search","/websearch"),
tab_button("ai_chat","aichat"),
tab_button("talk","/talk"),
rx.button(
rx.icon(tag="moon"),
on_click=rx.toggle_color_mode,
),
rx.button("Log out", on_click=State.logout), # 로그아웃 버튼
rx.container(height='200px'),
align_items="left",
gap=4,
),
py=4,
)
# 오른쪽에 표시되는 사이드바
def sidebar(HomeState):
"""The sidebar displayed on the right."""
return rx.box(
rx.vstack(
rx.container(height='8px'),
rx.container(
rx.button(
rx.icon(
tag="arrow_left",
on_click=HomeState.right
),
),
),
rx.drawer(
rx.drawer_overlay(
rx.drawer_content(
rx.drawer_header(
rx.input(
on_change=HomeState.set_friend,
placeholder="Search users", # 사용자 검색을 위한 입력 상자
width="100%",
),
rx.foreach(
HomeState.search_users,
lambda user: rx.vstack(
rx.hstack(
rx.avatar(name=user.username, size="sm"), # 검색된 사용자의 아바타 이미지
rx.text(user.username), # 검색된 사용자의 사용자 이름
rx.spacer(),
rx.button(
rx.icon(tag="add"),
on_click=lambda: HomeState.follow_user(user.username), # 사용자를 팔로우하는 버튼
),
width="100%",
),
py=2,
width="100%",
),
),
),
rx.drawer_body(
rx.box(
rx.heading("Followers", size="sm"),
rx.foreach(
HomeState.followers,
lambda follow: rx.vstack(
rx.hstack(
rx.avatar(name=follow.follower_username, size="sm"), # 팔로워의 아바타 이미지
rx.text(follow.follower_username), # 팔로워의 사용자 이름
width="100%",
),
padding="1em",
),
),
p=4,
border_radius="md",
border="1px solid #eaeaea",
),
rx.container(height='8px'),
rx.box(
rx.heading("Following", size="sm"),
rx.foreach(
HomeState.following,
lambda follow: rx.vstack(
rx.hstack(
rx.avatar(name=follow.followed_username, size="sm"), # 팔로잉 중인 사용자의 아바타 이미지
rx.text(follow.followed_username), # 팔로잉 중인 사용자의 사용자 이름
rx.spacer(),
rx.button(
rx.icon(tag="minus"),
on_click=lambda: HomeState.unfollow_user(follow.followed_username),
),
),
padding="1em",
),
),
p=4,
border_radius="md",
border="1px solid #eaeaea",
w="100%",
),
align_items="start",
gap=4,
h="100%",
py=4,
),
rx.drawer_footer(
rx.button(
"Close", on_click=HomeState.right
)
),
bg="rgba(100, 100, 100, 0.7)",
)
),
is_open=HomeState.show_right,
),
)
)
# 피드의 헤더
def feed_header(HomeState):
"""The header of the feed."""
return rx.hstack(
rx.heading("Story", size="md"), # 피드의 제목
rx.input(on_change=HomeState.set_search, placeholder="Search"), # 트윗 검색을 위한 입력 상자
justify="space-between",
p=4,
border_bottom="3px solid #000000",
)
def composer(HomeState):
HomeState.setting_user_id
HomeState.syn_user_name
HomeState.syn_user_status_message
HomeState.syn_user_account_status
HomeState.getprofile
return rx.vstack(
rx.container(height='10px'),
rx.vstack(
rx.hstack(
rx.vstack(
rx.container(height='10px'),
rx.avatar(size="xl"), # 사용자의 아바타 이미지
),
rx.vstack(
rx.text(HomeState.user.username, size = "md", fontSize = "30px", fontWeight = "bold"),
rx.text(HomeState.users_name, fontSize = "20px", fontweight='bold'),
rx.text(HomeState.users_status_message, fontSize = '15px'),
align_items='start',
),
p=4,
width='100%',
margin_left='5px',
align_items='start',
),
rx.hstack(
rx.hstack(
rx.button(
"load",
on_click = HomeState.getprofile,
border_radius="1em",
box_shadow="rgba(151, 65, 252, 0.8) 0 15px 30px -10px",
background_image="linear-gradient(144deg,#AF40FF,#5B42F3 50%,#00DDEB)",
box_sizing="border-box",
color="white",
opacity="0.6",
_hover={"opacity": 1},
),
rx.button(
"Edit Profile",
on_click = HomeState.change1,
border_radius="1em",
box_shadow="rgba(151, 65, 252, 0.8) 0 15px 30px -10px",
background_image="linear-gradient(144deg,#AF40FF,#5B42F3 50%,#00DDEB)",
box_sizing="border-box",
color="white",
opacity="0.6",
_hover={"opacity": 1},
),
rx.modal(
rx.modal_overlay(
rx.modal_content(
rx.modal_header("Edit Profile"),
rx.modal_body(
rx.vstack(
rx.hstack(
rx.vstack(
rx.text('Nickname '),
rx.container(height='3px'),
rx.text('Message '),
align_items='start',
),
rx.vstack(
rx.input(on_change=HomeState.set_edit_user_name, placeholder='write nickname'),
rx.input(on_change=HomeState.set_edit_user_status_message, placeholder='write status_message'),
align_items='start',
),
width='100%',
),
align_items='start',
),
),
rx.modal_footer(
rx.button(
'Confirm',
on_click=HomeState.change,
border_radius="1em",
box_shadow="rgba(151, 65, 252, 0.8) 0 15px 30px -10px",
background_image="linear-gradient(144deg,#AF40FF,#5B42F3 50%,#00DDEB)",
box_sizing="border-box",
color="white",
opacity="0.6",
_hover={"opacity": 1},
)
)
),
),
is_open=HomeState.show,
)
),
rx.container(width='10px'),
justify_content='flex-end',
width='100%',
),
rx.container(height='10px'),
width='100%',
border='3px solid #eda239',
border_radius='20px',
),
rx.container(height='10px'),
width ='97%',
margin_left='10px',
)
def tweet(tweet):
"""Display for an individual tweet in the feed."""
image_tags = rx.cond(
tweet.image_content,
rx.foreach(
tweet.image_content.split(", "),
lambda image: rx.image(src=f"/{image}", alt="tweet image")
),
rx.box() # 이미지가 없는 경우 빈 리스트를 반환합니다.
),
return rx.vstack(
rx.hstack(
rx.container(width='5px'),
rx.vstack(
rx.avatar(name=tweet.author, size="md"), # 트윗 작성자의 아바타 이미지
),
rx.box(
rx.hstack(
rx.text("@" + tweet.author, font_weight="bold"), # 트윗 작성자의 사용자 이름
rx.text("["+ tweet.created_at +"]"),
),
rx.text(tweet.content, width="100%"), # 트윗 내용
*image_tags,
width = '100%',
),
py=4,
gap=1,
border="3px solid #3498db",
border_radius='10px',
width='98%',
),
rx.container(height='5px'),
margin_left='15px',
align_items='start',
width='97%',
)
# 피드 영역
def feed(HomeState):
"""The feed."""
return rx.box(
feed_header(HomeState),
composer(HomeState),
rx.cond(
HomeState.user_tweets,
rx.foreach(
HomeState.user_tweets,
tweet
),
rx.vstack(
rx.button(
rx.icon(
tag="repeat",
mr=1,
),
rx.text("Click to load tweets"),
on_click=HomeState.get_user_tweet,
), # 트윗을 불러오는 버튼
p=4,
),
),
border_x="3px solid #000000",
)
# 마이 페이지
def myprofile():
State.check_login
return container(
rx.grid(
tabs(),
feed(HomeState),
sidebar(HomeState),
grid_template_columns="1fr 4fr 1fr",
h="100vh",
gap=4,
),
max_width="1600px",
)
--> 맨 위 입력칸에 키워드 입력시 kakao api를 활용해 키워드와 관련있는 장소를 검색하고 결과를 데이터프레임으로 제공하는 기능
※ maps 화면(front-end)을 구성하는 전체 코드 : pages/maps.py
# aurora.state.home 모듈에서 필요한 State 및 HomeState를 가져옵니다.
import reflex as rx
from aurora.state.base import State, User
from aurora.state.home import HomeState
# 컴포넌트를 가져옵니다.
from ..components import container
color = "rgb(107,99,246)"
# 탭 버튼을 생성하는 함수
def tab_button(name, href):
"""A tab switcher button."""
return rx.link(
rx.icon(tag="star", mr=2), # 별 모양 아이콘
name, # 버튼 텍스트
display="inline-flex",
align_items="center",
py=3,
px=6,
href=href, # 버튼 클릭 시 이동할 경로
border="1px solid #eaeaea",
font_weight="semibold",
border_radius="full",
)
# 왼쪽에 표시되는 탭 스위처
def tabs():
"""The tab switcher displayed on the left."""
return rx.box(
rx.vstack(
rx.container(
rx.hstack(
rx.icon(tag="moon", mr=2, color='yellow'), # 달 모양 아이콘
rx.text(
"Aurora",
style={
"fontSize": "25px",
"fontWeight": "bolder",
"fontFamily": "Open Sans,Sans-serif",
"background": "-webkit-linear-gradient(-45deg, #e04a3f, #4e8be6)",
"-webkit-background-clip": "text",
"color": "transparent",
},
center_content=True,
), # 앱 이름
),
),
tab_button("Home", "/"), # Home 탭 버튼
tab_button("My Profile","/myprofile"),
tab_button("Maps","/maps"),
tab_button("video","/video"),
tab_button("web search","/websearch"),
tab_button("ai chat","/aichat"),
tab_button("talk","/talk"),
rx.button("Sign out", on_click=State.logout), # 로그아웃 버튼
rx.button(
rx.icon(tag="moon"),
on_click=rx.toggle_color_mode,
),
rx.container(height='200px'),
align_items="left",
gap=4,
),
py=4,
)
def sidebar(HomeState):
return rx.vstack(
align_items="start",
gap=4,
h="100%",
py=4,
)
# 피드의 헤더
def feed_header(HomeState):
"""The header of the feed."""
return rx.hstack(
rx.heading("Maps", size="md"), # 피드의 제목
rx.input(on_blur=HomeState.set_tag_search, placeholder="Search tags"), # 트윗 검색을 위한 입력 상자
rx.button(
"Search",
on_click = HomeState.map_search,
border_radius="1em",
box_shadow="rgba(151, 65, 252, 0.8) 0 15px 30px -10px",
background_image="linear-gradient(144deg,#AF40FF,#5B42F3 50%,#00DDEB)",
box_sizing="border-box",
color="white",
opacity="0.6",
_hover={"opacity": 1},
),
rx.button(
"clear",
on_click = HomeState.map_clear,
border_radius="1em",
box_shadow="rgba(151, 65, 252, 0.8) 0 15px 30px -10px",
background_image="linear-gradient(144deg,#AF40FF,#5B42F3 50%,#00DDEB)",
box_sizing="border-box",
color="white",
opacity="0.6",
_hover={"opacity": 1},
),
justify="space-between",
p=4,
border_bottom="3px solid #ededed",
)
# 피드 영역
def feed(HomeState):
HomeState.map_iframe1
HomeState.clear_map1
HomeState.clear_map2
HomeState.clear_map3
return rx.box(
feed_header(HomeState),
rx.container(height='10px'),
rx.data_table(
data=HomeState.df,
font_size = '8px',
),
border_x="3px solid #ededed",
h="100%",
)
# 홈 페이지
def maps():
State.check_login
return container(
rx.grid(
tabs(),
feed(HomeState),
sidebar(HomeState),
grid_template_columns="1fr 4fr 1fr",
h="100vh",
gap=4,
),
max_width="1600px",
)
--> 비디오의 링크를 위에 입력시 해당 동영상을 광고없이 무한 반복재생 가능
※ video화면(front-end)를 구성하는 전체 코드 : pages/video.py
# aurora.state.home 모듈에서 필요한 State 및 HomeState를 가져옵니다.
import reflex as rx
from aurora.state.base import State
from aurora.state.home import HomeState
# 컴포넌트를 가져옵니다.
from ..components import container
color = "rgb(107,99,246)"
# 탭 버튼을 생성하는 함수
def tab_button(name, href):
"""A tab switcher button."""
return rx.link(
rx.icon(tag="star", mr=2), # 별 모양 아이콘
name, # 버튼 텍스트
display="inline-flex",
align_items="center",
py=3,
px=6,
href=href, # 버튼 클릭 시 이동할 경로
border="1px solid #eaeaea",
font_weight="semibold",
border_radius="full",
)
# 왼쪽에 표시되는 탭 스위처
def tabs():
"""The tab switcher displayed on the left."""
return rx.box(
rx.vstack(
rx.container(
rx.hstack(
rx.icon(tag="moon", mr=2, color='yellow'), # 달 모양 아이콘
rx.text(
"Aurora",
style={
"fontSize": "25px",
"fontWeight": "bolder",
"fontFamily": "Open Sans,Sans-serif",
"background": "-webkit-linear-gradient(-45deg, #e04a3f, #4e8be6)",
"-webkit-background-clip": "text",
"color": "transparent",
},
center_content=True,
), # 앱 이름
),
),
tab_button("Home", "/"), # Home 탭 버튼
tab_button("My Profile","/myprofile"),
tab_button("Maps","/maps"),
tab_button("video","/video"),
tab_button("web search","/websearch"),
tab_button("ai chat","/aichat"),
tab_button("talk","/talk"),
rx.button("Sign out", on_click=State.logout), # 로그아웃 버튼
rx.button(
rx.icon(tag="moon"),
on_click=rx.toggle_color_mode,
),
rx.container(height='200px'),
align_items="left",
gap=4,
),
py=4,
)
def sidebar():
"""The sidebar displayed on the right."""
return rx.vstack(
align_items="start",
gap=4,
h="100%",
py=4,
)
# 피드의 헤더
def feed_header(HomeState):
"""The header of the feed."""
return rx.hstack(
rx.heading("Video", size="md"), # 피드의 제목
rx.input(on_blur=HomeState.set_video_search, placeholder="Enter the link to the video.."), # 트윗 검색을 위한 입력 상자
rx.button(
"Search",
on_click = HomeState.search_video,
border_radius="1em",
box_shadow="rgba(151, 65, 252, 0.8) 0 15px 30px -10px",
background_image="linear-gradient(144deg,#AF40FF,#5B42F3 50%,#00DDEB)",
box_sizing="border-box",
color="white",
opacity="0.6",
_hover={"opacity": 1},
),
justify="space-between",
p=4,
border_bottom="3px solid #ededed",
)
# 피드 영역
def feed(HomeState):
return rx.box(
feed_header(HomeState),
rx.vstack(
rx.container(height='10px'),
rx.video(
url = HomeState.show_video,
max_width = '700px',
max_height = 'auto',
playing = True,
loop = True,
),
),
border_x="3px solid #ededed",
h="100%",
)
# 홈 페이지
def video():
State.check_login
return container(
rx.grid(
tabs(),
feed(HomeState),
sidebar(),
grid_template_columns="1fr 4fr 1fr",
h="100vh",
gap=4,
),
max_width="1600px",
)
728x90
'Projects' 카테고리의 다른 글
Aurora-(15)최종 프로젝트 4 - 각 화면에서 동작하는 기능을 구현한 파일 (1) | 2023.11.28 |
---|---|
Aurora-(14)최종 프로젝트 3 - web search, ai chat, talk (0) | 2023.11.28 |
Aurora-(12)최종 프로젝트 1 - 소개, 로그인,회원가입,비밀번호찾기, 홈화면 구성 (0) | 2023.11.28 |
Aurora-(11)오라클 데이터베이스 연동하기 (0) | 2023.11.27 |
※Aurora 전체 코드 링크 (0) | 2023.11.26 |