Skip to content

Commit

Permalink
[ALL] release: v1.2.0 (#608) (#620)
Browse files Browse the repository at this point in the history
* [AN/USER] feat: ํ‹ฐ์ผ“ ์˜ˆ๋งค ๋””์ž์ธ ์ˆ˜์ • (#567) (#570)

* feat: ํ‹ฐ์ผ“ ์˜ˆ๋งค ๋ฐ”ํ…€ ์‹œํŠธ ํ™”๋ฉด ๋””์ž์ธ ์ˆ˜์ •

* feat: ํฌ์Šคํ„ฐ ํฌ๊ธฐ ์ˆ˜์ •

* refactor: ํ‹ฐ์ผ“์„ ์„ ํƒํ•˜๋ฉด INVISIBLE๋กœ ๋ณ€ํ™˜

* refactor: ํ™”๋ฉด ๊ฒน์น˜๋Š” ํ˜„์ƒ ์ œ๊ฑฐ

* refactor: ๋ถˆํ•„์š”ํ•œ ๊ณต๋ฐฑ ์ œ๊ฑฐ

---------

Co-authored-by: re4rk <[email protected]>

* [AN/USER] feat: ํŽ˜์Šคํƒ€๊ณ  ์œ ์ € ์•ฑ ๋ฒ„์ „ ๋ณ€๊ฒฝ (#571) (#572)

* [BE] chore: ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์˜ ์„œ๋ธŒ ๋ชจ๋“ˆ์„ ์—…๋ฐ์ดํŠธ (#573) (#574)

* refactor: ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ฒŒ๋œ ํด๋ž˜์Šค๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค. (#513)

* [BE] feat: ํšŒ์›์˜ ํ•™์ƒ ์ธ์ฆ ์ •๋ณด ์กฐํšŒ API ๊ตฌํ˜„ (#496) (#531)

* refactor: ๋ฉ”์„œ๋“œ ๋„ค์ด๋ฐ ์ˆ˜์ • (verifiacte -> verify)

* feat: ํ•™์ƒ ์ธ์ฆ ์ •๋ณด ์กฐํšŒ ๊ธฐ๋Šฅ ๊ตฌํ˜„

* refactor: findByMemberIdWithFetch INNER JOIN์œผ๋กœ ์ˆ˜์ •

* refactor: inner line return ์œผ๋กœ ์ˆ˜์ •

* refactor: ์บ์‹ฑ๋œ Response ๋ฐ˜ํ™˜

* [AN/USER] fix: ์˜ˆ๋งค ์™„๋ฃŒ ํ™”๋ฉด ๋ฒ„๊ทธ ํ”ฝ์Šค (#575) (#576)

* fix: getParcelableExtraCompat

* update: ๋ฒ„์ „ ๋ณ€๊ฒฝ

* [ALL] ํ”„๋กœ์ ํŠธ README ์ถ”๊ฐ€ (#552) (#577)

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* docs: ๊ธฐ๋Šฅ ๊ฐ„๋‹จ ์†Œ๊ฐœ ์ž‘์„ฑ

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* docs: update

* Update README.md

์ค„๋ฐ”๊ฟˆ ์ˆ˜์ •

* docs: Update README.md

* Update README.md

๋ฐฑ์—”๋“œ ๊ธฐ์ˆ ์Šคํƒ ์ถ”๊ฐ€

* Update README.md

- JUnit5 ์˜คํƒ€ ์ˆ˜์ •

* Update README.md

๋ฐฑ์—”๋“œ ๊ธฐ์ˆ ์Šคํƒ flyway ์ถ”๊ฐ€

* ์ธํ”„๋ผ ์•„ํ‚คํ…์ฒ˜ ์‚ฌ์ง„ ์ถ”๊ฐ€

* Update infra structure image

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

---------

Co-authored-by: xxeol2 <[email protected]>
Co-authored-by: Hyun-Seo Oh / ์˜คํ˜„์„œ <[email protected]>
Co-authored-by: ํ•ด์‹œ <[email protected]>
Co-authored-by: Guga <[email protected]>

* [AN/USER] refactor: ViewModel Test Code Dispatcher Rule ์ถ”๊ฐ€ (#590)

* feat: coroutine dispatcher main rule ์ถ”๊ฐ€

* refactor: ํ‹ฐ์ผ“ ์˜ˆ๋งค ํ™”๋ฉด ViewModel ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ„ฐ๋ง

* refactor: ํ‹ฐ์ผ“ ๋ชฉ๋ก ํ™”๋ฉด ViewModel ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ„ฐ๋ง

* refactor: ํ‹ฐ์ผ“ ๊ธฐ๋ก ํ™”๋ฉด ViewModel ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ„ฐ๋ง

* refactor: ํ‹ฐ์ผ“ ์ž…์žฅ ํ™”๋ฉด ViewModel ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ„ฐ๋ง

* refactor: ํ•™์ƒ ์ธ์ฆ ํ™”๋ฉด ViewModel ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ„ฐ๋ง

* refactor: ๋กœ๊ทธ์ธ ํ™”๋ฉด ViewModel ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ„ฐ๋ง

* refactor: ํ•™๊ต ์„ ํƒ ํ™”๋ฉด ViewModel ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ„ฐ๋ง

* refactor: ๋งˆ์ดํŽ˜์ด์ง€ ํ™”๋ฉด ViewModel ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ„ฐ๋ง

* refactor: ํ™ˆ ํ™”๋ฉด ViewModel ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ„ฐ๋ง

* refactor: ์ถ•์ œ ๋ชฉ๋ก ํ™”๋ฉด ViewModel ํ…Œ์ŠคํŠธ ๋ฆฌํŒฉํ„ฐ๋ง

* refactor: ๋งˆ์ดํŽ˜์ด์ง€ ํ™”๋ฉด ViewModel ํ…Œ์ŠคํŠธ ์žฌ๋ณ€๊ฒฝ

* [AN/USER] feat: ๋ฒ„ํŠผ ๋”๋ธ” ํด๋ฆญ ๋ง‰๊ธฐ(#584) (#585)

* feat: SingleClick Util ์ถ”๊ฐ€

* feat: ๋ฐ”ํ…€ ์‹œํŠธ ๋ฐ”๊นฅ ํด๋ฆญ ๋ง‰๊ธฐ

* feat: single ํด๋ฆญ ์ ์šฉ

* refactor: SingleClick ๋ฉ”์„œ๋“œ๋ช… ๋ณ€๊ฒฝ

* refactor: xml ํŒŒ์ผ ํ˜ธ์ถœ ์ˆœ์„œ ๋งž์ถ”๊ธฐ

* [AN/USER] feat: ํ™ˆ ํ™”๋ฉด์—์„œ ๋’ค๋กœ๊ฐ€๊ธฐ ๋ˆ„๋ฅด๋ฉด ๊ณง๋ฐ”๋กœ ์ข…๋ฃŒ๋˜์ง€ ์•Š๋Š”๋‹ค. (#588)

* feat: ํ™ˆํ™”๋ฉด ๋’ค๋กœ๊ฐ€๊ธฐ ์ƒ์ˆ˜ ์ถ”๊ฐ€

* feat: ํ™ˆํ™”๋ฉด ๋’ค๋กœ๊ฐ€๊ธฐ ๋‘ ๋ฒˆ ํด๋ฆญ ์‹œ ์ข…๋ฃŒ

* [AN/USER] feat: SingleLivedata ์ œ๊ฑฐ (#586) (#587)

* refactor: ์‚ฌ์šฉํ•˜์ง€์•Š๋Š” SingleLiveData ์ œ๊ฑฐ

* refactor: ์‚ฌ์šฉํ•˜์ง€์•Š๋Š” Event ์ œ๊ฑฐ

* [AN/USER] feat: ์˜ˆ๋งค ์‹คํŒจ ์ผ€์ด์Šค ์ฒ˜๋ฆฌ(#369) (#593)

* feat: ์—๋Ÿฌ ์ฝ”๋“œ๋ฅผ ๊ตฌ๋ถ„ํ•œ๋‹ค

* feat: API ์š”์ฒญ ์‹คํŒจ ๊ฒฐ๊ณผ์— ๋”ฐ๋ผ ์—๋Ÿฌ ์ฝ”๋“œ๋ฅผ ์˜ˆ์™ธ๋กœ ๋˜์ง„๋‹ค

* feat: ํ‹ฐ์ผ“ ์˜ˆ๋งค ์š”์ฒญ์— ์‹คํŒจํ•˜๋ฉด ์˜ˆ์™ธ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

* feat: ์—๋Ÿฌ ์ฝ”๋“œ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋ฉ”์„ธ์ง€๋ฅผ ๋„์šด๋‹ค

* [AN/USER] refactor: ๋„คํŠธ์›Œํฌ ์—๋Ÿฌ ๋กœ๊น…์„ ํ™•์žฅํ•จ์ˆ˜ ์—†์ด ์ง์ ‘ ์ฒ˜๋ฆฌํ•œ๋‹ค(#595) (#596)

refactor: ๋„คํŠธ์›Œํฌ ์—๋Ÿฌ ๋กœ๊น…์„ ํ™•์žฅํ•จ์ˆ˜ ์—†์ด ์ง์ ‘ ์ฒ˜๋ฆฌํ•œ๋‹ค

* [BE] feat: ์ถ•์ œ ์กฐํšŒ ํ•„ํ„ฐ๋ง ๊ตฌํ˜„(#602) (#603)

* feat: specification ์ •์˜

* feat: FestivalFilter ์ •์˜

* feat: ์ถ•์ œ ์ง„ํ–‰ ์ƒํƒœ์— ๋”ฐ๋ฅธ Controller, Service ์ƒ์„ฑ

* refactor: private ์ƒ์„ฑ์ž๋ฅผ lombok ์„ ํ†ตํ•ด ์ƒ์„ฑ

* chore: ๊ด„ํ˜ธ ์ œ๊ฑฐ

* chore: ๋ณ€์ˆ˜ ์ƒ์ˆ˜ํ™”

* chore: given ์ ˆ ํƒ€์ž… ๋ช…์‹œ

* feat: ์ถ•์ œ ์กฐํšŒ ALL ์‚ญ์ œ ๋ฐ ๊ธฐ๋ณธ๊ฐ’์„ ์ง„ํ–‰ ์ค‘์œผ๋กœ ๋ณ€๊ฒฝ

* feat: ์ถ•์ œ ๋‹น์ผ์ด Progress์— ํฌํ•จ๋˜๋„๋ก ๋ณ€๊ฒฝ ๋ฐ Spec ๋ฆฌํŒฉํ„ฐ๋ง

* feat: ์ถ•์ œ ์ง„ํ–‰ ์ƒํ™ฉ๋ณ„ ์ •๋ ฌ ์กฐ๊ฑด ์ถ”๊ฐ€

* chore: ๋ฉ”์„œ๋“œ ์ˆœ์„œ ๋ณ€๊ฒฝ

* chore: index ์ถ”๊ฐ€

* chore: ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋ณ€๊ฒฝ

* chore: test ๊ฐœํ–‰ ๋ณ€๊ฒฝ ๋ฐ ๋ณ€์ˆ˜ ์žฌํ™œ์šฉ

* [AN/USER] feat: ํ™ˆํ™”๋ฉด ํ•„ํ„ฐ๋ง ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค (#600) (#606)

* feat: ์ถ•์ œ ๋ชฉ๋ก ํ•„ํ„ฐ ์ด๋ฆ„ ์ƒ์ˆ˜ํ™”

* feat: ์ถ•์ œ ๋ชฉ๋ก ์นฉ ์ƒ‰๊น” ๋ฐ ํ…์ŠคํŠธ ์Šคํƒ€์ผ ์ž‘์„ฑ

* feat: ์ถ•์ œ ๋ชฉ๋ก ์นฉ์œผ๋กœ ํ•„ํ„ฐ๋งํ•˜๊ธฐ ํ™”๋ฉด ๊ทธ๋ฆฌ๊ธฐ

* feat: ์ถ•์ œ ํ•„ํ„ฐ ๋ถ„๋ฅ˜ ์ •์˜

* feat: FestivalRepository ํ•„ํ„ฐ๋ง ์š”์ฒญ ๊ฐ€๋Šฅํ•˜๋„๋ก ์žฌ์ •์˜

* feat: ์ถ•์ œ ๋ชฉ๋ก ViewModel ์— ์ถ•์ œ ํ•„ํ„ฐ๋ง ๊ธฐ๋Šฅ ์ ์šฉ

* feat: ์ถ•์ œ ๋ชฉ๋ก Fragment ์— ํ•„ํ„ฐ๋ง ๊ธฐ๋Šฅ ์ ์šฉ

* feat: ์ถ•์ œ ๋ชฉ๋ก ํ•„ํ„ฐ๋ง API ์—ฐ๋™ ์ž‘์—…

* feat: ํŽ˜์Šคํƒ€๊ณ  ํ™ˆํ™”๋ฉด ์•„์ด์ฝ˜ ์ถ”๊ฐ€

* refactor: ์นฉ ์ƒ‰๊น” selector ๋„ค์ด๋ฐ ์ˆ˜์ •

* refactor: ์ถ•์ œ ๋ชฉ๋ก ์นฉ ์ƒ‰๊น” ๋„ค์ด๋ฐ ๋ณ€๊ฒฝ

* feat: ํ•„ํ„ฐ๋ง ์นฉ ๋‹คํฌ๋ชจ๋“œ ์ ์šฉ

* feat: ํ•„ํ„ฐ๋ง ์ƒํƒœ๋ฅผ ViewModel ์—์„œ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๋Š”๋‹ค

* feat: ํ˜„์žฌ ์„ ํƒ๋œ ์นฉ์˜ ํ•„ํ„ฐ๋ง์— ํ•ด๋‹นํ•˜๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ์š”์ฒญํ•œ๋‹ค

* fix: Loading ์ด ์•„๋‹ˆ๋ฉด ๊ตฌ์„ฑ ๋ณ€๊ฒฝ ์‹œ ์ถ•์ œ ๋ชฉ๋ก์„ ์žฌ์š”์ฒญํ•˜์ง€ ์•Š๋Š”๋‹ค

* [BE] refactor: /stages/{stageId}/tickets API์˜ N+1์„ ํ•ด๊ฒฐํ•œ๋‹ค.(#517) (#578)

* refactor: findAllByStageId fetch ์กฐ์ธ์œผ๋กœ ๋ณ€๊ฒฝ

* refactor: fetch join ๋ฉ”์„œ๋“œ ์‚ฌ์šฉํ•˜๋„๋ก ๋ณ€๊ฒฝ

* chore: Inner ์กฐ๊ฑด ๋ช…์‹œํ•˜๋„๋ก ๋ณ€๊ฒฝ

* [BE] ๋„๋ฉ”์ธ ์—”ํ‹ฐํ‹ฐ์˜ ์˜ˆ์™ธ๋ฅผ ์ •์˜, ์ ์šฉํ•˜๊ณ  ํ…Œ์ŠคํŠธ ํŒจํ‚ค์ง€ ๊ตฌ์กฐ๋ฅผ ์ •๋ฆฌํ•œ๋‹ค. (#482) (#515)

* feat: DomainValidException ์ถ”๊ฐ€

* fix: DomainValidException -> ValidException ๋ณ€๊ฒฝ, ์ˆ˜์ •

* feat: Validator ๊ฒ€์ฆ ๋กœ์ง ์ถ”๊ฐ€

* refactor: ๊ฒ€์ฆ ๋กœ์ง ๋„๋ฉ”์ธ์— ์ ์šฉ

* refactor: ValidException ์—๋Ÿฌ์ฝ”๋“œ ์ˆ˜์ •, Validator ๋กœ์ง ์ถ”๊ฐ€

* feat: Admin ๊ฒ€์ฆ ์ถ”๊ฐ€

* feat: EntryCode ๊ฒ€์ฆ ์ถ”๊ฐ€

* refactor: ๊ฒ€์ฆ ๋กœ์ง ๋Œ€ํญ ๊ฐœ์„ 

* test: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ํŒจํ‚ค์ง€ ๊ตฌ์กฐ์— ๋งž๊ฒŒ ์ด๋™

* test: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ถ”๊ฐ€

* test: Member ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ถ”๊ฐ€

* fix: EntryState IllegalArgumentException ๋ณ€๊ฒฝ

* fix: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ๊นจ์ง ์ˆ˜์ •

* refactor: Validator ํ˜ธ์ถœ ์‹œ ํ•„๋“œ๋ช… ๋ณ€์ˆ˜๋กœ ์ถ”์ถœ

* feat: IllegalArgumentException์„ ๋Œ€์ฒดํ•˜๋Š” UnexpectedException ์ถ”๊ฐ€, ์ ์šฉ

* feat: OAuth2Clients ์ค‘๋ณต ์ถ”๊ฐ€ ์‹œ ์—๋Ÿฌ ๋กœ๊ทธ ์ถ”๊ฐ€

* feat: UnexpectedException ์˜ˆ์™ธ ํ•ธ๋“ค๋Ÿฌ ์ถ”๊ฐ€

---------

Co-authored-by: BGuga <[email protected]>

* [BE] test properties show sql ๊ด€๋ จ ์„ค์ • ์‚ญ์ œ (#605) (#607)

test: ํ…Œ์ŠคํŠธ ๋กœ๊ทธ์— ์ฟผ๋ฆฌ ๋กœ๊ทธ ์ œ๊ฑฐํ•˜๋„๋ก ๋ณ€๊ฒฝ

* [BE] refactor: ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” AdminService ์ œ๊ฑฐ (#610) (#611)

* test: ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์— ์„œ๋น„์Šค ํด๋ž˜์Šค ์ œ๊ฑฐ

* refactor: AdminService ์‚ญ์ œ

* refactor: AdminDTO ์‚ญ์ œ

* style: ๊ฐœํ–‰ ์ˆ˜์ •

* [BE] ํ•™๊ต ์ •๋ณด API์— Swagger Annotation์„ ์ถ”๊ฐ€ (#597) (#598)

feat: SchoolController์— Swagger ์ •๋ณด ์ถ”๊ฐ€

Co-authored-by: hyunseo <>

* [AN/USER] feat: ์ถ•์ œ ๋ชฉ๋ก ํ™”๋ฉด UX ๊ฐœ์„ (#614) (#615)

* [AN] release: v1.2.0 (#618) (#619)

chore: release v1.2.0

---------

Co-authored-by: re4rk <[email protected]>
Co-authored-by: ํ•ด์‹œ <[email protected]>
Co-authored-by: Hyun-Seo Oh / ์˜คํ˜„์„œ <[email protected]>
Co-authored-by: xxeol2 <[email protected]>
Co-authored-by: seokjin8678 <[email protected]>
Co-authored-by: Guga <[email protected]>
  • Loading branch information
7 people authored Nov 16, 2023
1 parent 31a4abd commit a6bcaa9
Show file tree
Hide file tree
Showing 147 changed files with 2,231 additions and 1,024 deletions.
74 changes: 73 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,73 @@
# 2023-festa-go
# ํŽ˜์Šคํƒ€๊ณ , ๋Œ€ํ•™ ์ถ•์ œ๋ฅผ ๋”์šฑ ์ฆ๊ฒ๊ฒŒ!
> ๋Œ€ํ•™ ์ถ•์ œ ์ค„์„œ๊ธฐ ๋ฐ ์ถ•์ œ ์ •๋ณด ์ œ๊ณต ์„œ๋น„์Šค "ํŽ˜์Šคํƒ€๊ณ "
![](https://github.com/woowacourse-teams/2023-festa-go/assets/71129059/55f0d73b-c032-4c15-9cdf-40a560af948f)

๋‹ค๋“ค ์ฆ๊ฑฐ์›Œ ํ•˜๋Š” ๋Œ€ํ•™ ์ถ•์ œ์ด์ง€๋งŒ, ํ•œ ๊ฐ€์ง€ ๊ฑฑ์ •๋˜๋Š” ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ โ€˜์ค„ ์„œ๊ธฐโ€™์ž…๋‹ˆ๋‹ค. ํ‹ฐ์ผ“ํŒ…๊ณผ ์˜ˆ๋งค๋ฅผ ์œ„ํ•œ ์ง€๋ฃจํ•œ ์ค„์„œ๊ธฐ ๊ณผ์ •์€ ์ถ•์ œ์˜ ์žฌ๋ฏธ๋ฅผ ๋ฐ˜๊ฐ์‹œํ‚ค๋Š” ์š”์ธ์ž…๋‹ˆ๋‹ค.

ํŽ˜์Šคํƒ€๊ณ ๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์—ฌ, ์šฐ๋ฆฌ ๋ชจ๋‘๊ฐ€ ๋Œ€ํ•™ ์ถ•์ œ๋ฅผ ๋” ํŽธ๋ฆฌํ•˜๊ฒŒ ์ฆ๊ธฐ๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค.

ํŽ˜์Šคํƒ€๊ณ ๋ฅผ ํ†ตํ•ด ํ‹ฐ์ผ“์„ ์˜ˆ๋งคํ•˜๊ธฐ ์œ„ํ•ด ๋ถˆํŽธํ•œ ์ค„ ์„œ๊ธฐ ๊ณผ์ •์„ ๊ฑฐ์น  ํ•„์š” ์—†์ด ์˜จ๋ผ์ธ์œผ๋กœ ํ‹ฐ์ผ“์„ ์˜ˆ๋งคํ•˜๊ณ , ๋ณต์žกํ•œ ์ ˆ์ฐจ ์—†์ด ์Šค๋งˆํŠธํฐ์˜ QR ์ฝ”๋“œ๋งŒ์œผ๋กœ ์ž…์žฅ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<img width="1192" alt="image" src="https://github.com/woowacourse-teams/2023-festa-go/assets/71129059/8e761c81-6066-4f93-89af-b9d2d22eb577">

<br/>
<br/>

**โ–ท ๐Ÿ“ฒ ๋‹ค์šด๋กœ๋“œ |** [PlayStore](https://play.google.com/store/apps/details?id=com.festago.festago)

**โ–ท ๐Ÿ“ ํŒ€๋ธ”๋กœ๊ทธ |** [Festago ํŒ€๋ธ”๋กœ๊ทธ](https://festago.github.io/)

**โ–ท ๐Ÿ“ง ์—ฐ๋ฝ์ฒ˜ |** [email protected]

## Android
<div align="center">
<h3>ํ”„๋กœ์ ํŠธ ์•„ํ‚คํ…์ฒ˜</h3>
<img width="955" src="https://github.com/woowacourse-teams/2023-festa-go/assets/67777523/2fc5e26f-c628-41fe-b2d3-5b74da794fdc">
</div>

<div align="center">
<h3>๊ธฐ์ˆ  ์Šคํƒ</h3>
<img width="500" src="https://github.com/woowacourse-teams/2023-festa-go/assets/67777523/90c3eec2-ada6-4c83-a915-0ab3754ab40c">
</div>

## Backend
<div align="center">
<h3>๋ฐฑ์—”๋“œ ์ธํ”„๋ผ ์•„ํ‚คํ…์ฒ˜</h3>
<img width="800" src="https://github.com/woowacourse-teams/2023-festa-go/assets/103228463/aad084a6-c1ca-41fa-89c0-f2d2371e59cc">
</div>


<div align="center">
<h3>๊ธฐ์ˆ  ์Šคํƒ</h3>
<img src="https://img.shields.io/badge/Java17-000000?style=flat-square&logo=java&color=F40D12">
<img src="https://img.shields.io/badge/Spring_Boot_3-0?style=flat-square&logo=spring-boot&logoColor=white&color=%236DB33F">
<img src="https://img.shields.io/badge/MySQL_8-0?style=flat-square&logo=mysql&logoColor=white&color=4479A1">
<img src="https://img.shields.io/badge/Nginx-0?style=flat-square&logo=nginx&logoColor=white&color=009639">
<img src="https://img.shields.io/badge/Hibernate-0?style=flat-square&logo=hibernate&logoColor=white&color=%2359666C">
<img src="https://img.shields.io/badge/Amazon_EC2-0?style=flat-square&logo=amazon-ec2&logoColor=white&color=%23FF9900">
<img src="https://img.shields.io/badge/Flyway-0?style=flat-square&logo=flyway&color=%23CC0200">
<br/>
<img src="https://img.shields.io/badge/Amazon_CloudWatch-0?style=flat-square&logo=amazon-cloudwatch&logoColor=white&color=%23FF4F8B">
<img src="https://img.shields.io/badge/OAuth2-0?style=flat-square&logo=oauth2&logoColor=white&color=%23000000">
<img src="https://img.shields.io/badge/Gradle-0?style=flat-square&logo=gradle&logoColor=white&color=%2302303A">
<img src="https://img.shields.io/badge/Swagger-0?style=flat-square&logo=Swagger&logoColor=white&color=%2385EA2D">
<img src="https://img.shields.io/badge/GitHub%20Actions-0?style=flat-square&logo=GitHub%20Actions&logoColor=white&color=%232088FF">
<img src="https://img.shields.io/badge/JUnit5-0?style=JUnit5-square&logo=junit5&logoColor=white&color=%2325A162">
<img src="https://img.shields.io/badge/Jenkins-0?style=flat-square&logo=Jenkins&logoColor=white&color=%23D24939">
</div>
<br/>

## ๐ŸŽ‰ ์ถ•์ œ ์Šคํƒœํ”„๋ฅผ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค

|BackEnd|BackEnd|BackEnd|BackEnd|Android|Android|Android|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|![](https://avatars.githubusercontent.com/u/103228463?v=4&size=100)|![](https://avatars.githubusercontent.com/u/116627736?v=4&size=100)|![](https://avatars.githubusercontent.com/u/71129059?v=4&size=100)|![](https://avatars.githubusercontent.com/u/100915276?v=4&size=100)|![](https://avatars.githubusercontent.com/u/108349655?v=4&size=100)|![](https://avatars.githubusercontent.com/u/67777523?v=4&size=100)|![](https://avatars.githubusercontent.com/u/37167652?v=4&size=100)|
|[ํ‘ธ์šฐ](https://github.com/BGuga)|[๊ธ€๋ Œ](https://github.com/seokjin8678)|[์• ์‰ฌ](https://github.com/xxeol2)|[์˜ค๋ฆฌ](https://github.com/carsago)|[๋ฒ ๋ฅด](https://github.com/SeongHoonC)|[ํ•ด์‹œ](https://github.com/EmilyCh0)|[์•„ํฌ](https://github.com/re4rk)|

<br>

## โ›”๏ธ ๊ณต์—ฐ ๊ด€๋žŒ์‹œ ์ฃผ์˜์‚ฌํ•ญ
> ํŽ˜์Šคํƒ€๊ณ  ํŒ€์˜ ๊ทธ๋ผ์šด๋“œ ๋ฃฐ์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.
<img width="787" alt="image" src="https://github.com/woowacourse-teams/2023-festa-go/assets/71129059/85c4d4d0-24fa-4602-9eed-a9a2e4a6482e">
4 changes: 2 additions & 2 deletions android/festago/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ android {
applicationId = "com.festago.festago"
minSdk = 28
targetSdk = 34
versionCode = 3
versionName = "1.0.1"
versionCode = 7
versionName = "1.2.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ import com.festago.festago.data.service.FestivalRetrofitService
import com.festago.festago.data.util.onSuccessOrCatch
import com.festago.festago.data.util.runCatchingResponse
import com.festago.festago.model.Festival
import com.festago.festago.model.FestivalFilter
import com.festago.festago.model.Reservation
import com.festago.festago.repository.FestivalRepository
import javax.inject.Inject

class FestivalDefaultRepository @Inject constructor(
private val festivalRetrofitService: FestivalRetrofitService,
) : FestivalRepository {
override suspend fun loadFestivals(): Result<List<Festival>> =
runCatchingResponse { festivalRetrofitService.getFestivals() }
.onSuccessOrCatch { it.toDomain() }
override suspend fun loadFestivals(festivalFilter: FestivalFilter): Result<List<Festival>> =
runCatchingResponse {
festivalRetrofitService.getFestivals(festivalFilter.name)
}.onSuccessOrCatch { it.toDomain() }

override suspend fun loadFestivalDetail(festivalId: Long): Result<Reservation> =
runCatchingResponse { festivalRetrofitService.getFestivalDetail(festivalId) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.festago.festago.data.dto.ReservedTicketRequest
import com.festago.festago.data.service.TicketRetrofitService
import com.festago.festago.data.util.onSuccessOrCatch
import com.festago.festago.data.util.runCatchingResponse
import com.festago.festago.model.ErrorCode
import com.festago.festago.model.ReservedTicket
import com.festago.festago.model.Ticket
import com.festago.festago.model.TicketCode
Expand Down Expand Up @@ -31,9 +32,16 @@ class TicketDefaultRepository @Inject constructor(
.onSuccessOrCatch { it.toDomain() }

override suspend fun reserveTicket(ticketId: Int): Result<ReservedTicket> =
runCatchingResponse {
ticketRetrofitService.postReserveTicket(
ReservedTicketRequest(ticketId),
)
}.onSuccessOrCatch { it.toDomain() }
runCatchingResponse { ticketRetrofitService.postReserveTicket(ReservedTicketRequest(ticketId)) }
.onSuccessOrCatch { it.toDomain() }
.onFailure { throwable ->
val message = throwable.message ?: "ERROR_UNKNOWN"
val error: Throwable = when {
"NEED_STUDENT_VERIFICATION" in message -> ErrorCode.NEED_STUDENT_VERIFICATION()
"RESERVE_TICKET_OVER_AMOUNT" in message -> ErrorCode.RESERVE_TICKET_OVER_AMOUNT()
"TICKET_SOLD_OUT" in message -> ErrorCode.TICKET_SOLD_OUT()
else -> throwable
}
return Result.failure(error)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import com.festago.festago.data.dto.ReservationFestivalResponse
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query

interface FestivalRetrofitService {
@GET("/festivals")
suspend fun getFestivals(): Response<FestivalsResponse>
suspend fun getFestivals(
@Query("festivalFilter") festivalFilter: String,
): Response<FestivalsResponse>

@GET("/festivals/{festivalId}")
suspend fun getFestivalDetail(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.activity.addCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
Expand Down Expand Up @@ -37,6 +38,7 @@ class HomeActivity : AppCompatActivity() {
initView()
initObserve()
initResultLauncher()
initBackPressedDispatcher()
}

private fun initResultLauncher() {
Expand Down Expand Up @@ -129,6 +131,22 @@ class HomeActivity : AppCompatActivity() {
resultLauncher.launch(SignInActivity.getIntent(this))
}

private fun initBackPressedDispatcher() {
var backPressedTime = START_BACK_PRESSED_TIME
onBackPressedDispatcher.addCallback {
if ((System.currentTimeMillis() - backPressedTime) > FINISH_BACK_PRESSED_TIME) {
backPressedTime = System.currentTimeMillis()
Toast.makeText(
this@HomeActivity,
getString(R.string.home_back_pressed),
Toast.LENGTH_SHORT,
).show()
} else {
finish()
}
}
}

private inline fun <reified T : Fragment> changeFragment() {
val tag = T::class.java.name
val fragmentTransaction = supportFragmentManager.beginTransaction()
Expand All @@ -150,6 +168,8 @@ class HomeActivity : AppCompatActivity() {
}

companion object {
private const val START_BACK_PRESSED_TIME = 0L
private const val FINISH_BACK_PRESSED_TIME = 3000L
fun getIntent(context: Context): Intent {
return Intent(context, HomeActivity::class.java)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.GridLayoutManager
import com.festago.festago.R
import com.festago.festago.databinding.FragmentFestivalListBinding
import com.festago.festago.model.FestivalFilter
import com.festago.festago.presentation.ui.home.ticketlist.TicketListFragment
import com.festago.festago.presentation.ui.ticketreserve.TicketReserveActivity
import com.festago.festago.presentation.util.repeatOnStarted
Expand Down Expand Up @@ -59,6 +60,15 @@ class FestivalListFragment : Fragment(R.layout.fragment_festival_list) {
adapter = FestivalListAdapter()
binding.rvFestivalList.adapter = adapter

initFestivalListSpanSize()
initRefresh()
initFestivalFilters()
if (vm.uiState.value is FestivalListUiState.Loading) {
loadFestivalsBy(binding.cgFilterOption.checkedChipId)
}
}

private fun initFestivalListSpanSize() {
binding.rvFestivalList.layoutManager.apply {
if (this is GridLayoutManager) {
val spanSize = (resources.displayMetrics.widthPixels.dp / 160)
Expand All @@ -69,15 +79,29 @@ class FestivalListFragment : Fragment(R.layout.fragment_festival_list) {
}
}
}
}

vm.loadFestivals()

private fun initRefresh() {
binding.srlFestivalList.setOnRefreshListener {
vm.loadFestivals()
loadFestivalsBy(binding.cgFilterOption.checkedChipId)
binding.srlFestivalList.isRefreshing = false
}
}

private fun initFestivalFilters() {
binding.cgFilterOption.setOnCheckedStateChangeListener { group, _ ->
loadFestivalsBy(checkedChipId = group.checkedChipId)
}
}

private fun loadFestivalsBy(checkedChipId: Int) {
when (checkedChipId) {
R.id.chipProgress -> vm.loadFestivals(FestivalFilter.PROGRESS)
R.id.chipPlanned -> vm.loadFestivals(FestivalFilter.PLANNED)
R.id.chipEnd -> vm.loadFestivals(FestivalFilter.END)
}
}

private fun updateUi(uiState: FestivalListUiState) {
when (uiState) {
is FestivalListUiState.Loading,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ sealed interface FestivalListUiState {
object Loading : FestivalListUiState

data class Success(
val festivals: List<FestivalItemUiState>
val festivals: List<FestivalItemUiState>,
) : FestivalListUiState {
val hasFestival get() = festivals.isNotEmpty()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.festago.festago.analytics.AnalyticsHelper
import com.festago.festago.analytics.logNetworkFailure
import com.festago.festago.model.FestivalFilter
import com.festago.festago.presentation.ui.home.festivallist.FestivalListEvent.ShowTicketReserve
import com.festago.festago.repository.FestivalRepository
import dagger.hilt.android.lifecycle.HiltViewModel
Expand All @@ -28,9 +29,9 @@ class FestivalListViewModel @Inject constructor(
private val _event = MutableSharedFlow<FestivalListEvent>()
val event: SharedFlow<FestivalListEvent> = _event.asSharedFlow()

fun loadFestivals() {
fun loadFestivals(festivalFilter: FestivalFilter) {
viewModelScope.launch {
festivalRepository.loadFestivals()
festivalRepository.loadFestivals(festivalFilter)
.onSuccess {
_uiState.value = FestivalListUiState.Success(
festivals = it.map { festival ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.festago.festago.databinding.ActivityStudentVerificationBinding
import com.festago.festago.presentation.ui.customview.OkDialogFragment
import com.festago.festago.presentation.ui.home.HomeActivity
import com.festago.festago.presentation.util.repeatOnStarted
import com.festago.festago.presentation.util.setOnSingleClickListener
import dagger.hilt.android.AndroidEntryPoint
import java.time.LocalTime
import java.time.format.DateTimeFormatter
Expand Down Expand Up @@ -43,7 +44,7 @@ class StudentVerificationActivity : AppCompatActivity() {
}

private fun initRequestVerificationCodeBtn(schoolId: Long) {
binding.btnRequestVerificationCode.setOnClickListener {
binding.btnRequestVerificationCode.setOnSingleClickListener {
vm.sendVerificationCode(binding.tieUserName.text.toString(), schoolId)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.ConcatAdapter
import com.festago.festago.R
import com.festago.festago.databinding.ActivityTicketReserveBinding
import com.festago.festago.model.ErrorCode
import com.festago.festago.model.ReservationTicket
import com.festago.festago.model.ReservedTicket
import com.festago.festago.presentation.ui.customview.OkDialogFragment
Expand Down Expand Up @@ -75,7 +76,7 @@ class TicketReserveActivity : AppCompatActivity() {
)

is ReserveTicketSuccess -> handleReserveTicketSuccess(event.reservedTicket)
is ReserveTicketFailed -> handleReserveTicketFailed()
is ReserveTicketFailed -> handleReserveTicketFailed(event.errorCode)
is ShowSignIn -> handleShowSignIn()
}

Expand Down Expand Up @@ -113,8 +114,14 @@ class TicketReserveActivity : AppCompatActivity() {
finish()
}

private fun handleReserveTicketFailed() {
OkDialogFragment.newInstance("์˜ˆ์•ฝ์— ์‹คํŒจํ•˜์˜€์Šต๋‹ˆ๋‹ค.")
private fun handleReserveTicketFailed(errorCode: ErrorCode) {
val message: String = when (errorCode) {
is ErrorCode.TICKET_SOLD_OUT -> getString(R.string.ticket_reserve_dialog_sold_out)
is ErrorCode.RESERVE_TICKET_OVER_AMOUNT -> getString(R.string.ticket_reserve_dialog_over_amount)
is ErrorCode.NEED_STUDENT_VERIFICATION -> getString(R.string.ticket_reserve_dialog_need_student_verification)
is ErrorCode.UNKNOWN -> getString(R.string.ticket_reserve_dialog_unknown)
}
OkDialogFragment.newInstance(message)
.show(supportFragmentManager, OkDialogFragment::class.java.name)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.festago.festago.presentation.ui.ticketreserve

import com.festago.festago.model.ErrorCode
import com.festago.festago.model.ReservationTicket
import com.festago.festago.model.ReservedTicket
import java.time.LocalDateTime
Expand All @@ -11,6 +12,6 @@ sealed interface TicketReserveEvent {
) : TicketReserveEvent

class ReserveTicketSuccess(val reservedTicket: ReservedTicket) : TicketReserveEvent
object ReserveTicketFailed : TicketReserveEvent
class ReserveTicketFailed(val errorCode: ErrorCode) : TicketReserveEvent
object ShowSignIn : TicketReserveEvent
}
Loading

0 comments on commit a6bcaa9

Please sign in to comment.