Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(instrument-types): add localization #146

Merged
merged 2 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion client/src/generated/model/instrument-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,11 @@ export interface InstrumentType {
* @type {string}
* @memberof InstrumentType
*/
instrument_type: string;
code: string;
/**
*
* @type {string}
* @memberof InstrumentType
*/
localized_text: string;
}
38 changes: 23 additions & 15 deletions client/src/pages/home/ui/Home.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,37 +15,37 @@ import { useDarkMode } from "shared/dark-mode/use-dark-mode";
const images = [
{
image: saxophone,
caption: "Saxophone"
caption: "Saxophone",
},
{
image: guitar,
caption: "Guitar"
caption: "Guitar",
},
{
image: rock_guitar,
caption: "Rock Guitar"
caption: "Rock Guitar",
},
{
image: violin,
caption: "Violin"
}
caption: "Violin",
},
];

const trendingInstrumentsResponsiveSettings = [
{
breakpoint: 571,
settings: {
slidesToShow: 3,
slidesToScroll: 1
}
slidesToScroll: 1,
},
},
{
breakpoint: 570,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
slidesToScroll: 1,
},
},
];

export function HomePage() {
Expand All @@ -58,10 +58,12 @@ export function HomePage() {
<div
className={styles.home_logo}
style={{
background: `url(${homeLogo}) no-repeat center, linear-gradient(blue, cyan)`
background: `url(${homeLogo}) no-repeat center, linear-gradient(blue, cyan)`,
}}
>
<form className={`${styles.search_bar__form} ${darkMode && darkStyles.text_dark_mode}`}>
<form
className={`${styles.search_bar__form} ${darkMode && darkStyles.text_dark_mode}`}
>
<input
type="text"
placeholder="What instrument?"
Expand All @@ -75,19 +77,25 @@ export function HomePage() {
</form>
</div>

<h1 className={`${darkMode ? styles.reason__h1__dark_mode : styles.reason__h1}`}>
<h1
className={`${darkMode ? styles.reason__h1__dark_mode : styles.reason__h1}`}
>
Why Choose Us for Your Musical Needs
</h1>

<div className={`${styles.reasons} ${darkMode && darkStyles.text_dark_mode}`}>
<div
className={`${styles.reasons} ${darkMode && darkStyles.text_dark_mode}`}
>
<div>
We offer a wide range of high-quality instruments for all skill levels
</div>
<div>Our expert staff provides personalized advice and service</div>
<div>Enjoy competitive prices and exclusive deals on top brands</div>
</div>

<h1 className={`${styles.trends__h1} ${darkMode && darkStyles.text_dark_mode}`}>
<h1
className={`${styles.trends__h1} ${darkMode && darkStyles.text_dark_mode}`}
>
Trending Instruments
</h1>

Expand Down
1 change: 0 additions & 1 deletion client/src/pages/home/ui/styles/Home.page.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
color: #000000;
}


.reason__h1 {
color: #002244;
margin: 1em 0;
Expand Down
4 changes: 2 additions & 2 deletions client/src/pages/instrument/api/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const loader: LoaderFunction = async ({
}
const instrument = instrumentRequest.data;

const jwt = Jwt.extractFromCookie()
const jwt = Jwt.extractFromCookie();
if (jwt === null || jwt.expired()) {
return {
instrument: instrument,
Expand All @@ -42,7 +42,7 @@ export const loader: LoaderFunction = async ({
});

if (listFavoriteRequest.status !== 200) {
throw new Error(`Failed to extract favorite list}`)
throw new Error(`Failed to extract favorite list}`);
}

const favoriteIds = listFavoriteRequest.data.content.map(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface Props {
setErrorModal: (errorModal: boolean) => void;
}

const deleteInstrumentById = new DeleteInstrumentByIdApi(apiConfig)
const deleteInstrumentById = new DeleteInstrumentByIdApi(apiConfig);

export const RemoveInstrumentButton = (props: Props) => {
const { darkMode } = useDarkMode();
Expand All @@ -27,7 +27,7 @@ export const RemoveInstrumentButton = (props: Props) => {
Authorization: `Bearer ${Jwt.extractFromCookie()!.toStringValue()}`,
},
},
)
);
if (response.status === 200) {
props.setSuccessModal(true);
return;
Expand Down
2 changes: 1 addition & 1 deletion client/src/shared/styles/dark-mode.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

//.text_dark_mode input::placeholder {
// color: #ff;
//}
//}
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ export const InstrumentTypeFilter = (props: Props) => {

return (
<div>
<legend style={{ padding: "0" }}>
Type
</legend>
<legend style={{ padding: "0" }}>Type</legend>
{instrumentTypes.map((instrumentType) => (
<div key={instrumentType.instrument_type}>
<input
Expand Down
8 changes: 6 additions & 2 deletions openapi/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -666,11 +666,15 @@ components:
InstrumentType:
type: object
required:
- instrument_type
- code
- localized_text
properties:
instrument_type:
code:
type: string
example: STRINGED
localized_text:
type: string
example: Stringed
ManufacturerName:
type: object
required:
Expand Down
9 changes: 6 additions & 3 deletions openapi/specs/common/InstrumentType.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ components:
schemas:
InstrumentType:
type: object
required: [instrument_type]
required: [code, localized_text]
properties:
instrument_type:
code:
type: string
example: "STRINGED"
example: STRINGED
localized_text:
type: string
example: Stringed
3 changes: 3 additions & 0 deletions server/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.properties]
charset = utf-8

[**openapi/*.yml]
indent_size = 2

Expand Down
6 changes: 3 additions & 3 deletions server/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ group = "mu.muse"
version = "1.0.0-SNAPSHOT"

java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}

kotlin {
jvmToolchain(17)
jvmToolchain(21)
}

configurations {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ import jakarta.validation.Valid

/**
*
* @param instrumentType
* @param code
* @param localizedText
*/
data class InstrumentType(

@get:JsonProperty("instrument_type", required = true) val instrumentType: kotlin.String
@get:JsonProperty("code", required = true) val code: kotlin.String,

@get:JsonProperty("localized_text", required = true) val localizedText: kotlin.String
) {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,32 @@ import mu.muse.usecase.GetInstrumentsByIds
import mu.muse.usecase.GetUser
import mu.muse.usecase.RegisterUser
import mu.muse.usecase.RemoveFavorite
import org.springframework.context.MessageSource
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.support.ResourceBundleMessageSource
import org.springframework.web.servlet.LocaleResolver
import org.springframework.web.servlet.i18n.SessionLocaleResolver
import java.util.Locale

@Configuration
@Suppress("TooManyFunctions")
class RestConfiguration {

@Bean
fun localResolver(): LocaleResolver = with(SessionLocaleResolver()) {
setDefaultLocale(Locale.US)
this
}

@Bean
fun messageSource(): ResourceBundleMessageSource = with(ResourceBundleMessageSource()) {
setUseCodeAsDefaultMessage(true)
setBasenames("messages")
setDefaultEncoding("UTF-8")
this
}

@Bean
fun helloEndpoint() = HelloEndpoint()

Expand All @@ -54,25 +73,28 @@ class RestConfiguration {
fun getProfileEndpoint(getUser: GetUser) = GetProfileEndpoint(getUser)

@Bean
fun getInstrumentsByCriteriaEndpoint(getInstrumentsByCriteria: GetInstrumentsByCriteria) =
GetInstrumentsByCriteriaEndpoint(getInstrumentsByCriteria)
fun getInstrumentsByCriteriaEndpoint(
getInstrumentsByCriteria: GetInstrumentsByCriteria,
messageSource: MessageSource
) = GetInstrumentsByCriteriaEndpoint(getInstrumentsByCriteria, messageSource)

// @format:off
@Bean
fun getInstrumentsByCriteriaPaginatedEndpoint(getInstrumentsByCriteriaPaginated: GetInstrumentsByCriteriaPaginated)
= GetInstrumentsByCriteriaPaginatedEndpoint(getInstrumentsByCriteriaPaginated)
// @format:on
fun getInstrumentsByCriteriaPaginatedEndpoint(
getInstrumentsByCriteriaPaginated: GetInstrumentsByCriteriaPaginated,
messageSource: MessageSource,
) = GetInstrumentsByCriteriaPaginatedEndpoint(getInstrumentsByCriteriaPaginated, messageSource)

@Bean
fun getInstrumentByIdEndpoint(getInstrumentById: GetInstrumentById) = GetInstrumentByIdEndpoint(getInstrumentById)
fun getInstrumentByIdEndpoint(getInstrumentById: GetInstrumentById, messageSource: MessageSource) =
GetInstrumentByIdEndpoint(getInstrumentById, messageSource)

@Bean
fun deleteInstrumentByIdEndpoint(deleteInstrumentById: DeleteInstrumentById) =
DeleteInstrumentByIdEndpoint(deleteInstrumentById)

@Bean
fun getInstrumentTypesEndpoint(getInstrumentTypes: GetInstrumentTypes) =
GetInstrumentTypesEndpoint(getInstrumentTypes)
fun getInstrumentTypesEndpoint(getInstrumentTypes: GetInstrumentTypes, messageSource: MessageSource) =
GetInstrumentTypesEndpoint(getInstrumentTypes, messageSource)

@Bean
fun getInstrumentMaterialsEndpoint(getInstrumentMaterials: GetInstrumentMaterials) =
Expand All @@ -95,7 +117,10 @@ class RestConfiguration {
fun registrationEndpoint(registerUser: RegisterUser) = RegistrationEndpoint(registerUser)

@Bean
fun listFavoriteEndpoint(getFavoriteByUsername: GetFavoriteByUsername) = ListFavoriteEndpoint(getFavoriteByUsername)
fun listFavoriteEndpoint(
getFavoriteByUsername: GetFavoriteByUsername,
messageSource: MessageSource,
) = ListFavoriteEndpoint(getFavoriteByUsername, messageSource)

@Bean
fun addFavoriteEndpoint(addFavorite: AddFavorite) = AddFavoriteEndpoint(addFavorite)
Expand Down
19 changes: 4 additions & 15 deletions server/app/src/main/kotlin/mu/muse/domain/instrument/Instrument.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,10 @@ class Instrument internal constructor(
}
}

enum class Type(val realName: String) {
KEYBOARD(realName = "Keyboard"),
STRINGED(realName = "Stringed"),
WIND(realName = "Wind");

companion object {
fun fromRealName(realNameValueRaw: String): Type {
return when (realNameValueRaw) {
KEYBOARD.realName -> KEYBOARD
STRINGED.realName -> STRINGED
WIND.realName -> WIND
else -> throw IllegalArgumentException("Unknown value `${realNameValueRaw}")
}
}
}
enum class Type(val i18nCode: String) {
KEYBOARD(i18nCode = "instrument.type.keyboard"),
STRINGED(i18nCode = "instrument.type.stringed"),
WIND(i18nCode = "instrument.type.wind");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,36 @@ import mu.muse.rest.api.ListFavoriteApi
import mu.muse.rest.dto.ListFavoriteResponse
import mu.muse.rest.instruments.toDto
import mu.muse.usecase.GetFavoriteByUsername
import org.springframework.context.MessageSource
import org.springframework.http.HttpHeaders
import org.springframework.http.ResponseEntity
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.core.userdetails.UserDetails
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.context.request.RequestContextHolder
import org.springframework.web.context.request.ServletRequestAttributes
import java.util.Locale

@RestController
class ListFavoriteEndpoint(
private val getFavoriteByUsername: GetFavoriteByUsername,
private val messageSource: MessageSource,
) : ListFavoriteApi {

override fun listFavorite(): ResponseEntity<ListFavoriteResponse> {
val principal = SecurityContextHolder.getContext().authentication.principal as UserDetails
val username = Username.from(principal.username)
val instruments = getFavoriteByUsername.execute(username)
return instruments.toResponse()
val request = (RequestContextHolder.getRequestAttributes() as ServletRequestAttributes).request
val locale = Locale.of(request.getHeader(HttpHeaders.ACCEPT_LANGUAGE)) ?: Locale.US
return instruments.toResponse(messageSource, locale)
}
}

fun List<Instrument>.toResponse(): ResponseEntity<ListFavoriteResponse> {
fun List<Instrument>.toResponse(messageSource: MessageSource, locale: Locale): ResponseEntity<ListFavoriteResponse> {
return ResponseEntity.ok(
ListFavoriteResponse(
content = this.map { it.toDto() },
content = this.map { it.toDto(messageSource, locale) },
),
)
}
Loading
Loading